我正在尝试使用多个前端应用程序来优化网站。我想动态下载(解析)应用程序并为我们系统的关键应用程序设置顺序。
我在想
fetchpriority
:
function appendScriptWithPriority(src, priority) {
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = src;
script.async = true;
script.fetchpriority = 'low';
script.onload = () => {
resolve();
};
script.onerror = (error) => {
reject(error);
};
// Append the script to the head of the document
document.head.appendChild(script);
});
}
在 DOM 中,我可以看到没有
fetchpriority
的脚本:
<script src='src' async></script>
有什么办法,如何动态设置脚本的
fetchpriority
?或者我应该走完全不同的路?
fetchPriority是HTMLImageElement的属性,script标签没有这样的属性。
fetchPriority
设置与其他图像相比获取图像(而非脚本)的优先级。因此,当您尝试为 script
标签设置此属性时,浏览器将必须处理此无效属性。处理它的一种方法是简单地放弃更改,就像在浏览器中发生的那样。在测试过程中,您可能会发现浏览器添加了此属性,但该属性最终没有效果。
所以,这个想法应该以不同的方式实现,因为这个是无效的。相反,您可以创建依赖关系图。
确保您的图是树或森林,也就是说,其中不存在循环。
经验法则是,节点的加载是一个承诺,应该在所有依赖项的相应承诺都得到满足后执行。
因此,让我们创建一系列脚本设置,例如:
let myScripts = {
["src2"]: {dependencies: [], promise: null},
["src3"]: {dependencies: ["src2"], promise: null},
["src1"]: {dependencies: ["src2", "src3], promise: null},
};
让我们确保将这些对象排序到一个数组中,我们这样称呼它
arrScripts
:
如果 script1 和 script2 是两个脚本,那么
arrScripts.indexOf(script1) < arrScripts.indexOf(script2) => myScripts[script1].dependency.indexOf(script2) === -1
确保排序正确,因为这是一个 POSET,无论哪种方式都不是依赖项的脚本都无法通过上述规则进行比较。
现在,循环数组并为所有元素创建一个
Promise
,以这样的方式,琐碎的项目(没有依赖项的项目)将被承诺加载相应的脚本,最好是看起来像这样的函数的返回值appendScriptWithPriority
,而重要的项目看起来像:
Promise.all(yourdependencies).then(yourPromise)
也就是说,上面的脚本只有在其所有依赖项完成加载后才会开始加载。因此,您将拥有创建 Promise 的机制,并且可以一致地应用它们,而琐碎 Promise 和非平凡 Promise 之间的区别在于,没有依赖项的平凡 Promise 将被创建为 Promise,而非平凡 Promise 将是
then
Promise.all
。