Предоставляйте современный код современным браузерам для более быстрой загрузки страниц.

Хуссейн Джирдех
Houssein Djirdeh

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

Babel — наиболее широко используемый инструмент для компиляции кода, содержащего новый синтаксис, в код, который могут понимать различные браузеры и среды (например, Node). В этом руководстве предполагается, что вы используете Babel, поэтому вам нужно следовать инструкциям по настройке , чтобы включить его в свое приложение, если вы еще этого не сделали. Выберите webpack в Build Systems если вы используете webpack в качестве сборщика модулей в своем приложении.

Чтобы использовать Babel для транспиляции только того, что необходимо вашим пользователям, вам необходимо:

  1. Определите, на какие браузеры вы хотите ориентироваться.
  2. Используйте @babel/preset-env с соответствующими целевыми браузерами.
  3. Используйте <script type="module"> , чтобы прекратить отправку транспилированного кода в браузеры, которым он не нужен.

Определите, на какие браузеры вы хотите ориентироваться

Прежде чем вы начнете изменять способ транспиляции кода в вашем приложении, вам нужно определить, какие браузеры обращаются к вашему приложению. Проанализируйте, какие браузеры в настоящее время используют ваши пользователи, а также те, на которые вы планируете нацелиться, чтобы принять обоснованное решение.

Используйте @babel/preset-env

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

Вместо включения определенных плагинов для выборочной компиляции определенных языковых функций, которые вы используете, Babel предоставляет ряд предустановок, которые объединяют плагины вместе. Используйте @babel/preset-env, чтобы включить только преобразования и полифиллы, необходимые для браузеров, на которые вы планируете нацеливаться.

Включите @babel/preset-env в массив presets в файле конфигурации Babel, .babelrc :

{
 "presets": [
   [
     "@babel/preset-env",
     {
       "targets": ">0.25%"
     }
   ]
 ]
}

Используйте поле targets , чтобы указать, какие версии браузеров вы хотите включить, добавив соответствующий запрос в поле browsers . @babel/preset-env интегрируется с браузерами, конфигурацией с открытым исходным кодом, общей для различных инструментов для таргетинга браузеров. Полный список совместимых запросов находится в документации браузеров . Другой вариант — использовать файл .browserslistrc для перечисления сред, на которые вы хотите нацелиться.

Значение ">0.25%" сообщает Babel, что нужно включать только те преобразования, которые необходимы для поддержки браузеров, которые составляют более 0,25% от глобального использования. Это гарантирует, что ваш пакет не будет содержать ненужный транспилированный код для браузеров, которые используются очень малым процентом пользователей.

В большинстве случаев это лучший подход, чем использование следующей конфигурации:

  "targets": "last 2 versions"

Значение "last 2 versions" транспилирует ваш код для последних двух версий каждого браузера, что означает, что поддержка предоставляется для браузеров, поддержка которых прекращена, таких как Internet Explorer. Это может неоправданно увеличить размер вашего пакета, если вы не ожидаете, что эти браузеры будут использоваться для доступа к вашему приложению.

В конечном итоге вам следует выбрать подходящую комбинацию запросов, чтобы охватить только те браузеры, которые соответствуют вашим потребностям.

Включить современные исправления ошибок

@babel/preset-env группирует несколько функций синтаксиса JavaScript в коллекции и включает/отключает их на основе указанных целевых браузеров. Хотя это работает хорошо, вся коллекция функций синтаксиса преобразуется, когда целевой браузер содержит ошибку только с одной функцией. Это часто приводит к большему количеству преобразованного кода, чем необходимо.

Первоначально разработанный как отдельный пресет , параметр bugfixes в @babel/preset-env решает эту проблему, преобразуя современный синтаксис, который не работает в некоторых браузерах, в наиболее близкий эквивалентный синтаксис, который не работает в этих браузерах. Результатом является практически идентичный современный код с несколькими небольшими синтаксическими настройками, которые гарантируют совместимость во всех целевых браузерах. Чтобы использовать эту оптимизацию, убедитесь, что у вас установлен @babel/preset-env 7.10 или более поздней версии, затем установите свойство bugfixes в true :

{
 "presets": [
   [
     "@babel/preset-env",
     {
       "bugfixes": true
     }
   ]
 ]
}

В Babel 8 опция bugfixes будет включена по умолчанию.

Используйте <script type="module">

Модули JavaScript, или модули ES, являются относительно новой функцией, поддерживаемой во всех основных браузерах . Вы можете использовать модули для создания скриптов, которые могут импортировать и экспортировать из других модулей, но вы также можете использовать их с @babel/preset-env чтобы нацеливаться только на браузеры, которые их поддерживают.

Вместо того чтобы запрашивать конкретные версии браузеров или долю рынка, рассмотрите возможность указания "esmodules" : true в поле targets вашего файла .babelrc .

{
   "presets":[
      [
         "@babel/preset-env",
         {
            "targets":{
               "esmodules": true
            }
         }
      ]
   ]
}

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

Браузеры, поддерживающие модули, игнорируют скрипты с атрибутом nomodule . И наоборот, браузеры, не поддерживающие модули, игнорируют элементы скрипта с type="module" . Это означает, что вы можете включить модуль, а также скомпилированный запасной вариант.

В идеале два сценария версий приложения включаются следующим образом:

  <script type="module" src="main.mjs"></script>
  <script nomodule src="compiled.js" defer></script>

Браузеры, которые поддерживают модули, извлекают и выполняют main.mjs и игнорируют compiled.js . Браузеры, которые не поддерживают модули, делают наоборот.

Если вы используете Webpack, вы можете задать разные цели в своих конфигурациях для двух отдельных версий вашего приложения:

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

Выражаем благодарность Коннору Кларку и Джейсону Миллеру за их обзоры.