Согласно web.dev, улучшение качества взаимодействия с пользователем — ключ к долгосрочному успеху любого сайта. Понимая, насколько важен для развития интернета качественный пользовательский опыт, компания Google в 2020 году представила инициативу Web Vitals. Это единое руководство по метрикам качества, которые необходимы для обеспечения удобного взаимодействия с пользователем. Хотя за прошедшие годы Google создала ряд инструментов для измерения эффективности взаимодействия и составления отчетов (Lighthouse, PageSpeed Insights и Measure), Web Vitals должна упростить измерение производительности и помогает разработчикам сайтов сосредоточиться на самых важных показателях — Core Web Vitals.
Core Web Vitals
CWV — это подмножество метрик инициативы Web Vitals, позволяющих численно оценить впечатления пользователя от вашего сайта. Полученные с их помощью оценки пользовательского опыта применимы ко всем веб-страницам (независимо от их специализации), поэтому владельцам сайтов необходимо измерять CWV. Google планирует поддержать CWV во всех своих инструментах для разработчиков.
Метрики CWV будут развиваться с течением времени (лог изменений), на текущий момент их три:
- Largest Contentful Paint (LCP): воспринимаемая скорость загрузки. Значение метрики — это время, которое прошло с момента начала загрузки страницы до момента, когда основное содержимое, вероятно, загружено. Окончание загрузки определяется по моменту отрисовки самого большого элемента (изображение или текстовый блок, видимый в области просмотра). Значение метрики должно быть как можно меньше (75-й перцентиль равен 2,5 секунды).
- First Input Delay (FID): интерактивность страницы (численная оценка опыта, который испытывают пользователи, пытаясь взаимодействовать с неотвечающими страницами). Значение метрики является временем, которое прошло с момента, когда пользователь впервые начал взаимодействовать со страницей (нажал на ссылку, кнопку и т.п.), и до момента, когда браузер может ответить на это действие. Значение метрики должно быть как можно меньше (75-й перцентиль равен 100 миллисекундам, но уже сейчас Google «по-прежнему настоятельно рекомендует использовать 95—99 процентили»).
- Cumulative Layout Shift (CLS): визуальная стабильность. Значение метрики — это показатель наибольшего неожиданного сдвига макета (layout shift), который происходит в течение определенного времени. До 1 июня 2021 года метрика охватывала весь жизненный цикл страницы, однако сейчас она означает быструю последовательность сдвигов (shifts) с интервалом менее 1 секунды между сдвигами и не более 5 секунд для всей последовательности. Неожиданными сдвигами являются те, которые происходят без анимации или позднее 500 миллисекунд после пользовательского ввода. То есть на CLS влияют все неожиданные сдвиги содержимого при взаимодействии с сайтом (например, вызванные загрузкой баннеров или других асинхронных блоков). Значение метрики должно быть как можно меньше (75-й перцентиль равен 0,1).
Значение CWV для продукта
Для менеджеров продукта мотивацией к улучшению показателей Web Vitals может быть положительное влияние высоких оценок сайта на повышение качества пользовательского опыта, которое, в конечном итоге, влияет на длительность сессии и конверсию пользователей. Множество примеров влияния улучшения CWV-показателей на ключевые показатели бизнеса (Key Performance Indicators, KPI) можно найти на сайте WPO stats.
Другой мотивацией может стать влияние метрик на SEO: с мая 2021 года Google учитывает значения метрик при ранжировании сайтов в поисковой выдаче. А начиная с 85 версии Chrome для Android при переходе по ссылкам добавляет специальную метку для страниц, которые обладают высокими оценками по CWV.
Опыт главной страницы Mail.ru
Прежде чем рассказывать о нашем опыте улучшения CWV давайте кратко познакомимся с техническими особенностями главной страницы. Долгое время проект разрабатывался на основе собственного XML-like шаблонизатора Fest, однако в 2019 году мы от него отказались в пользу Svelte 3. Подробнее о преимуществах и недостатках Fest, а также о мотивации к изменению стека технологий в пользу Svelte можно узнать из доклада нашей команды на Svelte Russia Meetup #1. Отметим, что хотя Svelte и реализует реактивность, но не использует Virtual DOM, поэтому менее требователен к ресурсам. Подход, используемый в Svelte, позволяет избежать добавления неиспользуемых функций в результирующий код (бандл), потому что код, реализующий эти функции, просто не генерируется компилятором, если функции не используются. То есть на этапе компиляции этот код вырезается, что приводит к уменьшению результирующего бандла. Всё это само по себе положительно влияет на оценки по метрике FID CWV. Но несмотря на это, наш опыт исправления CWV может быть интересен тем, кто использует популярные фреймворки «большой тройки», или даже практически любой технологический стек.
Мы и до появления CWV контролировали значения некоторых других метрик Web Vitals, таких как First Contentful Paint (FCP), Total Blocking Time (TBT), Time to Interactive (TTI), с помощью дашборда для мониторинга производительности. Напомним:
- FCP — время с момента начала загрузки страницы до момента отображения какой-либо части содержимого. Отвечает за воспринимаемую пользователями скорость загрузки приложения. Помогает в диагностике проблем с LCP CWV (мониторинг ресурсов, блокирующих рендеринг).
- TBT — общее количество времени, в течение которого страница не отвечает на действия пользователя, такие как клики мыши, касания экрана или нажатия клавиатуры. Помогает выявлять и диагностировать потенциальные проблемы с интерактивностью, которые могут повлиять на FID CWV.
- TTI — сколько времени требуется странице, чтобы стать полностью интерактивной. Аналогично TBT помогает в обнаружении проблем с FID CWV.
Поэтому начать улучшать метрики CWV мы решили с внедрения системы мониторинга для CWV. Однако чтобы иметь возможность оценить результаты, необходимо понять, что именно влияет на различные метрики, то есть изучить рекомендации Google.
Рекомендации Google по улучшению CWV
Для улучшения метрик CWV компания Google предлагает ряд готовых советов. Однако поскольку в нашей команде разработчики всегда заинтересованы в повышении скорости работы страницы, то некоторая работа по улучшению метрик уже проводилась. Нужно было понять, что именно из советов уже реализовано, а также какие рекомендации следует применить.
Выделим основные советы Google по улучшению метрик CWV. Рядом с каждым советом мы добавили обозначения для десктопной версии главной страницы: ???? — уже реализовано, ???? — частично используется, ???? — не внедрено, ⚫️ — неприменимо (неактуально из-за специфики нашего проекта). Список рекомендаций:
-
LCP:
-
Длительное время ответа сервера
- Оптимизируйте работу динамического SSR (Server-Side Rendering) (в том числе серверных обращений за данными) — ????
- Направляйте пользователей в ближайшую CDN (Content Delivery Network, сеть доставки и дистрибуции содержимого) — ⚫️
- Настройте кеширование статических файлов (например, с помощью настройки заголовков ответов в Nginx) — ????
- Используйте Service Worker для кеширования — ????
- Устанавливайте сторонние (third-party) подключения на раннем этапе с помощью предзагрузки контента (специальных HTML-тегов) — ????
- Используйте подписанные HTTP-обмены (Signed exchanges, SXGs) (актуально для сайтов, получающих наибольший трафик из результатов поиска Google) — ⚫️
-
Блокировка рендеринга JavaScript и CSS
-
Уменьшение времени блокировки CSS
-
Уменьшение времени блокировки JavaScript
- Используйте все описанные выше техники для CSS (кроме отсрочивания загрузки некритичного JavaScript) — ????
- Минимизируйте количество неиспользуемых полифилов — ????
-
Уменьшение времени блокировки CSS
-
Медленная загрузка ресурсов
- Оптимизируйте и сжимайте изображения (кроме использования новейших форматов, таких как WebP) — ????
- Предварительно загружайте важные ресурсы — ????
- Сжимайте текстовые файлы (например, используя Gzip) — ????
- Используйте адаптивную подачу — ⚫️
- Кешируйте статические файлы с помощью Service Worker — ????
-
Клиентский рендеринг
-
Длительное время ответа сервера
-
FID:
- Высокое влияние стороннего кода
-
Долгое выполнение JavaScript
-
Минимизация работы основного потока
-
Обработка скриптов
-
Стили и верстка
-
Рендеринг
-
Парсинг HTML и CSS
-
Разбор (парсинг) и выполнение скриптов (схожие техники применяются в разделе «Долгое выполнение JavaScript» выше)
- Отправляйте только тот код, который нужен вашим пользователям, реализовав разделение кода (code splitting) — ????
- Удалите неиспользуемый код — ????
-
Сборка мусора (Garbage collection)
-
Обработка скриптов
- Сохраняйте небольшое количество запросов и небольшие размеры отправляемых данных — ????
- Высокое влияние стороннего кода
-
CLS:
-
Оптимизация загрузки изображений
- Используйте атрибуты изображений width и height для генерации CSS aspect-ratio — ????
- Добавляйте атрибут srcset для отзывчивых изображений — ????
-
Рекламные баннеры, встраиваемые объявления и окна iframe без предварительно известных размеров
- Статично зарезервируйте место для рекламного баннера — ????
- Будьте осторожны, размещая не-sticky рекламу в верхней части области просмотра (избегайте сдвига всей страницы после асинхронной загрузки рекламного баннера) — ⚫️
- Избегайте сворачивания зарезервированного под рекламу места, если рекламный баннер не приходит. Показывайте плейсхолдер — ????
- Устраняйте сдвиги (shifts), зарезервировав максимально возможный размер возможной рекламы. Или выберите наиболее вероятный размер рекламного места на основе исторических данных — ????
-
Динамически появляющийся контент
- Избегайте вставки нового содержимого над существующим контентом, если только это не является ответом на взаимодействие с пользователем. Это гарантирует, что любые изменения макета будут ожидаемыми — ????
-
Шрифты, вызывающие сдвиги
- Используйте font-display — ⚫️
- Применяйте Font Loading API для ускорения загрузки необходимых шрифтов — ⚫️
- Используйте теги для предзагрузки — ⚫️
-
Анимации
- Отдавайте предпочтение transform-анимации свойств, запускающих изменение макета — ????
-
Оптимизация загрузки изображений
Хотя этот список содержит только основные рекомендации, он уже довольно велик. Ряд советов для улучшения метрик LCP и FID повторяется. Для упрощения будущей работы по улучшению показателей CWV можно выделить следующие ключевые направления, сильнее всего влияющие на LCP и FID:
- Наличие SSR.
- Отправка только нужного пользователям кода, то есть реализация разделения кода (code splitting).
- Минификация и сжатие отправляемых данных.
- Настройка тегов для предзагрузки и атрибутов для асинхронной загрузки ресурсов.
- Эффективное кеширование с помощью настройки заголовков серверов.
- Оптимизация рендеринга (раздел «Минимизация работы основного потока» в FID в советах от Google выше).
- Применение Web Workers.
Если проанализировать список, то видно, что наименьшие показатели CWV на главной странице портала Mail.ru можно было ожидать у метрики CLS, поскольку по ней выполнялось меньше всего рекомендаций.
А теперь расскажем о своем опыте улучшения метрик Web Vitals.
Мониторинг метрик производительности
Как было сказано выше, перед началом работы над улучшением CWV необходимо оценить общую ситуацию со значениями метрик у реальных пользователей. Положиться только на запуск на машинах разработчиков таких инструментов, как Lighthouse, нельзя, поскольку так на отдельные измерения будет сильно влиять актуальное состояние окружения разработчика, в частности, скорость сети и загруженность процессора. То есть реальную картину нельзя воспроизвести синтетически. Необходим мониторинг данных реальных пользователей (Real User Monitoring, RUM), что также является рекомендацией Google. Поэтому возникла необходимость внедрения системы мониторинга показателей метрик CWV у клиентов.
Одновременно у наших коллег из Почты Mail.ru появилась инициатива по созданию универсальной Frontend «Платформы» и её внедрению внутри проектов Mail.ru Group. Часть её уже доступна в OpenSource. Одним из компонентов платформы является единый шаблон Health Page-дашборда Grafana, содержащий информацию об ошибках (клиентские ошибки JavaScript, статусы вызываемых API). Основной причиной перехода на унифицированные Health Page-страницы является упрощение анализа состояния каждого проекта различными около-почтовыми командами. Наличие простого и понятного для каждого разработчика Health Page-дашборда может облегчить мониторинг ошибок при работе над различными страницами внутри Почты Mail.ru, а также при выкатках отдельных кросс-портальных виджетов на различные проекты (часть блоков Почты Mail.ru и около-почтовых проектов разрабатывают независимые команды в виде отдельных виджетов, реализуя микрофронтенды).
То есть главная причина внедрения единого дашборда Health Page состояла в том, чтобы разработчики различных команд могли быстро переключаться между своим дашбордом и дашбордами соседних команд, при этом все метрики находились на одних и тех же местах. Другим преимуществом внедрения общего шаблона Health Page является единый для всех около-почтовых проектов механизм отслеживания ошибок. Применение одинакового инструмента для логирования позволит сравнить состояния «здоровья» различных проектов, чтобы обеспечить высокое качество всех около-почтовых проектов Mail.ru для пользователей.
Отдельный раздел дашборда посвящён интересующим нас метрикам CWV. Поэтому, несмотря на наличие у нас собственного Health Page-дашборда и механизма сбора ошибок, решили перейти на использование единой «Платформы». Для получения метрик она использует PerformanceObserver API в соответствии с рекомендациями Google (больше подробностей на Medium).
Внедрение механизма мониторинга CWV показало следующие метрики у пользователей (доля пользователей в процентах в соответствии с пороговыми значениями метрик: good — needs-improvement — poor, средние показания за неделю 15-21 марта 2021 года):
- CWV:
- LCP: 52 — 19 — 29
- FID: 92 — 5 — 3
- CLS: 33 — 23 — 44
- Остальные Web Vitals:
- FCP: 35 — 38 — 27
- TBT: 42 — 16 — 42
- TTI: 43 — 25 — 32
Значения Web Vitals до внесения улучшений.
Таким образом подтвердились наши прогнозы относительно наличия проблем с показателями CLS CWV, полученные после изучения актуальных советов от Google. Также необходимо было улучшить значения метрики LCP. Приятным результатом стали высокие оценки по FID. Поэтому мы выбрали основное направление для работы — улучшение метрик CLS и LCP CWV.
Однако при отсутствии «Платформы» в своих проектах для сбора информации о CWV вы можете использовать различные инструменты в зависимости от вашего стека технологий. В частности, одним из самых простых является JavaScript-библиотека web-vitals, рекомендуемая для измерений CWV компанией Google. Также могут использоваться как инструменты, предназначенные для мониторинга производительности (например, Search Console от Google, библиотека Perfume.js), так и различные продукты для сбора аналитики (Google Analytics поддерживает сбор CWV с помощью Web Vitals Report) и клиентских ошибок (Sentry).
При внесении изменений, влияющих на метрики, разработчикам удобно пользоваться Lighthouse или более простым Web Vitals Chrome Extension, можно настроить проверку метрик через CI (подробнее обо всех способах сбора метрик CWV). Более подробную информацию предоставляет WebPageTest. Еще раз подчеркнем, что ключевыми факторами для успешного измерения CWV является сбор метрик у реальных пользователей и возможность анализа производительности с течением времени.
Скелетоны для улучшения CLS
Самые низкие значения CWV были получены по CLS. Основной проблемой плохой визуальной стабильности страницы (согласно панели Performance DevTools браузера Google Chrome, раздел Experience, событие Layout Shift) стали сдвиги макета при загрузке рекламных баннеров. Для устранения нежелательных сдвигов элементов интерфейса в данном случае Google рекомендует использовать плейсхолдеры.
Первым этапом внедрения плейсхолдеров является определение размеров необходимого места для вставки рекламы. К счастью, на десктопной версии главной страницы Mail.ru размеры допустимых рекламных форматов строго документированы, поэтому этот этап прошел быстро. Далее мы согласовывали с дизайнерами формат плейсхолдеров в виде скелетонов. Перейдя к реализации мы остановились на создании SVG-анимированных скелетонов, поскольку отсутствие поддержки SVG-анимаций в Internet Explorer 11 не было для нас критически важным фактором (при строгой необходимости анимаций в Internet Explorer 11 можно использовать CSS).
Главная особенность, с которой мы столкнулись при реализации: важно не только наличие плейсхолдеров, но и отсутствие сдвигов интерфейса при переходе между состояниями отображения скелетонов и рекламных баннеров. Без этого условия нельзя достигнуть высокой визуальной стабильности интерфейса.
Также для улучшения показаний метрики CLS мы поправили атрибуты
width
и height
у изображений.Возвращение SSR
Чтобы было легче перейти с Fest на Svelte, мы решили не создавать новый проект, а поблочно переписывать имеющийся. Из-за особенностей Fest не было возможности совместить его SSR-разметку и разметку Svelte, поэтому при переписывании блоков страницы мы временно отказались от серверного рендеринга для Svelte. Общая схема вставки Svelte-приложения выглядела как загрузка «каркаса» страницы (полученная с помощью SSR Fest) с сервера, а затем вставка клиентского JavaScript-кода Svelte для отрисовки блоков в полученный с сервера «каркас».
Все новые блоки писались изначально на Svelte, это позволило относительно быстро значительно увеличить долю Svelte-кода. К марту 2021 года у нас оставалось только семь блоков на Fest, однако несмотря на это значительная доля Fest оставалась на сервере. Помимо функций шаблонизатора Fest на сервере частично решал задачу получения данных. Поэтому переписывать серверный код мы начали с вынесения в отдельную библиотеку всех относительно «низкоуровневых» функций получения данных. Затем мы решили полностью избавиться от клиентского Fest. После рефакторинга и переписывания семи последних блоков на Svelte оставалось переписать только серверный код.
Поскольку Fest на сервере существовал в production более 5 лет и, несмотря на относительно низкий опыт разработки (DX, developer experience), создавал достаточно оптимизированный код, мы немного опасались увеличения нагрузки на серверы при одномоментном переходе на новый «шаблонизатор». Поэтому изначально переделали под новое решение одну из наиболее загруженных страниц, с которой мы получаем данные. После её выкатки в production общая нагрузка на серверы снизилась на 5 %, всё шло по плану.
Заключительным шагом к получению SSR для Svelte стало переписывание серверного кода для основной страницы и включение режима SSR для Svelte-приложения. Однако при нагрузочном тестировании мы столкнулись с утечкой памяти в серверном SSR-коде. После покомпонентной отладки мы нашли причину: неправильное использование Svelte-хранилищ (были проблемы с отпиской). Вскоре в production появился SSR.
Не всегда нужно реализовывать полный SSR всего приложения. Например, нецелесообразно применять его для динамически появляющегося контента на странице, который пользователь не увидит при первой загрузке, первом хите. Также можно использовать Islands Architecture для встраивания с сервера и генерации SSR только критических блоков. Мы частично реализуем эту идею на странице.
При восстановлении SSR нашей страницы мы столкнулись с интересной особенностью, которая критически влияла на показатели CLS и которую не было заметно ни нам, ни тестировщикам: вставка новостей не выполнялась на первый хит. Возникала задержка между начальной отрисовкой всего приложения и вставкой новостей. Из-за такого поведения смещался скелетон рекламного баннера, что и вызывало снижение метрик CLS. Подобный сдвиг мог потенциально происходить и при смене таба новостей, однако при эмуляции обнаружить его ранее не получалось. И хотя SSR сам по себе не повлиял на улучшение CLS, он упростил обнаружение проблем. Решить проблему помогла переделка механизма работы с отображаемыми данными (что и вызывало задержку в отрисовке) и улучшение верстки самого компонента новостей.
Обнаружение проблемы с отрисовкой новостей при отключенном JavaScript.
Общий совет при реализации SSR: по возможности переносите всю логику отображения страницы из JavaScript в CSS для предотвращения сдвигов страницы при загрузке JavaScript-кода (негативное влияние на CLS).
Борьба с неиспользуемым кодом полифилов (внедрение code splitting)
Следующим ключевым направлением, влияющим на LCP и FID, является удаление неиспользуемого кода полифилов. Несмотря на то, что в проекте десктопной главной страницы мы очень внимательно относимся к добавлению новых полифилов (управляем ими вручную), в самом начале страницы у нас синхронно (по историческим причинам) загружается часть кросс-проектного виджета, за который также отвечает наша команда. Со временем доля полифилов (по сравнению с общим размером кода) в синхронной части виджета стала расти. Для уменьшения влияния этой части на скорость загрузки различных проектов мы внедрили в виджет разделение кода для современных и старых браузеров (code splitting).
Мы отказались от популярного паттерна module/nomodule для декларативной загрузки современного или legacy-кода (то есть определения современных браузеров), поскольку браузеры, определяемые по атрибуту
type="module"
тега script
, были для нас недостаточно новыми. То есть количество браузеров с поддержкой type="module"
велико, но не все из них в полной мере поддерживают современные браузерные API и синтаксис. Также хотелось иметь возможность в любой момент изменить версию браузера, определяемого как старый. Поэтому несмотря на простоту внедрения мы выбрали другой подход.У нас в Mail.ru есть кросс-проектный механизм определения версии браузера на сервере. С его помощью мы можем строго определять версии браузера, считающиеся современными, и в любой момент изменять параметры. Этот механизм мы и выбрали. В качестве альтернативы можем предложить пакет Browserslist Useragent, который на основе
.browserslistrc
формирует регулярное выражение,которое затем на сервере сравнивается с User agent. Оставалось подготовить два разных бандла для обеих версий виджета. Для транспиляции кода виджета мы используем Babel. Добавив в TOML-файл
.browserslistrc
modern-конфигурацию (где XX
— минимальная версия Chrome для вашего приложения, а YY
— минимальная версия считающегося современным Chrome), получили:[legacy]
chrome >= XX
...
[modern]
chrome >= YY
...
Далее необходимо было настроить сборку. Её мы сейчас выполняем с помощью бандлера Rollup. Для добавления второй версии приложения вставим проброс версии браузера в @rollup/plugin-babel:
import babel from '@rollup/plugin-babel'
import browserslist from 'browserslist'
const getConfig = isModern => {
const env = isModern ? 'modern' : 'legacy' // Должно соответствовать файлу .browserslistrc
const targets = browserslist(null, {
env,
})
...
return {
...
// babelrc: false,
presets: [
[
// Опции для пресетов @rollup/plugin-babel не берёт из babel.config.json =>
// => здесь вся конфигурация @babel/preset-env => весь ваш Babel Config (если не используете других пресетов и плагинов)
//
// Для других опций будет использоваться babel.config.json
// Чтобы конфигурация бралась только отсюда: babelrc: false
'@babel/preset-env',
{
targets,
// debug: true, — поможет узнать правильность забираемых версий из .browserslistrc
},
],
],
}
}
export default isModern => babel(getConfig(isModern))
Получили разделение кода для новых и старых браузеров. Синхронная часть кода для новых браузеров уменьшилась на 43,3 %. И это не предел, описанный подход позволяет добавить группы браузеров по степени поддержки ими современного синтаксиса. Например, C, B, A, A+, чтобы современные браузеры получали только минимум необходимых полифилов.
Кроме уменьшения размера бандла и положительного влияния на CWV разделение кода позволяет улучшить опыт разработки. После запуска новой версии виджета мы измерили долю пользователей наших продуктов со старыми браузерами: их оказалось приблизительно 3,5 %, то есть немного. Исходя из общего тренда на снижение этой доли, наша команда решила перестроить процесс реализации новых функций в виджете. Ранее при необходимости внедрения нового браузерного API мы анализировали размер соответствующих полифилов. Если размер был большой, то от использования новейшего API приходилось отказываться. А после внедрения разделения кода мы при необходимости поднимаем версию считающихся нами современных браузеров в
.browserslistrc
. Это позволяет разработчикам не отказываться от использования новейших браузерных API из-за большого веса полифилов данного API для старых браузеров.Внедрение полноценного разделения кода для разных браузеров иногда может потребоваться анализ совместно с владельцами продукта: нужно строго прописать версии браузеров, которые вы обязуетесь поддерживать и которые вам не важны. Соглашение позволит строго определить нижнюю границу для legacy-браузеров, которую следует установить в файле
.browserslistrc
. Разумно сразу же определить и периодичность такого «грумминга».Улучшение поведения загрузки ресурсов страницей
Теперь перейдем к минификации и сжатию отправляемых данных. Этот совет мы полностью выполняли и для CSS, и для JavaScript, поэтому останавливаться на нём не будем. То есть правильный ответ на вопрос «Минификация или сжатие?» будет «И минификация, и сжатие!»
Затем идёт настройка тегов для предзагрузки и атрибутов для асинхронной загрузки ресурсов. Мы уже упоминали, что некритичные для начальной отрисовки страницы виджеты на главной странице у нас загружаются асинхронно. Также мы немного поработали над оптимизацией тегов
preload
, prefetch
, preconnect
, dns-prefetch
.Кроме предзагрузки ресурсов требуется и настройка кеширования. Это делается с помощью настройки HTTP-заголовков ответа серверов. На главной странице проблем с этим не было.
Результаты
После всех описанных выше действий мы получили следующие результаты (доля пользователей в соответствии со значением метрик: good — needs-improvement — poor, средние показания за неделю 24-30 мая 2021 года):
- CWV:
- LCP: 58 (+6) — 18 — 26
- FID: 93 (+1) — 4 — 3
- CLS: 93 (+60) — 3 — 4
- Остальные Web Vitals:
- FCP: 43 (+8) — 34 — 23
- TBT: 49 (+7) — 17 — 34
- TTI: 51 (+8) — 24 — 25
Значения Web Vitals после внесения улучшений.
Сравнение значений метрик Web Vitals (в скобках указано изменение группы good).
Ниже представлены графики изменения значений метрик производительности страницы согласно «Платформе». Отметим две важные даты на графиках:
- 23 марта 2021 года — релиз итерации с переносом последних блоков страницы на Svelte;
- 19 апреля 2021 года — релиз итерации с возвращением SSR и изменением вёрстки для исправления CLS CWV.
Снижение значений с 1 по 10 мая вызвано объективными причинами — майскими праздниками в России.
График метрики LCP CWV в «Платформе» c 16 марта по 1 июня 2021 года.
График метрики FID CWV в «Платформе» c 16 марта по 1 июня 2021 года.
График метрики CLS CWV в «Платформе» c 16 марта по 1 июня 2021 года.
График метрики FCP в «Платформе» c 16 марта по 1 июня 2021 года.
График метрики TBT в «Платформе» c 16 марта по 1 июня 2021 года.
График метрики TTI в «Платформе» c 16 марта по 1 июня 2021 года.
Полученные с помощью «Платформы» результаты по CWV соответствуют росту метрик в Chrome UX Report (CrUX) — это еще один инструмент для отслеживания изменений CWV, не требующий от разработчиков внедрения какого-либо дополнительного кода на страницу. В CrUX данные по CLS CWV даже выше по сравнению со значениями из «Платформы».
Изменение метрики LCP в CrUX в 2021 году.
Изменение метрики FID в CrUX в 2021 году.
Изменение метрики CLS в CrUX в 2021 году.
И хотя мы не проводили полноценного A/B-тестирования, чтобы оценить влияние улучшения метрик CWV на поведение пользователей, однако сравнение средней длительности сессии пользователя на странице за неделю до выкатки первых улучшений и за неделю после выкатки улучшений показывает рост метрики на 2,7 %.
Выводы и планы
В статье мы кратко описали метрики, перечислили рекомендации Google и сформировали краткий список требуемых изменений для главной страницы Mail.ru. Для получения значения CWV внедрили frontend «Платформу» для сбора метрик у реальных пользователей и предложили разработчикам альтернативные инструменты. Затем описали опыт внедрения трех рекомендаций Google:
- Использование скелетонов для избавления от сдвигов интерфейса при загрузке рекламных баннеров.
- Внедрение серверного рендеринга (SSR).
- Применение разделения кода (code splitting).
Полученные результаты показывают значительный рост метрики CLS CWV — более чем на 50 %. Однако несмотря на рост LCP CWV на 6 % после внедрения SSR теперь ее значения являются наименьшими среди CWV, поэтому мы уже составили план действий для повышения пользовательского опыта и значений метрики LCP CWV.
Основной вывод из нашей работы — улучшение значений метрик CWV хоть и кажется сложной и нетривиальной задачей, но является выполнимой. Главная проблема состоит в другом: нужно быть готовым, что процесс улучшения производительности будет растянут по времени. За изменениями метрик необходимо следить постоянно, никакая новая продуктовая задача не должна снижать показатели CWV. Для этого каждый участник команды должен понимать важность поддержания высоких метрик производительности, а также необходимо интегрировать задачи по улучшению CWV в бизнес-процессы компании.
Все участники продуктовых команд, начиная с менеджеров и дизайнеров и заканчивая тестировщиками и QA, должны следить за влиянием новых продуктовых задач на метрики CWV на всех этапах: при появлении идеи и её проработке, при реализации и тестировании. Лишь совместная работа всех участников команды способна привести к успеху — к созданию высокого пользовательского опыта и получению положительных отзывов от клиентов!