Ускорение старых сайтов с помощью современных методов Front-End

Ускорение старых сайтов с помощью современных методов Front-End

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

Команда разработчиков интерфейсов присоединилась, в то время как наша команда дизайнеров все еще работала. Наши задачи состояли в том, чтобы: 1) познакомиться с текущей кодовой базой Drupal 7 и 2) сделать ускорение сайта, то есть улучшение производительности, там, где это возможно. Все это сопровождалось предостережением о том, что, когда проекты приземлились, мы ожидали немедленного перемещения по ним.

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

Определение скорости веб-сайта

Скорость веб-сайта — это сочетание скорости back end и скорости рендеринга браузера, которая определяется интерфейсом. Скорость Pantheon довольно внушительна. Помимо того, что они построены поверх инфраструктуры Pantheon, они интегрировали Fast CDN с HTTP / 2.

80-90% времени отклика конечного пользователя расходуется на интерфейс. Начните оттуда. — Стив Соудерс

В нормальной ситуации внешний интерфейс составляет 80% времени, необходимого браузеру для отображения веб-сайта. В нашей ситуации это больше похоже на 90%.

Это означает, что мы можем провести много оптимизаций, чтобы сделать сайт еще быстрее. Захватывающе!

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

В этой статье мы сосредоточимся на четырех основных показателях скорости веб-сайта:

Время до первого байта — это время, необходимое серверу для получения первого байта HTML. В нашем случае инфраструктура Pantheon справляется с этим очень хорошо.

Time to First Paint — это когда браузер первоначально закончил компоновку DOM и начинает рисовать экран.

Time to Last Hero Paint — это время, необходимое браузеру для рисования баннера в начальном окне просмотра.

Time to First Interactive — это самый важный показатель. Это когда сайт окрашивается и становится пригодным для использования (кнопки доступны для кликов, работает JavaScript и т. д.).

В этой статье мы рассмотрим панель производительности Chrome Developer Tools. Этот профиль был взят на предварительную версию сайта и идентифицирует эти показатели.

Front end производительность с H2

HTTP / 2 (или H2) — это новая технология в Интернете, которая управляет тем, как серверы передают данные назад и вперед между браузером. В предыдущей версии HTTP (1.1) каждому запросу ресурса требовалось цельное рукопожатие TCP, которое вводило дополнительную задержку для каждого запроса. Чтобы смягчить это, разработчики интерфейсов объединили ресурсы как можно меньше файлов. Например, сторонние разработчики объединили бы несколько файлов CSS в один монолитный файл. Мы также объединим несколько небольших изображений в одно изображение «спрайт» и отображаем только его части за раз. Эти «хаки» сокращают количество HTTP-запросов.

С H2 эти проблемы в значительной степени смягчаются самим протоколом, оставляя front end разработчика разделить ресурсы на свои собственные логические файлы. H2 позволяет мультиплексировать несколько файлов в одном потоке TCP. Поскольку Pantheon имеет H2, интегрированный со своим глобальным CDN, мы смогли использовать эти новые оптимизации.

Определение проблемы (проблем)

Интерфейс не оптимизирован. Давайте посмотрим на вкладку сети в инструментах разработчика Chrome:

Первое, что нужно заметить, это то, что агрегированный набор CSS составляет 1,4 МБ. Это чрезвычайно важно для файла CSS и заслуживает дальнейшего изучения.

Второе, что нужно заметить: сайт загружает некоторые файлы JavaScript, которые могут не использоваться на главной странице.

Давайте сначала оптимизируем пакет CSS

Пакет CSS объемом 1,4 Мбайт является противоречивым и вредит нашей метрике «Время до первой отрисовки», а также всем метрикам, которые появляются позже. Помимо необходимости загрузки большего файла, браузер должен также анализировать и интерпретировать его.

Глядя глубже в этот набор CSS, мы нашли некоторые встроенные base64 и кодированные изображения SVG. При использовании HTTP / 1.1 это сохраняло запрос на обратный путь к серверу для этого ресурса, но означает, что браузер загружает изображение независимо от того, нужна ли ему эта страница. Кроме того, мы обнаружили, что многие из этих изображений принадлежат к компонентам, которые больше не используются.

Аналогичным образом, различные целевые страницы использовали только небольшую часть монолитного файла CSS. Чтобы уменьшить размер пакета CSS, мы сначала взяли двухсторонний подход:

Извлеките внедренные изображения и обратитесь к ним через стандартное свойство background-image CSS. Поскольку Pantheon поставляется со встроенным HTTP / 2, практически нет штрафа за производительность, чтобы загрузить их в виде отдельных файлов.

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

Удаление встроенных изображений упало с пакетом до 700 КБ — большое улучшение, но все же очень большой CSS-файл. Следующим шагом было «разделение кода» пакета CSS на несколько файлов. Кодовая база Pantheon использует различные частицы Sass, которые могли бы сделать это относительно простым. К сожалению, кодовая база Sass имела очень большие частичные и ограниченную документацию в коде.

Трудно написать поддерживаемый Sass. CSS по самой своей природе «каскадирует» вниз по дереву DOM на различные компоненты. Также невозможно узнать, где именно в кодовой базе HTML существует определенный селектор CSS. Кодовая база Pantheon Sass была прекрасным примером этих общих проблем. При перемещении кода мы не могли предвидеть все возможные визуальные модификации.

Написание поддерживаемого Sass

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

Следите за тем, чтобы части Sass были небольшими и модульными. Начните думать о том, чтобы разделить их, когда они достигли более 300 линий.

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

Используйте соглашение об именах, например BEM, и придерживайтесь его.

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

Рефакторинг кодовой базы Sass

Рефакторинг запутанной кодовой базы Sass требует немного проб и ошибок, но это было бы невозможно без системы визуальной регрессии, встроенной в систему непрерывной интеграции (CI).

