Блог

Как сократить полезную нагрузку JavaScript, используя разделение кода

Сразу же после того, как время загрузки сайта превысит 3 секунды, 50% пользователей откажутся ждать продолжения. И с каждой секундой число отказов растёт на 12%. Это нужно учитывать всегда. Особенно, если речь идёт о слабых интернет-соединениях, которые осуществляются посредством мобильных устройств. А именно оттуда приходит около 70% поисковых запросов.

Почему скорость загрузки сайта так важна? Пользовательский опыт существенно сказывается на ранжировании страниц поисковыми системами. Если она низкая и приходит большое количество отказов, поисковики определяют сайт как проблемный. И они предпочитают не выводить его в ТОП как в процессе органической выдачи, так и при платном продвижении. И поскольку большинство сайтов являются продающими, то это снижает конверсию, так как пользователи уходят на действительно скоростные страницы.

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

В процессе оптимизации интернет-сайта специалистами, определяются как поверхностные проблемы, так и скрытые. Теоретически, их можно исправить самостоятельно, но для этого необходимо хорошо разбираться не только в структуре сайта, но и полностью во всей внутренней начинке. Особое внимание требуется уделить JavaScript и особенностям его работы.

Как сократить полезную нагрузку JavaScript

Если JavaScript отправляет большие полезные нагрузки, то это существенно снижает скорость загрузки сайта и взаимодействия с ним. Поэтому, вместо того, чтобы отправлять весь JavaScript пользователю сразу, как только будет загружена первая страница приложения, гораздо эффективнее разделить пакет на несколько частей. Таким образом, данные которые требуются для первоочередной загрузки браузер получит и обработает сразу, а остальное — по мере необходимости.

Если проводить тестирование скорости при помощи инструментов Google, то аудит от Lighthouse окажется неудачным в случае, когда для выполнения всего JavaScript на странице требуется много времени. Разделение кодов позволяет минимизировать количество скриптов, которые необходимо проанализировать и скомпилировать, а это положительно влияет на скорость загрузки страницы.

Использование динамического импорта

Возможность использования динамического импорта модулей у веб-разработчиков появилась относительно недавно. Не смотря на то, что визуально он схож с функцией «import», но функцией он не является. Он создан как синтаксис и использует круглые скобки (). Его наследование от Function.prototype не происходит, следовательно, вызов динамического импорта посредством call или apply не возможен.

Для примера, рассмотрим условный модуль, который находится по адресу ./utils.mjs.

При статическом импорте он будет выглядеть таким образом:

<script type=”module”>

import * as module from ‘./utils.mjs’;

module.default();

// → logs ‘Hi from the default export!’

module.doStuff();

// → logs ‘Doing stuff…’

</script>

Если же применять динамический импорт, то он вводит новую функциональную форму, «import». Она и обслуживает все варианты варианты использования: Import (moduleSpecifier) для объекта пространства имен запрошенного модуля, создания и оценки всех зависимостей модуля, а также самого модуля. Чтобы выполнить динамический импорт необходимо использовать модуль ./utils.mjs. Выглядит это приблизительно так:

<script type=”module”>

const moduleSpecifier = ‘./utils.mjs’;

import(moduleSpecifier)

.then((module) => { module.default();

// → logs ‘Hi from the default export!’

module.doStuff();

// → logs ‘Doing stuff…’

.});

</script>

Стоит учитывать, что обратного вызова, вместо стиля «then» можно использовать в качестве альтернативы async/await.

Применение динамического импорта с использованием someFunction

Для разделения JavaScript и загрузки динамического импорта можно использовать метод someFunction. Он импортируется из из определенной библиотеки. Если этот модуль не используется в другом месте, блок кода можно изменить. Тогда появляется возможность извлекать динамический импорт только тогда, когда запрос поступил от пользователя.

form.addEventListener(“submit”, e => {

e.preventDefault();

import(‘library.moduleA’)

.then(module => module.default) // using the default export

.then(someFunction())

.catch(handleError());

});

const someFunction = () =>

{ // uses moduleA

}

При данном алгоритме, код из которого и состоит модуль, загружается в «ленивом» формате. Это достигается за счёт того, что он не входит в исходный пакет данных и позволяет осуществлять ленивую загрузку, либо загрузку по запросу пользователя (при отправке им соответствующей формы). Чтобы еще больше повысить производительность страницы, необходимо настроить предварительную загрузку критических блоков, чтобы расставить приоритеты и они были загружены в первую очередь.

Предварительная загрузка критических ресурсов, как способ разделения нагрузки JavaScript

Данный пример, который приведён выше, является крайне простым. При этом, довольно странно видеть, что многие веб-разработчики не используют отложенную загрузку сторонних ресурсов в больших приложениях. Как правило, сторонние зависимости разделяются на отдельные пакеты поставщиков, которые можно кэшировать, поскольку их обновление осуществляется довольно редко.

Разделение на уровне маршрута или компонента при использовании клиентской среды является более простым подходом к отложенной загрузке различных частей приложения. Многие популярные фреймворки, в которых используется веб-пакет, предоставляют абстракции, облегчающие ленивую загрузку. Таким образом, они упрощают задачи веб-разработчиков избавляя их от необходимости погружаться в конфигурации самостоятельно. При этом, стоит учитывать, что использование плагинов далеко не всегда является эффективным. Для того, чтобы сайт работал максимально корректно, необходимо проводить глубокие настройки вручную.

Похожие записи