Skip to content

Добавляет статью о Core Web Vitals - #6101

Open
shmakovdima wants to merge 17 commits into
doka-guide:mainfrom
shmakovdima:add-web-vitals-article
Open

Добавляет статью о Core Web Vitals#6101
shmakovdima wants to merge 17 commits into
doka-guide:mainfrom
shmakovdima:add-web-vitals-article

Conversation

@shmakovdima

@shmakovdima shmakovdima commented Jul 25, 2026

Copy link
Copy Markdown

Описание

Добавляю статью о web-vitals
Closes #5498

не совсем понятно, куда добавлять в навигации, временно добавил в Веб-платформа->Как устроен веб

Превью: https://content-6101.dev.doka.guide/tools/web-vitals/

Чек-лист

  • Текст оформлен согласно руководству по стилю
  • Ссылки на внутренние материалы начинаются со слеша и заканчиваются слэшем либо якорем на заголовок (/css/color/, /tools/json/, /tools/gulp/#kak-ponyat)
  • Ссылки на картинки, видео и демки относительные (images/example.png, demos/example/, ../demos/example/)

@shmakovdima shmakovdima changed the title Add web vitals article Добавляю статью о Core Web Vitals Jul 25, 2026
@shmakovdima

shmakovdima commented Jul 25, 2026

Copy link
Copy Markdown
Author

Проконсультироваля с @furtivite - переношу в секцию "Инструменты" в "Веб-платформа"

@shmakovdima
shmakovdima marked this pull request as ready for review July 25, 2026 16:37
@shmakovdima shmakovdima changed the title Добавляю статью о Core Web Vitals Добавляет статью о Core Web Vitals Jul 25, 2026
@vitya-ne vitya-ne added the веб-платформа Контент по Веб-платформе label Jul 25, 2026
@github-actions github-actions Bot added the статья Расширенный материал label Jul 30, 2026
@github-actions

Copy link
Copy Markdown
Превью контента из ad92927 опубликовано.

@vitya-ne vitya-ne left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Привет, спасибо за такую подробную статью!
Добавил несколько коментов. Пока лучше не исправляй - я просмотрел около четверти (Ооочень большой пиар).
Когда закончу, напишу.

@@ -0,0 +1,4 @@
{

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Этот файл добавлять не нужно, он создаётся автоматически.

Comment thread tools/web-vitals/index.md
- article
---

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Все это производительность и очень долгое время не существовало..

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

Comment thread tools/web-vitals/index.md

## Зачем Google ввёл эти метрики

У производительности сайтов существуют две стороны, и обе важны бизнесу:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

и обе важны бизнесу:

Может стоит два следующих абзаца сделать элементами ненумерованного списка ?

Comment thread tools/web-vitals/index.md

**Пользовательский опыт.** Медленный и нестабильный сайт заставляет людей уходить, не дойдя до просмотра, заявки или заказа. Core Web Vitals выражают в понятных показателях три главных раздражителя: долгую загрузку, медленную реакцию на действия и прыжки элементов.

**SEO.** Google встроил Core Web Vitals в сигнал ранжирования Page Experience. При этом Google оценивает метрики не по лабораторным тестам, а по данным реальных пользователей Chrome из отчёта [CrUX (Chrome User Experience Report)](https://cruxvis.withgoogle.com). То есть поисковик смотрит, как ведёт себя сайт на реальных устройствах пользователей.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Мысль ясна, но она немного пугает. "Смотрит" всё-таки браузер, а не поисковик, да ?

Может стоит поменять на:

"То есть поисковик анализирует, как ведёт себя сайт на реальных устройствах пользователей."

Comment thread tools/web-vitals/index.md

**SEO.** Google встроил Core Web Vitals в сигнал ранжирования Page Experience. При этом Google оценивает метрики не по лабораторным тестам, а по данным реальных пользователей Chrome из отчёта [CrUX (Chrome User Experience Report)](https://cruxvis.withgoogle.com). То есть поисковик смотрит, как ведёт себя сайт на реальных устройствах пользователей.

И сразу нужно запомнить главное: **все Core Web Vitals считаются по 75-му перцентилю**. Метрика считается хорошей только в том случае, если установленному порогу соответствуют не менее 75 % посещений. То есть фокусироваться на быстром сегменте аудитории и не обращать внимания на пользователей с медленными устройствами или со слабым интернетом не получится - Google смотрит именно на «хвост» распределения отдельно для мобильных устройств и десктопных компьютеров

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
И сразу нужно запомнить главное: **все Core Web Vitals считаются по 75-му перцентилю**. Метрика считается хорошей только в том случае, если установленному порогу соответствуют не менее 75 % посещений. То есть фокусироваться на быстром сегменте аудитории и не обращать внимания на пользователей с медленными устройствами или со слабым интернетом не получится - Google смотрит именно на «хвост» распределения отдельно для мобильных устройств и десктопных компьютеров
И сразу нужно запомнить главное: **все Core Web Vitals считаются по 75-му перцентилю**. Метрика считается хорошей только в том случае, если установленному порогу соответствуют не менее 75 % посещений. То есть фокусироваться на быстром сегменте аудитории и не обращать внимания на пользователей с медленными устройствами или со слабым интернетом не получится - Google смотрит именно на «хвост» распределения отдельно для мобильных устройств и десктопных компьютеров.

Метрика считается хорошей только в том случае

Может "значение метрики"?

Comment thread tools/web-vitals/index.md

И сразу нужно запомнить главное: **все Core Web Vitals считаются по 75-му перцентилю**. Метрика считается хорошей только в том случае, если установленному порогу соответствуют не менее 75 % посещений. То есть фокусироваться на быстром сегменте аудитории и не обращать внимания на пользователей с медленными устройствами или со слабым интернетом не получится - Google смотрит именно на «хвост» распределения отдельно для мобильных устройств и десктопных компьютеров

**Как понять 75-й перцентиль.** Представим 100 посещений сайта и расположим результаты по скорости - от лучших к худшим. Значение на 75-й позиции и будет 75-м перцентилем. Иными словами, установленному порогу должны соответствовать не менее 75 % посещений. Поэтому нельзя ориентироваться только на людей с быстрыми устройствами и стабильным интернетом: Google учитывает и менее удачный пользовательский опыт.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Как понять 75-й перцентиль. Представим 100 посещений сайта...

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

Comment thread tools/web-vitals/index.md

Если коротко, три основные метрики отвечают на три простых вопроса:

- **LCP** (Largest Contentful Paint) - «когда я наконец увидел то, ради чего пришёл в полном составе?»

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

когда я наконец увидел то, ради чего пришёл в полном составе?»

Это игра слов? Не понятно к какой части предложения относится "полный состав". "Я" мог придти не в полном составе ?

Comment thread tools/web-vitals/index.md

На практике этот этап редко оказывается узким местом: у большинства сайтов основную часть LCP съедают TTFB и задержки, а не сама загрузка файла. Прежде чем оптимизировать именно длительность загрузки, проверьте по полевым данным (CrUX, `web-vitals`), действительно ли это ваше слабое место.

**Задержка отрисовки**, чтобы скачанное сразу показалось:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Сбивает.
чтобы "скачанное сразу показалось" - не должно быть задержки.

@vitya-ne vitya-ne left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shmakovdima
Добавил ещё несколько коментов и закончил первый раунд ревью.

После прочтения возникло несколько мыслей (делюсь как читатель):

  • некоторые подробности можно спрятать в <details>/<summary>;
  • возможно, статью можно разбить на несколько (Как измерять и улучшать Core Web Vitals отдельно);
  • материала так много, что очень непросто прочитать за один раз.

Comment thread tools/web-vitals/index.md

#### Углублённая оптимизация

**Мгновенные переходы между страницами.** Если сайт в основном многостраничный, посмотрите на **Speculation Rules API** - он умеет предзагружать или полностью предрендерить вероятную следующую страницу (например, по наведению на ссылку или по данным аналитики о частых переходах). При переходе она открывается практически мгновенно: LCP такой навигации получается близким к нулю, как при восстановлении из bfcache.</

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Speculation Rules API пока не реализован в Firefox и Safari. Возможно стоит предупредить читателя.

Comment thread tools/web-vitals/index.md

#### Остальные приёмы

- **[Дебаунсите](/js/debounce) частые события** (`input`, `resize`, `scroll`) - не запускайте тяжёлую логику при каждом событии. Особенно актуально для автокомплита: без дебаунса каждое нажатие клавиши создаёт отдельный обработчик, и они конкурируют за главный поток. Для событий, которые нужно ограничить по частоте, а не отложить до паузы (скролл, resize), больше подходит [троттлинг](/js/throttle);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- **[Дебаунсите](/js/debounce) частые события** (`input`, `resize`, `scroll`) - не запускайте тяжёлую логику при каждом событии. Особенно актуально для автокомплита: без дебаунса каждое нажатие клавиши создаёт отдельный обработчик, и они конкурируют за главный поток. Для событий, которые нужно ограничить по частоте, а не отложить до паузы (скролл, resize), больше подходит [троттлинг](/js/throttle);
- Применяйте **[дебаунсинг](/js/debounce)** к частым событиям (`input`, `resize`, `scroll`) - не запускайте тяжёлую логику при каждом событии. Особенно актуально для автокомплита: без дебаунса каждое нажатие клавиши создаёт отдельный обработчик, и они конкурируют за главный поток. Для событий, которые нужно ограничить по частоте, а не отложить до паузы (скролл, resize), больше подходит [троттлинг](/js/throttle);

Comment thread tools/web-vitals/index.md
#### Остальные приёмы

- **[Дебаунсите](/js/debounce) частые события** (`input`, `resize`, `scroll`) - не запускайте тяжёлую логику при каждом событии. Особенно актуально для автокомплита: без дебаунса каждое нажатие клавиши создаёт отдельный обработчик, и они конкурируют за главный поток. Для событий, которые нужно ограничить по частоте, а не отложить до паузы (скролл, resize), больше подходит [троттлинг](/js/throttle);
- **Отменяйте устаревшие запросы через [`AbortController`](/js/abort-controller).** Если пользователь быстро печатает в поиске, каждый символ может улетать отдельным [`fetch`](/js/fetch). Отменяйте предыдущий запрос перед отправкой нового - иначе главный поток обрабатывает колбэки ответов, которые уже никому не нужны:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

каждый символ может улетать отдельным fetch

По-моему, слишком образно - fetch() ведь не самолёт.
Я бы предложил:

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

Comment thread tools/web-vitals/index.md
Comment on lines +262 to +270
let controller;
input.addEventListener("input", async (e) => {
controller?.abort();
controller = new AbortController();
const res = await fetch(`/search?q=${e.target.value}`, {
signal: controller.signal,
});
// ...
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не уверен, что это хорошая идея (даже для демонстрации) - выполнять запрос на любое изменение значения без проверки на пустую строку, и трима.

Comment thread tools/web-vitals/index.md
- **Осторожнее с таймерами.** [`setInterval`](/js/setinterval) мешает интерактивности сильнее, чем разовый [`setTimeout`](/js/settimeout), потому что колбэк срабатывает снова и снова независимо от того, успел ли отработать предыдущий. Проверяйте, не работает ли где-то забытый `setInterval` (частый источник - счётчики, поллинг, автосохранение), и переносите тяжёлую работу из таймеров в Web Worker;
- **Анимируйте через [CSS](/css/animation), а не `requestAnimationFrame`** там, где это возможно - браузер сможет прогнать анимацию в композиторе, не трогая главный поток. Если JS-анимация всё же нужна, следите, чтобы она не стала non-composited (не анимируйте `width`/`top`/[`box-shadow`](/css/box-shadow), смотрите приёмы для CLS ниже);
- **Не рендерите большие куски HTML на клиенте через `innerHTML` или аналоги.** В отличие от HTML, который браузер стримит с сервера, у клиентской вставки нет автоматической нарезки на части - вся разметка обрабатывается одной длинной задачей и блокирует кадр. Плюс ресурсы (картинки, скрипты) внутри такой разметки не увидит preload-сканер, это бьёт уже по LCP. Максимизируйте серверный рендеринг (SSR/RSC) и держите то, что всё же дорисовывается на клиенте, компактным;
- **Грузите меньше JavaScript.** Основные способы собраны ниже, в разделе «[Снижайте размер бандла](#снижайте-размер-бандла)»;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тут я оставлю отметку для редактора, чтобы не забыть про якорные ссылки (возможно потребуется что-то поменять)

Comment thread tools/web-vitals/index.md

- **Уменьшайте DOM** и применяйте **`content-visibility: auto`**, чтобы браузер не рендерил то, что вне экрана. Lighthouse считает DOM «раздутым» уже от **800 узлов** и предупреждает жёстко после **1400**: чем больше узлов и глубже вложенность, тем дороже каждый пересчёт стилей и layout. Помогают фрагменты вместо оберток (`<>...</>` в React), плоская вёрстка без лишних `div > div > div` и отложенная отрисовка скрытых секций (табы, аккордеоны) до реального обращения к ним.

`content-visibility: auto` пропускает layout, style и paint для того, что вне экрана, и включает их обратно, как только элемент подъезжает к вьюпорту - на длинной странице (лента, документация с якорями) это заметно ускоряет рендер (в примере Google - с 232 до 30 мс). Обязательно задавайте **`contain-intrinsic-size`**, иначе браузер уменьшит высоту ещё не отрисованного блока до нуля и вы получите те же скачки скролла, которых хотели избежать:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Может стоит завернуть описание content-visibility: auto и content-visibility: hidden в <details> / <summary> ?

Comment thread tools/web-vitals/index.md
#### Если вы используете [React](/tools/react-and-alternatives)

- Используйте конкурентные возможности - **`useTransition`/`useDeferredValue`**, чтобы пометить тяжёлые обновления как несрочные и не блокировать отклик. Конкурентный рендер сам уступает главный поток примерно **каждые 5 мс**, так что срочные взаимодействия (ввод, клики) не ждут медленного рендера;
- В SSR-приложениях **дробите гидратацию через `<Suspense>`**: чем гранулярнее границы, тем меньше компонентов React гидратирует синхронно за раз - главный поток блокируется короче. А **серверные компоненты вообще не гидратируются** - для них шаг гидратации пропускается, и это лучшее, что можно сделать для INP в React;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- В SSR-приложениях **дробите гидратацию через `<Suspense>`**: чем гранулярнее границы, тем меньше компонентов React гидратирует синхронно за раз - главный поток блокируется короче. А **серверные компоненты вообще не гидратируются** - для них шаг гидратации пропускается, и это лучшее, что можно сделать для INP в React;
- В SSR-приложениях **дробите гидратацию через `<Suspense>`**: чем гранулярнее границы, тем меньше компонентов React гидратирует синхронно за раз - главный поток блокируется на меньшее время. А **серверные компоненты вообще не гидратируются** - для них шаг гидратации пропускается, и это лучшее, что можно сделать для INP в React;

Comment thread tools/web-vitals/index.md

Способы, по сложности усилий:

- **Сначала измерьте.** Не оптимизируйте вслепую - посмотрите, из чего бандл состоит. `webpack-bundle-analyzer` или `@next/bundle-analyzer` рисуют интерактивную карту, где сразу видно самые большие пакеты (если не уверены, чем вообще [сборщики](/tools/bundlers) отличаются друг от друга и зачем нужны, вроде [Webpack](/tools/webpack) или [Rollup](/tools/rollup) - начните оттуда). Дальше всё просто: измерить → найти самое тяжёлое → заменить или разбить → сжать → поставить бюджет;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

если не уверены, чем вообще сборщики отличаются друг от друга и зачем нужны, вроде Webpack или Rollup - начните оттуда

Перечитал несколько раз, но не понял. Предлагаю упростить.

@shmakovdima

Copy link
Copy Markdown
Author

@vitya-ne может тогда разбить на каждый из параметров?

@vitya-ne

vitya-ne commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

@vitya-ne может тогда разбить на каждый из параметров?

Каждая метрика в отдельной статье ? Как по-мне, да, было бы проще читать.

@shmakovdima

Copy link
Copy Markdown
Author

@vitya-ne как лучше организовать - отдельный раздел в веб-платформе или оставить все в "Как устроен веб"?

@vitya-ne

vitya-ne commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

как лучше организовать - отдельный раздел в веб-платформе или оставить все в "Как устроен веб"?

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

веб-платформа Контент по Веб-платформе статья Расширенный материал

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Core Web Vitals (CLS, INP и LCP)

3 participants