К счастью, Pantheon интегрировал BackstopJS в свой пайплайн CI. Эта система просматривает список репрезентативных URL-адресов при нескольких ширинах видовых экранов. Когда отправляется запрос на перенос, он использует безголовый Chrome для доступа к эталонному сайту и сравнивает его с средой Pantheon Multidev, которая содержит код из запроса pull. Если он обнаружит разницу, он отметит это и покажет различия в розовом.

Через кровь, пот и слезы мы смогли значительно реорганизовать кодовую базу Sass в 13 отдельных файлов. Затем в Drupal мы написали пользовательскую функцию препроцесса, которая загружает только CSS для каждого типа контента.

Из этого мы смогли довести основной файл CSS до управляемых 400 КБ (и только 70 КБ по проводу). В то время как все еще массивный, это уже не является технически мужественным. Есть еще некоторые оптимизации, которые можно сделать, но с помощью этих методов мы уменьшили размер этого файла до трети его первоначального размера.

Оптимизация стека JavaScript

Тема Pantheon была создана в 2015 году и широко использовала jQuery, которая была обычной практикой в то время. Хотя у нас не было времени или бюджета для реорганизации jQuery с сайта, у нас было время сделать некоторые простые, но значительные оптимизации.

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

Кроме того, файлы JavaScript, включенные в заголовок, также блокируют рендеринг макета, что задерживает метрику «Время до первой отрисовки».

Самый простой трюк, чтобы избежать задержки этих показателей, прост: удалите ненужный JavaScript. Для этого мы инвентаризировали используемые библиотеки и составили список селекторов, которые создавали различные методы. Затем мы очистили всю HTML-версию веб-сайта с помощью Wget и перекрестно указали очищенный HTML для этих селекторов.

# Recursively scrape the site, ignore specific extensions, and append .html extension.
wget http://panther.local -r -R gif,jpg,pdf,css,js,svg,png –adjust-extension

После того, как мы получили список того, где и когда нам нужна была каждая библиотека, мы изменили уровень предварительной обработки Drupal, чтобы загрузить их только тогда, когда это необходимо. Благодаря этому мы уменьшили размер пакета JavaScript на несколько сотен килобайт! Кроме того, мы перемещали как можно больше файлов JavaScript в футер (таким образом, улучшая Time to First Paint).

Дополнительное преимущество front end

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

Вы можете видеть на изображении выше, что в процессе рендеринга происходит еще одна операция макета. Если мы внимательно рассмотрим, Chrome Developer Tools позволяет нам отслеживать это.

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

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

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

Предварительная загрузка веб-шрифтов с помощью подсказок ресурсов

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

<link rel="preload" href="/sites/all/themes/zeus/fonts/tablet_gothic/360074_3_0.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/sites/all/themes/zeus/fonts/tablet_gothic/360074_2_0.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/sites/all/themes/zeus/fonts/tablet_gothic/360074_4_0.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/sites/all/themes/zeus/fonts/tablet_gothic/360074_1_0.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/sites/all/themes/zeus/fonts/tablet_gothic_condensed/360074_5_0.woff2" as="font" type="font/woff2" crossorigin>

Да! С подсказками ресурсов браузер сразу узнает о файлах и будет загружать файлы, как только это будет возможно. Это устраняет повторную компоновку и связанную с ней вспышку неравномерного содержимого (FOUT). Это также уменьшает время до метрики времени до последнего баннера.

>Предварительная загрузка адаптивных изображений через подсказки ресурсов

Давайте посмотрим на страницу «Просмотр фильма» в вкладке «Сеть разработчиков Chrome». Для этого вы нажимаете значок панели инструментов, который выглядит как камера. Когда мы обновляемся, мы видим, что все быстро загружается, за исключением фонового изображения баннера. Это влияет на показатель Last Hero Paint.

Если вы перейдете на вкладку «Сеть», мы увидим, что изображение баннера было 65-м ресурсом для загрузки. Это связано с тем, что на изображение ссылается свойство CSS background-image. Чтобы загрузить изображение, браузер должен сначала загрузить и интерпретировать пакет CSS, а затем перекрестно ссылаться на него с помощью DOM.

Нам нужно выяснить способ для подсказки ресурсов для этого изображения. Однако для экономии полосы пропускания мы загружаем разные версии фонового изображения в зависимости от ширины экрана. Чтобы убедиться, что мы загружаем правильное изображение, мы включаем атрибут media в элемент ссылки.

Нам нужно убедиться, что мы не загружаем несколько версий одного и того же фонового изображения, и мы, конечно же, не хотим извлекать ненужные ресурсы.

 <link rel="preload" href="/<?php print $zeus_theme_path; ?>/images/new-design/homepage/hero-image-primary--small.jpg" as="image" media="(max-width: 640px)"> <link rel="preload" href="/<?php print $zeus_theme_path; ?>/images/new-design/homepage/hero-image-primary--med.jpg" as="image" media="(min-width: 640px) and (max-width: 980px)"> <link rel="preload" href="/<?php print $zeus_theme_path; ?>/images/new-design/homepage/hero-image-primary--med-large.jpg" as="image" media="(min-width: 980px) and (max-width: 1200px)"> <link rel="preload" href="/<?php print $zeus_theme_path; ?>/images/new-design/homepage/hero-image-primary.jpg" as="image" media="(min-width: 1200px)">

На этом этапе правильное фоновое изображение для окна просмотра загружается сразу же после шрифтов, и это полностью удаляет FOUT (вспышка неровного содержимого) — по крайней мере, при быстрых соединениях.

Заключение

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

Автор: Mike Herchel

Источник: https://www.lullabot.com/

Редакция: Команда webformyself.