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

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

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

Чтобы использовать 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 в коллекции и включает/отключает их в зависимости от указанных целевых браузеров. Хотя это работает хорошо, весь набор синтаксических функций преобразуется, когда целевой браузер содержит ошибку только с одной функцией. Это часто приводит к большему преобразованию кода, чем необходимо.

Изначально разработанная как отдельная предустановка , опция исправлений ошибок в @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 . Браузеры, не поддерживающие модули, делают наоборот.

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

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

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