Smart Bundling: Как служить Наследие код только для наследие браузеров

Веб-сайт сегодня получает большой кусок своего трафика от вечнозеленых браузеров — большинство из которых имеют хорошую поддержку для ES6 ,, новые стандарты JavaScript, новые веб-платформы AVI и CSS атрибуты. Тем не менее, устаревшие браузеры все еще должны быть поддержаны в ближайшем будущем — их доля использования достаточно велика, чтобы не быть проигнорированным, в зависимости от вашей пользовательской базы.

Беглый взгляд наcaniuse.com ‘s использование таблицы показывает, что вечнозеленые браузеры занимают львиную долю рынка браузеров — более 75%. Несмотря на это, нормой является префикс CSS, транспиле всех наших JavaScript к ES5, и включают полифилы для поддержки каждого пользователя мы заботимся о.

Хотя это понятно из исторического контекста — Интернет всегда был о прогрессивном повышении — остается вопрос: Мы замедляем веб для большинства наших пользователей, с тем чтобы поддержать уменьшение набора устаревших браузеров?

Transpilation to ES5, web platform polyfills, ES6+ polyfills, CSS prefixing
Различные слои совместимости веб-приложения. (Просмотр большой версии)

Стоимость поддержки устаревших браузеров

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

Переплет к ES5

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

Размер библиотеки
(минифицированный ES6)
Размер
(минифицированный ES5)
Разница
ТодоМВК 8.4 КБ 11 КБ 24.5%
Перетаскивать 53,5 кБ 77,9 кБ 31.3%
Луксон 75.4 КБ 100.3 КБ 24.8%
Video.js 237,2 кБ 335,8 кБ 29.4%
PixiJS 370,8 кБ 452 КБ 18%

В среднем, нетрансскладные пучки примерно на 25% меньше, чем те, которые были транспилированы до ES5. Это неудивительно, учитывая, что ES6 обеспечивает более компактный и выразительный способ представления эквивалентной логики и что транспилляция некоторых из этих функций в ES5 может потребовать большого количества кода.

Полифилы ES6

В то время как Babel делает хорошую работу по применению синтаксической трансформации к нашему коду ES6, встроенные функции, введенные в ES6 — такие как Promise , и , и Map Set новый массив и струнные методы — все еще должны быть полизаполнены. Падение в babel-polyfill как можно добавить близко к 90 КБ к вашей minified расслоение.

Веб-платформа Полифиллс

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

Добавление полизаполнения, совместимого со спецификацией, для каждой из этих функций может оказать заметное влияние на размер расслоения.

CsS Префикс

Наконец, давайте посмотрим на влияние CSS префиксации. Хотя префиксы не собирается добавить столько мертвый вес расслоения, как и другие преобразования сборки делать — особенно потому, что они хорошо сжимают, когда Gzip’d — Есть еще некоторые сбережения, которые должны быть достигнуты здесь.

Размер библиотеки
(minified, префикс для последних 5 версий браузера)
Размер
(minified, префикс для последней версии браузера)
Разница
Bootstrap 159 КБ 132 КБ 17%
Бульма 184 КБ 164 КБ 10.9%
Фонд 139 КБ 118 КБ 15.1%
Семантический uI 622 КБ 569 КБ 8.5%

Практическое руководство по доставке эффективного кода

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

The modern bundle is smaller than the legacy bundle because it forgoes some compatibility layers.
Вилка наших пучков. (Посмотреть большую версию)

Эта идея не совсем нова. Такие службы, как Polyfill.io, являются попытками динамического полизаполнения сред браузера во время выполнения. Но такие подходы, как это страдают от нескольких недостатков:

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

Кроме того, это не решает проблему веса, добавленного транспилацией кода приложения, который порой может быть больше, чем сами полифилы.

Давайте посмотрим, как мы можем решить для всех источников раздуваться мы определили до сих пор.

Инструменты, которые нам понадобятся

  • Веб-пакет
    Это будет наш инструмент сборки, хотя процесс останется таким же, как и другие инструменты сборки, такие как Parcel и Rollup.
  • Браузерный список
    С этим мы будем управлять и определять браузеры, которые мы хотели бы поддерживать.
  • И мы будем использовать некоторые браузеры поддержки плагинов.

1. Определение современных и устаревших браузеров

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

Firefox >= 53; Edge >= 15; Chrome >= 58; iOS >= 10.1
Браузеры, поддерживающие ES6, новые атрибуты CSS и apIs браузера, такие как Обещания и Fetch. (Посмотреть большую версию)

Конфигурация Browserslist в корне проекта может хранить эту информацию. Подразделы «Окружающая среда» могут быть использованы для документирования двух групп браузеров, например:

[modern]
Firefox >= 53
Edge >= 15
Chrome >= 58
iOS >= 10.1

[legacy]
> 1%

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

2. Es6 » Транспилинг и полифиллинг

Для транспиля нашего JavaScript в осознает среду, мы собираемся использовать babel-preset-env .

Давайте инициализируем .babelrc файл в корне нашего проекта с этим:

{
  "presets": [
    ["env", { "useBuiltIns": "entry"}]
  ]
}

