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

Что такое содержимое верхней части страницы?

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

Как мы можем расставить приоритеты при рендеринге в верхней части страницы?

Браузер отображает веб-сайт сверху вниз, и каждый раз, когда он обнаруживает файл CSS или синхронизирующий файл JavaScript, весь рендеринг блокируется до тех пор, пока этот ресурс не будет загружен. Чтобы расставить приоритеты над содержимым верхней части страницы, мы должны встроить все CSS и JavaScript, которые необходимы для этого важного содержимого.
Есть несколько подходов, которые могут помочь вам в инлайнинге.
Для CSS вы можете попробовать автоматический инструмент, такой как critical from addyosmani, или вы сами определяете критические правила CSS, как это делаем мы. Для нас преимуществами являются один критический файл CSS для всех подстраниц и меньшее подмножество правил, потому что мы можем решить, какие правила важны, а какие нет.
Я думаю, что для JavaScript вы всегда должны определять их самостоятельно. Возможно, рендеринг на стороне сервера может помочь вам в некоторых случаях.

Чем может помочь представленная библиотека?

Идея моей новой библиотеки заключалась в обсуждении с внешним разработчиком проблемы обнаружения изменений, влияющих на верхнюю часть страницы. В компании, в которой я работаю, я внедряю большинство изменений во внешнем интерфейсе. Но иногда коллеге нужно развернуть небольшое изменение для своего проекта или во время моего отпуска, и побочный эффект рендеринга в верхней части страницы не виден. Иногда даже я не задумывался обо всех последствиях перемен. Небольшие скачки макета на один или два пикселя также трудно распознать во время рендеринга.
Таким образом, мы пришли к выводу, что мы можем использовать Google Puppeteer для управления безголовым Chrome с помощью JavaScript и делать скриншоты различных шагов во время рендеринга. После этого мы можем сравнить эти скриншоты с библиотекой различий и вычислить разницу в процентах.
Если вы уже оптимизировали контент в верхней части страницы, очень важно, чтобы эта область была завершена как можно быстрее во время будущих развертываний. . Если вы измените эту область с помощью «асинхронной» таблицы стилей CSS, весь макет подпрыгнет, и браузеру придется все перерисовывать. Если скачок макета очень большой и у вас ленивый загрузчик изображений, вы можете загрузить изображения, которые не нужны.

Какие шаги при рендеринге интересны?

Мы не можем делать несколько скриншотов во время загрузки. Но с помощью Puppeteer мы можем контролировать каждый запрос и решать, хотим ли мы загрузить или прервать этот запрос.
Для меня интересны следующие 3 шага:

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

Каков результат работы библиотеки?

Библиотека создает объект JSON, который содержит снимки экрана, изображения различий и процентное соотношение пикселей, которые изменяются во время рендеринга. Все изображения возвращаются в формате base64 PNG.

Пример из реального мира

Теперь пришло время поближе взглянуть на скриншоты. Поэтому я приведу вам реальный пример оптимизации на https://www.buecher.de.

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

Мы видим, что весь макет меняется из-за уведомления о файлах cookie в верхней части страницы. Проблема заключалась в глобальном удалении заполнения td, которого не было в нашем встроенном критическом css.
Поэтому я добавил именно это маленькое правило CSS в наш критический CSS:
td, th { padding: 0; }

И это легкое исправление приводит к следующему:

Действительно удивительно, как это маленькое правило может иметь такое большое влияние. Теперь мне пришлось переместить еще несколько правил в критическое определение. Я также улучшил некоторые из существующих правил CSS и через некоторое время получил такой результат:

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

Кросс-девайсное тестирование

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

Мониторинг

Я решил запускать этот скрипт автоматически один раз в день. Если соотношение diff пикселей больше 5%, я получаю электронное письмо, содержащее diff изображение.
Следующим шагом является включение этого мониторинга в наши существующие jenkins и запуск его при каждом изменении кода, чтобы jenkins мог напрямую отправлять электронное письмо ответственному разработчику.