Производительность лучше, если динамически добавленный скрипт асинхронный - PullRequest
0 голосов
/ 17 декабря 2018

Есть несколько вопросов по этой теме, таких как следующий: Является ли атрибут / свойство "async" полезным, если сценарий динамически добавляется в DOM?

Но все этивопросы касаются только добавления одного тега script в DOM или только тегов script, которые не зависят друг от друга.

Мы используем 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
});

Я провел некоторые тесты и не обнаружил какой-либо существенной разницы между установкой асинхронности в false.Но я не уверен, что ничего не пропустил.Тем более, что я также хочу, чтобы браузер создавал пользовательский интерфейс при загрузке сценариев, а затем запускал сцену Three.js, если все готово.Поскольку это изменение не так легко сравнить с нашим реальным приложением, я создал пример проекта.Поскольку я не нашел реальной разницы, меня удивляет, правильно ли я измерил или нет различий в производительности.

Как вы думаете, есть ли значительные улучшения производительности при использовании async:true по сравнению с async:false илиэто в лучшем случае микрооптимизация?Примечание: нас интересуют только результаты для современных браузеров

1 Ответ

0 голосов
/ 19 декабря 2018

Ваши результаты имеют смысл для меня.async скажет браузеру продолжить анализ HTML, когда он достигнет тега <script>, и выполнит его, как только файл будет готов.Поскольку вы уже загружаете свои файлы Javascript асинхронно с Promises, это не блокирует браузер, чтобы продолжить синтаксический анализ вашего HTML, так что, используете ли вы async или нет, на самом деле не имеет значения.Я бы даже удалил его, чтобы упростить исходный код.

...