Простой способ повысить эффективность сайта – выпуск Google I/O 2018

На конференции Google I/O 2018 мы представили обзор инструментов, библиотек и методов оптимизации, которые упрощают повышение производительности сайтов. В этой статье мы объясним их на примере приложения The Oodles Theater. Мы также расскажем о наших экспериментах с упреждающей загрузкой и новой инициативе Guess.js.

Ewa Gasperowicz

В прошлом году мы много работали над тем, чтобы сделать интернет быстрее и эффективнее. В результате появились новые инструменты, подходы и библиотеки, о которых мы расскажем в этой статье. В первой части мы покажем вам некоторые методы оптимизации, которые мы использовали на практике при разработке приложения Oodles Theater. Во второй части мы поговорим о наших экспериментах с предиктивной загрузкой и новой инициативой Guess.js.

.

Необходимость в эффективности

С каждым годом интернет становится все тяжелее. Если мы проверим состояние интернета, то увидим, что средняя страница на мобильном устройстве весит около 1,5 МБ, причем большая часть этого объема приходится на JavaScript и изображения.

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

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

Пирамида иерархии UX
Рис. 1. Насколько важна скорость для пользователей? (Speed Matters, Vol. 3)

Мы знаем, что производительность важна для пользователей, но не всегда понятно, с чего начать оптимизацию. К счастью, есть инструменты, которые могут вам помочь.

Lighthouse – основа для работы с производительностью

Lighthouse – это часть инструментов разработчика Chrome, которая позволяет провести аудит сайта и получить рекомендации по его улучшению.

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

Новые проверки Lighthouse
Рис. 2. Новые проверки Lighthouse

Давайте посмотрим, как вы можете использовать их на практике, на примере Oodles Theater. Это небольшое демонстрационное веб-приложение, в котором вы можете попробовать некоторые из наших любимых интерактивных дудлов Google и даже сыграть в пару игр.

При создании приложения мы хотели сделать его максимально производительным. Отправной точкой для оптимизации стал отчет Lighthouse.

Отчет Lighthouse для приложения Oodles
Рис. 3. Отчет Lighthouse для приложения Oodles

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

Размер страницы составлял около 3,4 МБ, и нам нужно было срочно его уменьшить.

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

Возможности оптимизации эффективности

Удалите ненужные ресурсы

Есть очевидные вещи, которые можно безопасно удалить: пробелы и комментарии.

Преимущества минификации
Рис. 4. Уменьшайте и сжимайте файлы JavaScript и CSS.

Lighthouse выделяет эту возможность в аудите неминифицированных CSS и JavaScript. Для сборки мы использовали webpack, поэтому для минификации нам понадобился только плагин Uglify JS.

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

Ещё одна полезная проверка – Включите сжатие текста. Нет причин отправлять несжатые файлы, и большинство сетей доставки контента поддерживают это по умолчанию.

Мы использовали Firebase Hosting для размещения нашего кода, а Firebase по умолчанию включает gzipping, поэтому благодаря размещению нашего кода в разумной CDN мы получили это бесплатно.

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

Используйте эффективные правила кеширования

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

Проверка Неэффективные правила кеширования в Lighthouse помогла нам понять, что мы можем оптимизировать стратегии кеширования, чтобы добиться именно этого. Установив заголовок max-age expiration на нашем сервере, мы убедились, что при повторном посещении пользователь может повторно использовать ресурсы, которые он загрузил ранее.

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

Удалите неиспользуемый код

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

Покрытие кода в инструментах разработчика
Рис. 5. Проверьте покрытие кода.

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

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

В DevTools можно посмотреть статистику покрытия кода как для времени выполнения, так и для времени загрузки приложения. На нижнем скриншоте вы видите две большие красные полосы – у нас было более 95 % неиспользуемого CSS, а также большая часть JavaScript.

Lighthouse также обнаружил эту проблему при проверке неиспользуемых правил CSS. Он показал потенциальную экономию более 400 КБ. Мы вернулись к коду и удалили из библиотеки и JavaScript, и CSS.

Если мы уберем адаптер MVC, размер стилей уменьшится до 10 КБ.
Рис. 6. Если мы удалим адаптер MVC, размер стилей уменьшится до 10 КБ.

Это позволило уменьшить размер пакета CSS в 20 раз, что довольно неплохо для крошечного коммита длиной в две строки.

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

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

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

Кнопки не работают из-за отсутствия библиотеки
Рис. 7. Один компонент по-прежнему использовал удаленную библиотеку.

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

Избегайте передачи больших объемов данных по сети

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

Lighthouse обнаружил проблему с некоторыми сетевыми полезными нагрузками, используя аудит Огромная сетевая полезная нагрузка.

Обнаружение огромных полезных нагрузок сети
Рис. 8. Обнаружение слишком больших сетевых полезных нагрузок

Мы обнаружили, что объем кода, который передается пользователям, превышает 3 МБ. Это довольно много, особенно для мобильных устройств.

В самом верху этого списка Lighthouse выделил пакет JavaScript от поставщика, который содержал 2 МБ несжатого кода. На эту проблему также указывает webpack.

Как говорится, самый быстрый запрос – это тот, который не был сделан.

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

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

Аудит пакета JavaScript
Рис. 9. Аудит пакетов JavaScript

Мы начали с анализатора пакетов webpack, который сообщил нам, что мы включаем зависимость под названием unicode, которая представляет собой 1,6 МБ проанализированного JavaScript, то есть довольно много.

Затем мы перешли в редактор и с помощью плагина Import Cost для Visual Studio Code смогли визуализировать стоимость каждого импортируемого модуля. Это позволило нам обнаружить, какой компонент включал код, ссылающийся на этот модуль.

Затем мы перешли к другому инструменту – BundlePhobia. Это инструмент, который позволяет вам ввести название любого пакета NPM и фактически увидеть, каков его минимизированный и заархивированный размер. Мы нашли хорошую альтернативу модулю slug, который мы использовали, который весил всего 2,2 КБ, и поэтому мы его заменили.

Это сильно повлияло на нашу эффективность. Благодаря этому изменению и другим возможностям уменьшить размер пакета JavaScript мы сэкономили 2, 1 МБ кода.

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

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

Сократите время загрузки JavaScript с помощью разделения кода

Хотя большие сетевые полезные нагрузки могут оказать большое влияние на наше приложение, есть ещё одна вещь, которая может оказать действительно большое влияние, и это JavaScript.

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

Вот как браузер обрабатывает JavaScript.

Обработка JavaScript
Рис. 10. Обработка JavaScript

Сначала мы должны скачать этот скрипт, у нас есть движок JavaScript, который затем должен проанализировать этот код, скомпилировать его и выполнить.

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

Чтобы помочь вам обнаружить эти проблемы в вашем приложении, мы добавили в Lighthouse новый аудит времени загрузки JavaScript.

Время загрузки JavaScript
Рис. 11. Проверка времени загрузки JavaScript

В случае с приложением Oodle мы видим, что на запуск JavaScript ушло 1,8 секунды. Проблема была в том, что мы статически импортировали все маршруты и компоненты в один монолитный пакет JavaScript.

Один из способов обойти это ограничение – разделение кода.

Разделение кода похоже на пиццу

Разделение кода – это концепция, согласно которой вместо того, чтобы давать пользователям целую пиццу JavaScript, вы даете им по одному кусочку за раз, по мере необходимости.

Разделение кода можно применять на уровне маршрута или компонента. Он отлично работает с React и React Loadable, Vue.js, Angular, Polymer, Preact и многими другими библиотеками.

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

Разделение кода с помощью динамического импорта
Рис. 13. Разделение кода с помощью динамического импорта.

Это позволило не только уменьшить размер пакетов, но и сократить время загрузки JavaScript. Оно сократилось до 0,78 секунды, то есть приложение стало работать на 56 % быстрее.

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