Включение useBuiltIns флага позволяет Babel выборочно полизаполнить встроенные функции, которые были введены как часть ES6 . Поскольку он фильтрует полифилы, чтобы включить только те, которые требуются окружающей среды, мы смягчаем стоимость доставки в babel-polyfill полном объеме.

Для того, чтобы этот флаг работал, нам также нужно будет импортировать babel-polyfill в нашей точке входа.

// In
import "babel-polyfill";

Это заменит большой babel-polyfill импорт гранулированным импортом, отфильтрованным средой браузера, на которую мы ориентируемся.

// Transformed output
import "core-js/modules/es7.string.pad-start";
import "core-js/modules/es7.string.pad-end";
import "core-js/modules/web.timers";
…

3. Функции веб-платформы полизаполнения

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

require('whatwg-fetch');
require('es6-promise').polyfill();
// … other polyfills

И это:

// polyfills for modern browsers (if any)
require('intersection-observer');

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

4. Предопосылок CSS

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

Создание простого файла конфигурации PostCSS в корне проекта должно быть достаточно:

module.exports = {
  plugins: [ require('autoprefixer') ],
}

Ввод все это вместе

Теперь, когда мы определили все необходимые конфигурации плагина, мы можем собрать конфигурацию webpack, которая считывает эти и выводит две отдельные сборки dist/modern и dist/legacy папки.

const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const isModern = process.env.BROWSERSLIST_ENV === 'modern'
const buildRoot = path.resolve(__dirname, "dist")

module.exports = {
  entry: [
    isModern ? './polyfills.modern.js' : './polyfills.legacy.js',
    "./main.js"
  ],
  output: {
    path: path.join(buildRoot, isModern ? 'modern' : 'legacy'),
    filename: 'bundle.[hash].js',
  },
  module: {
    rules: [
      { test: /.jsx?$/, use: "babel-loader" },
      {
        test: /.css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader']
      }
    ]},
    plugins: {
      new MiniCssExtractPlugin(),
      new HtmlWebpackPlugin({
      template: 'index.hbs',
      filename: 'index.html',
    }),
  },
};

Чтобы закончить, мы создадим несколько команд сборки в нашем package.json файле:

"scripts": {
  "build": "yarn build:legacy && yarn build:modern",
  "build:legacy": "BROWSERSLIST_ENV=legacy webpack -p --config webpack.config.js",
  "build:modern": "BROWSERSLIST_ENV=modern webpack -p --config webpack.config.js"
}

Ну вот. Запуск yarn build должен теперь дать нам две сборки, которые эквивалентны по функциональности.

Обслуживание правильного пакета для пользователей

Создание отдельных сборок помогает нам достичь только первой половины нашей цели. Нам все еще нужно определить и служить право расслоение для пользователей.

Помните конфигурацию Browserslist, определенную ранее? Не было бы неплохо, если бы мы могли использовать ту же конфигурацию, чтобы определить, в какую категорию попадает пользователь?

Введите браузер-useragent. Как следует из названия, browserslist-useragent можно прочитать нашу browserslist конфигурацию, а затем сопоставить агента пользователя с соответствующей средой. Следующий пример демонстрирует это с сервером Koa:

const Koa = require('koa')
const app = new Koa()
const send = require('koa-send')
const { matchesUA } = require('browserslist-useragent')
var router = new Router()

app.use(router.routes())

router.get('/', async (ctx, next) => {
  const useragent = ctx.get('User-Agent')  
  const isModernUser = matchesUA(useragent, {
      env: 'modern',
      allowHigherVersions: true,
   })
   const index = isModernUser ? 'dist/modern/index.html', 'dist/legacy/index.html'
   await send(ctx, index);
});

Здесь, установка allowHigherVersions флага гарантирует, что если новые версии браузера будут выпущены — те, которые еще не являются частью базы данных Can I Use — они будут по-прежнему сообщать, как правдивый для современных браузеров.

Одна из browserslist-useragent функций является обеспечение того, чтобы причуды платформы были приняты во внимание при сопоставлении агентов пользователей. Например, все браузеры на iOS (включая Chrome) используют WebKit в качестве базового движка и будут сопоставляться с соответствующим запросом браузера Safari.

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

Вывод: Стоит ли это?

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

1. Техническое обслуживание и тестирование

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

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

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

2. Время сборки против продолжительности выполнения

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

3. Прогрессивно повышенная скорость

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

4. Использование современных функций браузера с легкостью

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

Дифференциальный комплект Выступающей в производстве

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

В нашем уже оптимизированном пакете, мы смогли сжать экономию около 20% на Gzip’d CSS и JavaScript ресурсов, отправленных вниз провода для современных мобильных пользователей. Потому что более 80% наших ежедневных посетителей были на этих вечнозеленых браузеров, усилия положить в хорошо стоит воздействия.

Дополнительные ресурсы

Источник: smashingmagazine.com

Великолепный Журнал

Великолепный, сокрушительный, разящий (см. перевод smashing) независимый журнал о веб-разработке. Основан в 2006 году в Германии. Имеет няшный дизайн и кучу крутых авторов, которых читают 2 млн человек в месяц.

Добавить комментарий

%d такие блоггеры, как: