Список рекомендаций по Core Web Vitals (Part 1)
После долгих поисков интересной, а главное, доступной для понимания информации по оптимизации веб-приложения наткнулся на одну статью, написанную разработчиком из Google. Она почти целиком и полностью посвящена наиболее эффективным способам оптимизации показателей Core Web Vitals.
На протяжении многих лет ребята из Google давали веб-разработчикам множество рекомендаций по повышению производительности.
Хотя каждая из этих рекомендаций по отдельности может улучшить производительность. Для многих сайтов полный набор рекомендаций, по общему признанию, слишком велик. И ни один человек или сайт не может следовать им всем.
Если веб-производительность не является вашей повседневной работой, вероятно, не очевидно, какие рекомендации окажут наибольшее положительное влияние на ваш сайт. Например, вы, возможно, читали, что внедрение критически важного CSS может повысить производительность загрузки, и, возможно, вы также слышали, что важно оптимизировать ваши изображения. Но если у вас нет времени работать над обеими вещами, как бы вы решили, какую из них выбрать?
В команде Chrome последний год провели, пытаясь ответить на вопрос: какие самые важные рекомендации можно дать разработчикам, чтобы помочь им повысить производительность для своих пользователей?
Чтобы адекватно ответить на этот вопрос, нужно учитывать не только технические достоинства данной рекомендации, но также человеческие и организационные моменты, влияющие на вероятность того, что разработчики действительно смогут принять эти рекомендации. Другими словами, теоретически некоторые рекомендации могут быть очень эффективными, но очень немногие сайты будут иметь время или ресурсы для их реализации. Точно так же некоторые рекомендации имеют решающее значение, но большинство веб-сайтов уже следуют этим практикам.
Короче говоря, необходимо, чтобы список лучших рекомендаций по веб-производительности был сосредоточен на:
рекомендациях, которые окажут наибольшее влияние на реальный мир;
рекомендациях, наиболее актуальных и применимых к большинству сайтов;
рекомендациях, которые реалистичны для большинства разработчиков.
За последний год было потрачено много времени на проверку всего набора рекомендаций по эффективности и оценку каждой из них (как качественно, так и количественно) по трем вышеуказанным критериям.
В этом посте изложены основные рекомендации по повышению производительности для каждой из метрик Core Web Vitals. Если вы новичок в веб-производительности или пытаетесь решить, что даст вам наибольшую отдачу от затраченных средств, то эти рекомендации — лучшее место для знакомства.
Largest Contentful Paint (LCP)
Первый набор рекомендаций относится к Largest Contentful Paint (Загрузка основного контента) (LCP), которая является показателем производительности загрузки. Из трех показателей Core Web Vitals LCP — это тот, с которым борется наибольшее количество сайтов — только около половины всех сайтов в Интернете сегодня соответствуют рекомендуемому порогу — поэтому давайте начнем с него.
Убедитесь, что элемент LCP можно обнаружить из источника HTML.
Согласно веб-альманаху 2022 года, подготовленному HTTP Archive, 72% мобильных страниц имеют изображение в качестве элемента LCP, а это означает, что для оптимизации LCP большинству сайтов необходимо обеспечить быструю загрузку этих изображений.
Что может быть неочевидным для многих разработчиков, так это то, что время, необходимое для загрузки изображения, является лишь частью проблемы. Другой важной частью является время до начала загрузки изображения, и данные HTTP-архива показывают, что на самом деле многие сайты не соответствуют нормам.
Фактически, из страниц, где элементом LCP было изображение, 39% этих изображений имели исходные URL-адреса, которые нельзя было обнаружить из источника HTML-документа. Другими словами, эти URL-адреса не были найдены в стандартных атрибутах HTML (таких как <img src="..."> или <link rel="preload" href="...">), что позволило бы браузеру быстро обнаружить их и сразу же начать загружать.
Как правило, если ваш элемент LCP является изображением, то URL-адрес всегда должен быть доступен для обнаружения из источника HTML. Вот несколько советов, как сделать это возможным:
Загрузите изображение с помощью элемента <img> с атрибутом src или srcset. Не используйте нестандартные атрибуты, такие как data-src, которые требуют JavaScript для рендеринга, так как это всегда будет медленнее. 9% страниц скрывают свое изображение LCP за data-src.
Попробуйте использовать обработку на стороне сервера (SSR), а не обработку на стороне клиента (CSR), поскольку SSR подразумевает, что в исходном HTML-коде присутствует полная разметка страницы (включая изображение).
Если на ваше изображение нужно ссылаться из внешнего файла CSS или JS, вы все равно можете включить его в исходный код HTML с помощью тега <link rel="preload">. Обратите внимание, что изображения, на которые ссылаются встроенные стили, не могут быть обнаружены сканером предварительной загрузки браузера, поэтому даже если они найдены в исходном коде HTML, их обнаружение может быть заблокировано при загрузке других элементов, поэтому предварительная загрузка может помочь в этих случаях.
Чтобы помочь вам понять, есть ли проблемы с обнаружением вашего элемента LCP, Lighthouse выпустит обновленную версию 10.0 (ожидается в январе 2023 г.).
Обнаружение элемента LCP из источника HTML может привести к измеримым улучшениям, а также открывает дополнительные возможности для определения приоритета элемента, что является следующей рекомендацией.
Приоритетность LCP
Убедитесь, что элемент LCP может быть обнаружен из исходного HTML-кода — это первый важный шаг в обеспечении того, чтобы элемент LCP мог начать загружаться раньше, но еще один, не менее важный шаг — убедиться, что загрузка этого элемента имеет приоритет и не ставится в очередь за кучей других, менее важных элементов.
Например, даже если ваше изображение присутствует в исходном коде HTML с использованием стандартного тега <img>, если ваша страница включает множество тегов <script> в <head> вашего документа перед этим тегом <img>, то может пройти много времени до начала изображения.
Самый простой способ решить эту проблему — предоставить браузеру подсказку о том, какие элементы имеют наивысший приоритет, установив новый атрибут fetchpriority="high" в теге <img> или <link>, который загружает ваше изображение LCP. Это указывает браузеру загружать его раньше, а не ждать завершения этих сценариев.
Согласно веб-альманаху только 0,03% сайтов используют этот новый API. Это означает, что у большинства сайтов в Интернете есть много возможностей улучшить LCP с минимальными усилиями. Хотя атрибут fetchpriority в настоящее время поддерживается только в браузерах на основе Chromium, этот API представляет собой прогрессивное усовершенствование, которое другие браузеры просто игнорируют, поэтому мы настоятельно рекомендуем разработчикам использовать его сейчас.
Для браузеров, отличных от Chromium, единственный способ обеспечить приоритет элемента LCP над другими элементами — указать его ранее в документе. Снова используя пример сайта с большим количеством тегов <script> в <head> документа. Если вы хотите, чтобы ваш элемент LCP имел приоритет, то вы можете добавить <link rel="preload" > перед любым из этих сценариев, или переместить эти сценарии ниже <img>, позже в <body>. Хотя это работает, это менее удобно, чем использование fetchpriority, поэтому мы надеемся, что другие браузеры скоро добавят поддержку.
Другим важным аспектом приоритизации элемента LCP является отсутствие каких-либо действий, которые могут привести к снижению его приоритета, например, добавление атрибута loading="lazy". Сегодня 10% страниц фактически устанавливают loading="lazy" на своем изображении. Остерегайтесь решений для оптимизации изображений, которые без разбора применяют поведение отложенной загрузки ко всем изображениям. Если они предоставляют способ переопределить это поведение, обязательно используйте его для элемента LCP.
Задержка некритических элементов — еще один способ повысить относительный приоритет элемента LCP. Например, скрипты, которые не управляют пользовательским интерфейсом, такие как скрипты аналитики или виджеты социальных сетей, можно отложить до тех пор, пока не сработает событие ‘load’. Это гарантирует, что они не будут конкурировать с другими критически важными элементами (такими как изображения LCP).
Подводя итог, вы должны следовать этим рекомендациям, чтобы обеспечить наиболее раннюю загрузку элемента LCP и его высокий приоритет:
Добавьте fetchpriority="high" в тег <img>, который является элементом LCP. Если элемент LCP загружается через тег <link rel="preload"> не переживайте, ведь вы также можете установить для него fetchpriority="high"!
Никогда не устанавливайте loading="lazy" в теге <img> вашего элемента LCP. Это приведет к снижению приоритета изображения и задержке начала его загрузки.
По возможности откладывайте некритические элементы. Это делается посредством перемещения их в конец документа (используя встроенную ленивую загрузку изображений или фреймов) либо загрузив их асинхронно через JavaScript.
Используйте CDN для оптимизации документов и элементов TTFB
Предыдущие две рекомендации были сосредоточены на том, чтобы обеспечить раннее обнаружение вашего элемента LCP и его приоритетность, чтобы он мог сразу начать загрузку. Последняя часть этой головоломки — обеспечить максимально быстрое получение первоначального ответа на документ.
Браузер не может начать загрузку каких-либо элементов, пока не получит первый байт начального ответа HTML-документа, и чем раньше это произойдет, тем раньше начнет происходить все остальное.
Это время известно как Time to First Byte (TTFB), и лучший способ уменьшить TTFB — это:
Передавайте контент как можно (географически) ближе к своим пользователям;
Кэшируйте этот контент, чтобы недавно запрошенный контент можно было снова быстро загрузить.
Лучший способ сделать обе эти вещи — использовать CDN. CDN распределяют ваши ресурсы на пограничные серверы, разбросанные по всему миру, тем самым ограничивая расстояние, которое эти ресурсы должны пройти по сети к вашим пользователям. CDN также зачастую имеют детализированные элементы управления кэшированием, которые можно настроить и оптимизировать для нужд вашего сайта.
Многие разработчики знакомы с использованием CDN для размещения статических ресурсов, но CDN также могут обслуживать и кэшировать HTML-документы даже те, которые создаются динамически.
Согласно веб-альманаху только 29% запросов HTML-документов обслуживались через CDN, а это означает, что у сайтов есть значительные возможности для дополнительной экономии.
Вот несколько советов по настройке CDN:
Рассмотрите возможность увеличения времени кэширования контента (например, действительно ли важно, чтобы контент всегда был свежим?).
Рассмотрите также кеширование контента на неопределенный срок, а затем очистку кеша, если/когда вы делаете обновление.
Узнайте, можете ли вы переместить динамическую логику, работающую в настоящее время на исходном сервере, на периферию (функция большинства современных CDN).
В общем, каждый раз, когда вы можете обслуживать контент непосредственно с периферии (избегая перехода на исходный сервер), это выигрывает в производительности. И даже в тех случаях, когда вам нужно пройти весь путь до исходного сервера, CDN, как правило, оптимизированы для того, чтобы сделать это намного быстрее, так что это плюс в любом случае.
Это была первая часть нашего погружения в вопрос оптимизации веб-приложения. В следующей части мы поговорим о Cumulative Layout Shift (CLS), back/forward cache, animations/transitions в CSS, First Input Delay (FID), рефакторинге неиспользуемого JavaScript.