Используйте такие концепции, как разделение кода, изучите такие идеи, как tree shaking, и загляните в репозиторий webpack-libs-optimizations, чтобы узнать, как можно уменьшить размер библиотеки, если вы используете webpack.

Оптимизируйте изображения

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

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

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

Проверка изображений
Рис. 14. Проверка изображений в Lighthouse

Мы начали с оптимизации изображений.

Для разовой оптимизации можно использовать визуальные инструменты, такие как ImageOptim или XNConvert.

Более автоматизированный подход – добавить шаг оптимизации изображений в процесс сборки с помощью таких библиотек, как imagemin.

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

Если вы не хотите использовать CDN из-за стоимости или задержек, попробуйте альтернативные решения, например Thumbor или Imageflow.

До и после оптимизации
Рис. 15. До и после оптимизации

Наше фоновое изображение в формате PNG было помечено в webpack как слишком большое, и это было справедливо. После того как мы подогнали его под размер области просмотра и обработали в ImageOptim, его размер уменьшился до 100 КБ, что вполне приемлемо.

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

Используйте подходящий формат для анимированного контента

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

В приложении Oodle мы использовали GIF-изображение в качестве заставки на главной странице. Согласно Lighthouse, мы могли бы сэкономить более 7 МБ, перейдя на более эффективный формат видео. Наш клип весил около 7,3 МБ, что слишком много для любого сайта, поэтому мы превратили его в видеоэлемент с двумя исходными файлами – MP4 и WebM для более широкой поддержки браузеров.

Замените анимированные GIF-файлы видеороликами
Рис. 16. Замените анимированные GIF-файлы видео.

Для преобразования анимированного GIF-файла в формат MP4 мы использовали инструмент FFmpeg. Формат WebM позволяет сэкономить ещё больше места. ImageOptim API может выполнить такое преобразование за вас.

ffmpeg -i animation.gif -b:v 0 -crf 40 -vf scale=600:-1 video.mp4

Благодаря этому преобразованию нам удалось сэкономить более 80 % от общего веса. Это позволило нам уменьшить размер до 1 МБ.

Тем не менее, 1 МБ – это большой объем данных, особенно для пользователей с ограниченной пропускной способностью. К счастью, мы можем использовать Effective Type API, чтобы определить, что у пользователя медленное подключение, и показать ему изображение в формате JPEG меньшего размера.

Этот интерфейс использует эффективное время прохождения сигнала и значения загрузки, чтобы определить тип сети, к которой подключен пользователь. Он просто возвращает строку: slow 2G, 2G, 3G или 4G. В зависимости от этого значения, если пользователь находится ниже 4G, мы можем заменить видеоэлемент изображением.

if (navigator.connection.effectiveType) { ... }

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

Настройте отложенную загрузку изображений вне экрана

Карусели, слайдеры и очень длинные страницы часто загружают изображения, даже если пользователь не видит их сразу.

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

Отложенная загрузка пока не поддерживается браузерами, поэтому для ее реализации необходимо использовать JavaScript. Мы использовали библиотеку Lazysizes, чтобы добавить отложенную загрузку для обложек Oodle.

<!-- Import library -->
import lazysizes from 'lazysizes'  <!-- or -->
<script src="lazysizes.min.js"></script>

<!-- Use it -->

<img data-src="image.jpg" class="lazyload"/>
<img class="lazyload"
    data-sizes="auto"
    data-src="image2.jpg"
    data-srcset="image1.jpg 300w,
    image2.jpg 600w,
    image3.jpg 900w"/>

Lazysizes – это умная библиотека, которая не только отслеживает изменения видимости элемента, но и упреждающе предварительно загружает элементы, находящиеся рядом с областью просмотра, для оптимального взаимодействия с пользователем. Кроме того, вы можете интегрировать IntersectionObserver, чтобы эффективно отслеживать видимость.

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

Помогите браузеру быстрее доставлять важные ресурсы

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

