【问题标题】:Is performance better if dynamically added script is async如果动态添加的脚本是异步的,性能会更好吗
【发布时间】:2018-12-17 11:15:00
【问题描述】:

关于这个话题有几个问题,如下一个:Is the "async" attribute/property useful if a script is dynamically added to the DOM?

但所有这些问题都只关注向 DOM 添加一个 script-tag 或只关注彼此不依赖的 script-tags。

我们使用 Three.js 及其示例。由于 Three.js 是一个复杂的项目,很长一段时间以来并不是整个示例等都是围绕 ES 模块构建的。因此,我们通过添加脚本标签来动态加载这些示例脚本。正如在其他问题中提到的,添加脚本标签会动态地将其设置为异步。但是您可以覆盖此行为。这对我们来说非常好,因为如果我们将脚本设置为async:false,则会保留执行顺序(这有助于我们保持较低的复杂性),我们所做的基本上如下(实际代码涉及更多,但我想要显示要点):

const attatch = (url, options = {}) => {
    return new Promise((resolve, reject) => {
        const element = document.createElement('script');
        element.async = options.async || false;
        element.src = url;
        if (options.id) {
            element.id = options.id;
        }
        element.onload = () => {
            resolve();
        };
        element.onerror = (error) => {
            reject(error);
        };
        starts.push(performance.now());
        document.getElementById('container').appendChild(element);
    });
};

Promise.all([
    attatch('./three/lib/rthree.js'),
    attatch('./three/lib/postprocessing/EffectComposer.js', {id: 'effect-composer-js'}),
    attatch('./three/lib/postprocessing/RenderPass.js', {id: 'render-pass-js'}),
    attatch('./three/lib/postprocessing/ShaderPass.js', {id: 'shader-pass-js'}),
    attatch('./three/lib/shaders/LuminosityHighPassShader.js', {id: 'luminosity-high-pass-shader-js'}),
    attatch('./three/lib/postprocessing/UnrealBloomPass.js', {id: 'unreal-bloom-pass-js'}),
    attatch('./three/lib/postprocessing/OutlinePass.js', {id: 'outline-pass-js'})
]).then(() => {
    // Run 3D content now
});

我做了一些基准测试,并没有发现将 async 设置为 false 之间有任何显着差异。但我不确定我是否没有错过任何东西。特别是因为我还希望浏览器在加载脚本时构建 UI,然后在一切准备就绪时启动 Three.js 场景。由于在我们的现实世界应用程序中对这种变化进行基准测试并不容易,我创建了一个示例项目。由于我没有发现真正的差异,这让我怀疑我是否没有正确测量或者是否真的没有性能差异。

您认为使用async:true 是否比async:false 有显着的性能改进,或者这充其量只是一个微优化?附注:我们只对modern browsers的结果感兴趣

【问题讨论】:

    标签: javascript performance browser lazy-loading


    【解决方案1】:

    你的结果对我来说很有意义。 async 将告诉浏览器在到达 <script> 标记时继续解析 HTML,并在文件准备好后立即执行它。由于您已经使用Promises 异步加载您的Javascript 文件,这不会阻止浏览器继续解析您的HTML,因此您是否使用async 并不重要。我什至会删除它以简化源代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-25
      • 1970-01-01
      • 2015-06-17
      • 1970-01-01
      • 2016-05-13
      • 2011-12-07
      相关资源
      最近更新 更多