Использование ленивых загружаемых компонентов может привести к двойственности CLS и медленным соединениям
6 апреля 2022 г.Когда вы оптимизируете свое веб-приложение, ваша цель — сделать его более удобным для пользователя; обычно это означает «быстрее» за счет передачи и анализа меньшего количества данных. Но будьте осторожны: одно и то же веб-приложение может вызвать кумулятивное смещение макета (CLS) на более медленных соединениях, но работать без CLS на более быстрых соединениях.
Если вы хотите напомнить о Core Web Vitals, я объяснил их с помощью GIF-файлов в [этом посте] (https://wicki.io/posts/2021-07-core-web-vitals/).
==TL;DR:== ==более медленные соединения могут привести к CLS при ленивой загрузке компонентов, которые вы не увидите при подключении к Wi-Fi.==
== Либо вообще не ленитесь загружать компонент, либо дождитесь загрузки и монтирования js-файла. ==
Двойственность
Мы предполагаем, что веб-приложение загружает то же самое при более медленных соединениях, просто медленнее. К сожалению, это не всегда так с ленивыми загружаемыми компонентами.
С ленивыми загружаемыми компонентами мы имеем дело с двумя асинхронностями:
- ответы асинхронного API (JSON)
- Компоненты асинхронной ленивой загрузки (JS)
Что, если ответы API (1) быстрее, чем динамически загружаемый JS (2)? Что, если вы лениво загрузите компонент, который находится в середине вашего веб-контента? Ответ на эти вопросы вы видите на снимке экрана выше: Google накажет вас CLS.
Измерение CLS
Я видел много путаницы в отношении Core Web Vitals, особенно CLS.
В отличие от других Core Web Vitals, CLS постоянно измеряется и кумулятивно добавляется к баллу. Для классического веб-приложения SPA это означает, что Google будет сохранять оценку CLS для каждого маршрута.
CLS имеет следующие характеристики:
- После каждого изменения маршрута CLS сбрасывается на 0
- После любого взаимодействия с пользователем вы получаете льготный период в 500 мс, когда CLS не принимается во внимание.
Измерения реальных пользователей: пользователи Chrome отправляют показатели Core Web Vitals напрямую в Google. Это не робот Googlebot, который фиксирует эти показатели при сканировании сайта.
Эти реальные пользовательские измерения собираются как [данные поля] (https://web.dev/lab-and-field-data-differences/#field-data) и передаются в [отчет CrUX] Google (https://developers. google.com/web/tools/chrome-user-experience-report).
Это означает, что вам нужно учитывать реальный мир:
- Если у вас много трафика из Индии, но ваши серверы находятся на другом конце света, вероятно, пострадает ваш LCP (Largest Contentful Paint).
- Если у вас много трафика из Китая, вполне вероятно, что некоторые сервисы заблокированы китайскими провайдерами и не загружаются. Это может привести к появлению нежелательных CLS в вашем контенте.
Решения
Нам нужно иметь полный контроль над тем, что отображать пользователю и в какое время. Имея в виду двойственность, нам нужно знать следующее:
- Запросы API все еще загружаются?
- асинхронные компоненты все еще загружаются?
Скелетный загрузчик — это идеальный способ дождаться готовности как API-запросов, так и асинхронных компонентов.
Решение №1: вообще не откладывайте загрузку компонентов
Самым быстрым и наименее подверженным ошибкам решением будет передача компонентов с отложенной загрузкой. В большинстве случаев сэкономленные килобайты за счет отложенной загрузки не оправдывают CLS, который она может вызвать. Если ваш бюджет позволяет, используйте это решение.
Предположим, у нас есть веб-приложение Vue с 10% зарегистрированных пользователей.
```машинопись
функция рендеринга () {
// не всем пользователям требуется скачивать и отображать HugeComponent
если (вошел в систему) {
вернуть <ОгромныйКомпонент/>;
Без разделения кода мы отправили бы JS <HugeComponent>
90% пользователей, которым он не нужен. Это может повлиять на LCP и FID.
При разделении кода мы упаковываем JS-код <HugeComponent>
в фрагмент Additional-comps.js и отправляем его по сети только тогда, когда это необходимо.
```машинопись
// без разделения кода
импортировать HugeComponent из '@/components/HugeComponent';
// с разделением кода
const HugeComponent = () => (ожидание импорта(
/ webpackChunkName: "дополнительные-компы" /
'@/компоненты/HugeComponent')
).По умолчанию;
Есть два критерия, которые помогут вам решить, следует ли лениво загружать компонент или нет:
- размер
<HugeComponent>
- как часто
<HugeComponent>
будет отображаться для пользователей
Если вы пришли к выводу, что ваш бюджет на производительность ограничен и вам нужно лениво загружать компонент, см. решение № 2.
Решение №2: Дождитесь загрузки и монтирования компонента
Если ваш компонент не используется для большинства пользователей и это значительно увеличило бы пакет, взгляните на это решение.
Подождать, пока асинхронные компоненты будут лениво загружены и смонтированы, может быть сложно. Вам нужно визуализировать компонент, но монтирование происходит позже. Вот суть того, как это можно сделать.
```машинопись
функция Родитель({ isLoggedIn }) {
const [isLoading, setLoading] = useState (false);
// важно: скрыть дочерние элементы только с display: none.
// если бы мы использовали if-else, мы бы никогда не загрузили ленивый загружаемый компонент;
// и тогда мы бы никогда не изменили isLoading с его обратным вызовом.
const styles = { display: isLoading? 'нет' : 'заблокировать' };
вернуть (
{/ HugeComponent загружается лениво, потому что не всем пользователям он нужен /}
(isLoggedIn && <HugeComponent
стиль = { стили }
Mounted={() => setLoading(true)}
{/ отображать скелетный элемент во время загрузки /}
(isLoading &&
)function HugeComponent (реквизит: { смонтирован: () => void}) {
const [dataA, setData] = useState (null);
useEffect (асинхронный () => {
константный результат = ожидание lib.request();
установить данные (результат);
// сообщаем родительскому компоненту, что все готово для полного рендеринга
реквизит.mounted();
вернуть (/ ... /);
Если бы мы не использовали display: hidden
для состояния загрузки в <HugeComponent>
, мы бы никогда не инициировали загрузку асинхронного компонента. Таким образом, строка 28 никогда не будет достигнута, а состояние «isLoading» навсегда останется «ложным».
Заключение
Если вы потеряли зеленые URL-адреса в Google Search Console из-за CLS и не можете воспроизвести их самостоятельно, попробуйте отладить свое веб-приложение с более медленным соединением.
Поэтому, если вы используете ленивые загружаемые компоненты, высока вероятность, что вы можете стать жертвой двойственности CLS.
Если вы нашли этот пост интересным, оставьте ❤️ в [этом твите] (https://twitter.com/zwacky/status/1508354371205185537) и рассмотрите возможность подписаться на мое 🎢 путешествие о #webperf, #документальных книгах, #buildinpublic и #frontend имеет значение в Твиттере.
Оригинал