Было бы полезно, если бы мы, как авторы страницы, могли сообщить браузеру, что для нас действительно важно. К счастью, за последние несколько лет разработчики браузеров добавили ряд функций, которые помогают нам в этом, например подсказки ресурсов, такие как link rel=preconnect, preload или prefetch.

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

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

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

Избегайте многократных дорогостоящих обращений к источнику.
Рис. 17. Избегайте многочисленных и дорогостоящих обращений туда и обратно к любому пункту отправления.

В приложении Oodle мы активно используем Google Fonts. Каждый раз, когда вы добавляете на страницу таблицу стилей Google Fonts, она подключается к двум субдоменам. Lighthouse сообщает, что если бы мы могли прогреть это соединение, то могли бы сэкономить до 300 миллисекунд времени начального соединения.

Используя link rel preconnect, мы можем эффективно маскировать задержку соединения.

Это особенно важно для таких сервисов, как Google Fonts, где CSS-код шрифтов размещен на googleapis.com, а ресурсы шрифтов – на Gstatic. Мы применили эту оптимизацию и сэкономили несколько сотен миллисекунд.

Следующее, что предлагает Lighthouse, – это предварительная загрузка ключевых запросов.

Предварительная загрузка основных запросов
Рис. 18. Выполняйте предзагрузку ключевых запросов

<link rel=preload> – это очень мощный инструмент. Он сообщает браузеру, что ресурс необходим для текущей навигации, и пытается заставить браузер получить его как можно скорее.

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

Предзагрузка веб-шрифта выглядит следующим образом: указывая rel=preload, вы передаете as с типом шрифта, а затем указываете тип шрифта, который пытаетесь загрузить, например woff2.

Это может сильно повлиять на вашу страницу.

Влияние предзагрузки ресурсов
Рис. 19. Влияние предзагрузки ресурсов

Обычно, если вы не используете link rel preload, а веб-шрифты критически важны для вашей страницы, браузеру приходится сначала получить HTML, проанализировать CSS и только потом получить веб-шрифты.

Используя link rel preload, как только браузер проанализирует ваш HTML, он может начать получать эти веб-шрифты намного раньше. В случае с нашим приложением это позволило сократить время, необходимое для отрисовки текста с использованием веб-шрифтов, на секунду.

Но если вы собираетесь выполнять предзагрузку шрифтов Google Fonts, есть один нюанс.

URL-адреса Google Fonts, которые мы указываем для шрифтов в таблицах стилей, обновляются командой Google Fonts довольно регулярно. Срок действия этих URL может истечь, или они могут регулярно обновляться, поэтому, если вы хотите полностью контролировать загрузку шрифтов, мы рекомендуем размещать веб-шрифты на собственном хостинге. Это может быть здорово, потому что дает вам доступ к таким вещам, как link rel preload.

В нашем случае мы нашли инструмент Google Web Fonts Helper, который действительно помог нам отключить некоторые из этих веб-шрифтов и настроить их локально, поэтому ознакомьтесь с этим инструментом.

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

Экспериментальная функция: подсказки приоритета

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

Установите приоритет для контента, который виден сразу
Рис. 20. Подсказки по приоритету

Это новая функция, которая позволяет указать браузеру, насколько важен ресурс. Она предоставляет новый атрибут – важность – со значениями "низкая", "высокая" или "авто".

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

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

Установите приоритет для контента, который виден сразу
Рис. 21. Установите приоритет для контента, который виден сразу.

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

Мы надеемся добавить эту функцию в Canary в ближайшие несколько недель. Следите за новостями.

Используйте стратегию загрузки веб-шрифтов

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

Теперь в Lighthouse есть проверка Настройте показ текста во время загрузки веб-шрифтов.

Как избежать невидимого текста во время загрузки веб-шрифтов
Рис. 22. Настройте показ текста во время загрузки веб-шрифтов.

