Нет ничего хуже, чем развернуть приложение после нескольких месяцев напряженной работы только для того, чтобы понять, что у него ужасная оценка производительности Lighthouse. Все время, которое вы вкладываете в TDD, DRY, SEO и другие модные слова du-jour, напрасно, если ваше приложение будет наказано поисковыми системами за низкие показатели производительности или, что еще хуже, если ваши пользователи собираются уйти от ваших целевая страница через 5 секунд вечности, которая необходима браузеру для загрузки и анализа этого пакета генетически модифицированного JavaScript размером 3 Мб.

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

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

  1. Верните свое мышление AMD

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

Допустим, мы хотим отобразить карту Google. Он не имеет отношения к нашему SEO, нам не нужен его предварительный рендеринг, он даже не нужно отображать, пока пользователь не прокрутит вниз до определенной части нашей страницы. Даже если ваше приложение не было предварительно обработано, нет причин, по которым Google Maps блокирует вашу страницу. Если вы запустите проверку Lighthouse на странице, которая использует Google Maps, вы увидите, насколько ужасно это влияет на производительность.

Вот другой подход (я уже писал статью об этом раньше). Я использую компоненты Vue.js, но это применимо к любой интерфейсной платформе. Идея состоит в том, чтобы загрузить вашу зависимость только тогда, когда компонент смонтирован, и отобразить ее, когда зависимости загружены.

2. Держите свой <head> свет

Когда нас торопят сроки, возникает соблазн просто поместить элементы в <head> и двигаться дальше, но даже один тег <script> или <link> может существенно повлиять на производительность. Сторонние скрипты, шрифты, таблицы стилей - все это необходимо загрузить и проанализировать, что заставляет пользователя ждать.

2.1. <script>

Подход, который я описал выше, позволяет вам убедиться, что сторонний скрипт загружен, прежде чем вы попытаетесь действовать в соответствии с ним. Если вы загружаете сценарий, который может выполняться независимо, обязательно асинхронно и отложите его, чтобы сделать его неблокирующим <script async defer src=""/>. Тем не менее, подумайте, есть ли веская причина для размещения этого скрипта в заголовке вашего документа, есть вероятность, что он может счастливо жить в конце вашего документа, до закрывающего тега </body>. Сервисы, жаждущие наших данных, например, Google Analytics, захотят, чтобы вы загрузили их скрипты в голову, но Lighthouse накажет вас за это. Я разработчик, заботящийся о конфиденциальности, поэтому не слушаю: мой предпочтительный подход - спросить у пользователя разрешение на отслеживание, а затем асинхронно загрузить скрипт, добавив тег скрипта (как показано в моем первом примере).

2.2. <link rel="stylesheet" />

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

3. Отложенная загрузка визуальных ресурсов

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

Что касается изображений, обратите внимание на малоизвестные атрибуты srcset и decoding. Используя webpack, вы можете обслуживать набор оптимизированных изображений в зависимости от разрешения экрана, задав атрибут srcset, который поддерживается всеми вечнозелеными браузерами. Это то, что вам нужно будет учесть в начале вашего проекта и убедиться, что ваши компоненты совместимы. Атрибут decoding может использоваться, чтобы отложить декодирование изображений и помочь сократить время рисования на вашей странице.

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

Пожалуй, самый полезный инструмент для работы с изображениями и видео в папке - это IntersectionObserver. Я обнаружил, что если вы просто не показываете их, пока они не появятся в поле зрения, это действительно поможет вашей оценке Lighthouse.

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

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

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