我正在尝试优化页面加载时间。剩下的唯一一件事就是优化资源加载时间。我只有很少的资源和一个库脚本。 一些资产依赖于这个库。
供应商脚本
捆绑脚本
我想要实现的是当页面完全加载时开始加载所有这些资源。由于我在服务器端渲染所有内容,因此延迟用户交互对我来说不是问题。我只需要按照确切的顺序下载
library.min.js
,然后下载page.bundle.js
,但当我需要时。
我尝试了一些方法,但我无法开始下载并按正确的顺序执行它。目前我计划在需要时使用 xhr 和
eval
内容。但我不确定这是否是正确的方法。使用此方法时还有更多问题需要询问。缓存等
有人可以告诉我如何分割动态加载的 javascript 文件的下载和执行时间吗?
您可以动态创建
script
元素并将其添加到文档正文中,将 src
属性设置为您的 javascript 文件,然后让它下载。下载完成后,promise
将解析并设置下一个依赖的js文件。
function setExternalScript(src) {
return new Promise((resolve, reject) => {
const scriptTag = document.createElement('script');
scriptTag.type = 'text/javascript';
scriptTag.src = src;
scriptTag.onload = () => resolve();
document.appendChild(document.body, scriptTag);
});
}
async function afterLoaded() {
const scripts = ['a.js','b.js','c.js'];
for(let i=0; i< scripts.length; i++)
await setExternalScripts(scripts[i]);
}
afterLoaded(); // run this whenever you need
我想要实现的是当页面完全加载时开始加载所有这些资源。
然后只需将这些资源移动到页面末尾即可:
<body>
Some cool content
<script src="library.min.js"> </script>
<script src="page.bundle.js"> </script>
</body>
我只需要按照确切的顺序运行library.min.js,然后运行page.bundle.js,但当我需要时。
然后将它们按顺序放在页面上。您还可以添加
async
和 defer
标志来推迟下载。 (继续阅读)
如何分割动态加载的 javascript 文件的下载和执行时间?
当然可以,但为什么呢?如果js下载好了,为什么不直接运行呢?
目前我计划在需要时使用 xhr 和 eval 内容。
在极少数情况下,您需要加载额外的 javascript(例如,带有一些小游戏的页面,当用户选择其中一个游戏时您是否加载游戏脚本),只需将脚本添加到正文中即可:
function withScript(url, callback) {
var script = document.createElement("script");
script.src = url;
script.onload = callback;
}
withScript("additional.js", function() {
additional.start();
});
如果您的项目使用jquery,那么您可以使用get ajax回调脚本。该脚本在全局上下文中执行,因此它可以引用其他变量并使用 jQuery 函数。包含的脚本可能会对当前页面产生一些影响。一旦脚本加载但不一定执行,就会触发其成功回调。您可以找到一个工作示例https://www.w3schools.com/jquery/ajax_getscript.asp
对于多个脚本加载,可以使用以下代码:
$.getMultiScripts = function(arr, path) {
var _arr = $.map(arr, function(scr, i) {
var source = (path || "") + scr;
updatePreloader(i, arr.length);
return $.getScript(source);
});
_arr.push($.Deferred(function(deferred) {
$(deferred.resolve);
}));
return $.when.apply($, _arr);
}
var prereqArray = [ "model/Lab.js", "controller/init/main.js" ];
function getEngineStarter(id) {
$.getMultiScripts(prereqArray, rPath).done(function() {
console.log("Horray all loaded").
});
}
function setExternalScript(src) {
return new Promise((resolve, reject) => {
const scriptTag = document.createElement('script');
scriptTag.type = 'text/javascript';
scriptTag.src = src;
scriptTag.onload = () => resolve();
document.appendChild(document.body, scriptTag);
});
}
async function afterLoaded() {
const scripts = ['a.js','b.js','c.js'];
for(let i=0; i< scripts.length; i++)
await setExternalScripts(scripts[i]);
}
afterLoaded(); // run this whenever you need