Если вы загружаете веб-шрифты с помощью блока font-face, то браузер сам решает, что делать, если загрузка шрифта занимает много времени. Некоторые браузеры будут ждать до трех секунд, прежде чем вернуться к системному шрифту, и в конечном итоге заменят его на шрифт после его загрузки.

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

    @font-face {
      font-family: 'Montserrat';
      font-style: normal;
      font-display: swap;
      font-weight: 400;
      src: local('Montserrat Regular'), local('Montserrat-Regular'),
          /* Chrome 26+, Opera 23+, Firefox 39+ */
          url('montserrat-v12-latin-regular.woff2') format('woff2'),
            /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
          url('montserrat-v12-latin-regular.woff') format('woff');
    }

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

В этом случае мы используем font-display: swap. Swap дает шрифту нулевой период блокировки и бесконечный период замены. Это означает, что браузер сразу же отобразит текст, используя резервный шрифт, если основной шрифт загружается слишком долго. И он заменит его, как только шрифт станет доступен.

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

Результат отображения шрифта
Рис. 23. Результат отображения шрифта

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

Существует множество функций веб-платформы, которые можно использовать для оптимизации загрузки шрифтов. Также рекомендуем ознакомиться с репозиторием Web Font Recipes Зака Лезермана (Zach Leatherman).

Уменьшите количество скриптов, блокирующих отрисовку

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

На ленте хронологии Lighthouse видно, что в течение первых нескольких секунд, когда загружаются все ресурсы, пользователь не видит никакого контента.

Возможность сократить количество таблиц стилей, блокирующих отрисовку
Рис. 24. Возможность сократить количество таблиц стилей, блокирующих отрисовку

Скачивание и обработка внешних таблиц стилей блокирует процесс отрисовки.

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

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

В нашем случае мы использовали модуль NPM под названием Critical, чтобы встроить критически важный контент в index.html на этапе сборки.

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

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

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

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

Результат

Это был длинный список оптимизаций производительности, которые мы применили к нашему сайту. Давайте посмотрим на результат. Вот как наше приложение загружалось на мобильном устройстве среднего уровня в сети 3G до и после оптимизации.

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

Прогнозирование эффективности – пользовательский опыт на основе данных

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

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

У нас есть данные, которые помогут нам оптимизировать кампанию. Используя Google Аналитика Reporting API, мы можем посмотреть, на какие страницы чаще всего переходят пользователи с определенного URL и каков процент выходов с него. Это поможет нам понять, какие ресурсы следует оптимизировать в первую очередь.

Если мы объединим это с хорошей вероятностной моделью, мы избежим траты данных наших пользователей за счет агрессивного чрезмерного предварительного извлечения контента. Мы можем воспользоваться этими данными Google Аналитики и применить машинное обучение и такие модели, как цепи Маркова или нейронная сеть, чтобы реализовать эти модели.

Объединение веб-приложений на основе данных
Рис. 25. Data-driven Bundling for Web Apps

Чтобы упростить проведение таких экспериментов, мы рады представить новую инициативу под названием Guess.js.

Guess.js
Рис. 26. Guess.js

Guess.js – это проект, направленный на улучшение пользовательского опыта в интернете на основе данных. Надеемся, что это вдохновит вас на использование данных для улучшения производительности веб-сайтов и не только. Все это ПО с открытым исходным кодом, которое уже доступно на GitHub. Он был создан в сотрудничестве с сообществом разработчиков ПО с открытым исходным кодом Минко Гечевым, Кайлом Мэтьюсом из Gatsby, Кэти Хемпениус и другими.

Попробуйте Guess.js и поделитесь своим мнением.

Сводка

Оценки и показатели помогают повысить скорость работы сайта, но это лишь средства, а не цели.

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

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

Особая благодарность: Ward Peeters, Minko Gechev, Kyle Mathews, Katie Hempenius, Dom Farolino, Yoav Weiss, Susie Lu, Yusuke Utsunomiya, Tom Ankers, Lighthouse и дудлы Google.