首页 > 解决方案 > 如果动态添加的脚本是异步的,性能会更好吗

问题描述

关于这个主题有几个问题,如下所示:如果将脚本动态添加到 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:trueover是否有显着的性能改进,async:false或者这充其量只是一个微优化?附注:我们只对现代浏览器的结果感兴趣

标签: javascriptperformancebrowserlazy-loading

解决方案


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


推荐阅读