我希望优化在我的MVC项目中加载更大的javascript文件的方式。我已经在使用捆绑和缩小,但我真的只想在加载HTML和CSS之后加载其中的一些。我正在研究这种方法:
https://varvy.com/pagespeed/defer-loading-javascript.html
在这种方法中,在加载正文后,在load / onload事件中使用javascript注入脚本标记。我的问题是,我想与框架提供的捆绑和缩小一起使用,我还没有找到一个很好的方法来做到这一点。
我只是想知道是否有人成功地将这种方法用于MVC项目,并且是否已经有一个库(在Nuget或其他方面)来促进这一点。
编辑:这是我目前的解决方案,但我不确定是否喜欢它。
由于Bundling框架可以返回单个脚本标记或它们的列表,具体取决于您是否在调试中运行,我们需要提取这些标记的源值。为此,我创建了一个静态助手。
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);
}
从_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>
我认为这有点像黑客,因为我只是为了解析输出来渲染包,但我想我也可以缓存这些输出以进一步优化页面呈现。
答案 0 :(得分:2)
按Occam's Razor,最佳解决方案是使用 defer 属性...
<script src='myJavaScriptFile.js' defer></script>
如果要在ASP.NET MVC中使用它,那么您将执行此操作:
像这样创建一个新的Razor命令:
public static class Scripts
{
public static IHtmlString RenderDeferred(params string[] paths)
{
return Scripts.RenderFormat(@"<script src='{0}' defer></script>", paths);
}
}
然后像这样使用它:
@Scripts.RenderDeferred("~/myBundle/myJavaScriptBundle")
答案 1 :(得分:0)
一种选择是使用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 doc:https://api.jquery.com/jquery.getscript/