代码之家  ›  专栏  ›  技术社区  ›  Václav Procházka

动态创建获取和解析脚本的顺序

  •  1
  • Václav Procházka  · 技术社区  · 1 年前

    我正在尝试用多个前端应用程序优化网站。我想动态下载(解析)应用程序,并为我们的系统设置关键应用程序的顺序。

    我在想 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 用于动态脚本?还是我应该走完全不同的路?

    1 回复  |  直到 1 年前
        1
  •  0
  •   Lajos Arpad    1 年前

    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].dependences.indexOf(script2)===-1

    确保你的排序正确,因为这是一个 POSET ,无论哪种方式都不是依赖项的脚本都不能通过上述规则进行比较。

    现在,循环您的数组并创建 Promise 对于所有元素,以这样一种方式,琐碎的项(那些没有依赖项的项)将被承诺加载相应的脚本,最好是一个函数的返回值,看起来像 appendScriptWithPriority ,而非平凡的项目看起来像:

    Promise.all(yourdependencies).then(yourPromise)
    

    也就是说,在所有依赖项完成加载之前,上面的脚本不会开始加载。因此,您将拥有创建承诺的机制,并且可以始终如一地应用它们,而琐碎承诺和非平凡承诺之间的区别在于,没有依赖关系的琐碎承诺将被创建为承诺,而非平凡承诺将是 then Promise.all .