在asp.net MVC中延迟加载javascript
我希望优化在MVC项目中加载较大javascript文件的方式。我已经在使用捆绑和缩小,但我真的只想在加载HTML和CSS后加载其中的一些。我在研究这种方法: 在这种方法中,在加载主体之后,在load/onload事件中使用javascript将脚本标记注入。我的问题是,我想同时使用框架提供的捆绑和缩小功能,但我还没有找到一个好方法 我只是想知道是否有人在MVC项目中成功地使用了这种方法,是否已经有一个库(在Nuget或其他方面)来促进这一点 编辑:这是我目前的解决方案,但我不确定我是否喜欢它 由于绑定框架可以返回单个脚本标记或它们的列表,这取决于您是否在调试中运行,因此我们需要提取这些标记的源值。为此,我创建了一个静态助手在asp.net MVC中延迟加载javascript,javascript,asp.net-mvc,Javascript,Asp.net Mvc,我希望优化在MVC项目中加载较大javascript文件的方式。我已经在使用捆绑和缩小,但我真的只想在加载HTML和CSS后加载其中的一些。我在研究这种方法: 在这种方法中,在加载主体之后,在load/onload事件中使用javascript将脚本标记注入。我的问题是,我想同时使用框架提供的捆绑和缩小功能,但我还没有找到一个好方法 我只是想知道是否有人在MVC项目中成功地使用了这种方法,是否已经有一个库(在Nuget或其他方面)来促进这一点 编辑:这是我目前的解决方案,但我不确定我是否喜欢它
public static string ExtactFromScriptBundle(string aBundle)
{
List<string> returnValue = new List<string>();
var jQueryString = Scripts.Render(aBundle).ToHtmlString();
var reg = new Regex("\".*?\"");
var matches = reg.Matches(jQueryString);
foreach (var match in matches)
{
returnValue.Add(match.ToString().Replace("\"", ""));
}
return Json.Encode(returnValue);
}
公共静态字符串ExtactFromScriptBundle(字符串aBundle)
{
List returnValue=新列表();
var jQueryString=Scripts.Render(aBundle.ToHtmlString();
var reg=新正则表达式(“\”*?\”);
var matches=reg.matches(jQueryString);
foreach(匹配中的变量匹配)
{
添加(match.ToString().Replace(“\”,”);
}
返回Json.Encode(returnValue);
}
而不是从_layout.cshtml中,您可以在标记前插入一个如下所示的块:
<script>
function downloadJSAtOnload() {
createScripElementsFromArray(@Html.Raw(ScriptHelper.ExtactFromScriptBundle("~/bundles/jquery")));
createScripElementsFromArray(@Html.Raw(ScriptHelper.ExtactFromScriptBundle("~/bundles/bootstrap")));
}
function createScripElementsFromArray(fileNameList) {
var arrayLength = fileNameList.length;
for (var i = 0; i < arrayLength; i++) {
createScripElement(fileNameList[i]);
}
}
function createScripElement(fileName) {
var element = document.createElement("script");
element.src = fileName;
document.body.appendChild(element);
console.log(fileName + " was loaded");
}
if (window.addEventListener)
window.addEventListener("load", downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent("onload", downloadJSAtOnload);
else window.onload = downloadJSAtOnload;
</script>
函数downloadJSAtOnload(){
CreateScripteElementsFromArray(@Html.Raw(ScriptHelper.ExtactFromScriptBundle(“~/bundles/jquery”));
CreateScripteElementsFromArray(@Html.Raw(ScriptHelper.ExtactFromScriptBundle(“~/bundles/bootstrap”));
}
函数CreateScripteElementsFromArray(文件名列表){
var arrayLength=fileNameList.length;
对于(变量i=0;i
在我看来,这有点像黑客,因为我呈现捆绑包只是为了解析输出,但我想我也可以缓存这些输出以进一步优化页面呈现。一个选项是使用jquery加载外部脚本。您最初依赖于jquery本身,但jquery重量很轻 然后你会有:
$(document).ready(function(){
//At this point, the HTML/CSS has already been loaded and rendered.
//load external scripts
$.getScript( "ajax/test.js", function( data, textStatus, jqxhr ) {
console.log( data ); // Data returned
console.log( textStatus ); // Success
console.log( jqxhr.status ); // 200
console.log( "Load was performed." );
});
});
Jquery文档:根据,最好的解决方案是使用defer属性
<script src='myJavaScriptFile.js' defer></script>
这种方法的问题是,它没有利用捆绑/缩小框架来压缩test.js。假设我自己加载每个文件,但也希望使用捆绑和缩小框架来优化文件。好吧,@daoom,现在呢?看看我更新的答案。我的问题是,虽然解决方案看起来很优雅defer关键字的实现因浏览器而异,加载和执行脚本的顺序也不是完全确定的。使用defer,如果脚本B依赖于脚本A,并且两者都使用defer加载,即使您将一个放置在另一个之前,也无法保证它们始终在o中加载和执行顺序。我认为你考虑的是“异步”。异步顺序是不确定的。延迟将始终按照你列出的顺序运行……好吧……稍后。此外,你可以控制边缘情况,将顺序重要的情况放在头上,而不延迟,将正常的情况放在尾。所有这些都遵循了在发生错误时最不令人惊讶的原则其他开发人员阅读你的代码。只是说。。。
public static class Scripts
{
public static IHtmlString RenderDeferred(params string[] paths)
{
return Scripts.RenderFormat(@"<script src='{0}' defer></script>", paths);
}
}
@Scripts.RenderDeferred("~/myBundle/myJavaScriptBundle")