TL;DR: Когда мы занимаемся оптимизацией производительности, для чего мы оптимизируем? Вам нужно понимать основные вещи для оптимизации производительности? Как много вам нужно знать? Какова базовая архитектура браузера? В чем суть браузерного рендеринга? Какие аспекты оказывают наибольшее влияние на пользовательский опыт? Существуют ли какие-то общие стандарты или эталоны в отрасли? Прошло 1202 года, военный устав Yahoo все еще полезен? Какие есть инструменты анализа производительности? Где уместно анализировать?
Эта статья отвечает на эти вопросы для вас. Поняв эти проблемы, вы можете быть более удобными при оптимизации производительности.
содержание:
- 1. Суть оптимизации производительности
- 2. Ознакомьтесь с классикой: Yahoo Military Rules
- 3. Показатели эффективности
- 4. Инструменты производительности: если вы хотите делать хорошие дела вместе, вы должны сначала отточить свои инструменты.
- 5. Расскажите о мониторинге
- 6. Резюме
1. Суть оптимизации производительности
1.1 Быстрее отображать и быстрее реагировать
Цель оптимизации производительности — предоставить пользователям лучший опыт, который включает следующие аспекты: более быстрое отображение, более быстрый интерактивный отклик и отсутствие застреваний страниц.
Более подробно это означает, что когда пользователь вводит URL-адрес сайта для полного отображения всей страницы, используются различные стратегии и методы оптимизации, чтобы ускорить загрузку страницы; во время использования пользователем реакция пользователя на операцию более отзывчива. Со временем пользовательский опыт становится лучше.
Frontend-инженерам для оптимизации производительности необходимо понимать природу загрузки и рендеринга в браузере. Только поняв основные принципы, мы можем добиться лучшей оптимизации. Итак, давайте сначала посмотрим, как выглядит архитектура браузера.
1.2 Понимание многопроцессорной архитектуры браузера
По большому счету браузер представляет собой многопроцессорную архитектуру.
Может случиться так, что процесс содержит несколько потоков, или это может быть несколько процессов, каждый процесс имеет несколько потоков, и потоки взаимодействуют через IPC. Каждый браузер имеет разные детали реализации, и не существует стандарта, определяющего, как браузеры должны его реализовывать.
Здесь мы говорим только об архитектуре Chrome.
На следующем рисунке показана текущая диаграмма многопроцессорной архитектуры Chrome.(Изображение взято из статьи Марико Косака «Взгляд изнутри на современный веб-браузер»)
Давайте посмотрим, какой части окна браузера соответствует каждый из этих процессов:(Изображение взято из статьи Марико Косака «Взгляд изнутри на современный веб-браузер»)
Итак, как посмотреть, какой процесс запущен браузером?
В хроме мы можем увидеть запущенный процесс через Дополнительно->Дополнительные инструменты->Диспетчер задач.
Из официального сайта Chrome и исходного кода мы также можем узнать, что эти процессы включены в многопроцессорную архитектуру:
- Браузерный процесс: После открытия браузера всегда только один. Процесс имеет поток пользовательского интерфейса, сетевой поток, поток хранилища и так далее. После того, как пользователь вводит URL-адрес, процесс браузера сначала отвечает и запрашивает сервер для получения данных. Затем передается процессу Renderer.
- Процесс рендеринга: по одному на каждую вкладку, отвечающий за весь процесс выполнения html, css и js.Оптимизация производительности интерфейса также связана с этим процессом..
- Процесс плагина: связан с плагинами браузера, такими как flash и т. д.
- Процесс GPU: браузеры совместно используют один. Он в основном отвечает за загрузку растрового изображения тайла, нарисованного в процессе рендеринга, в графический процессор в виде текстуры и вызов методов, связанных с графическим процессором, для вывода текстуры на экран.
Слова здесь - лишь краткое введение в многопроцессорную архитектуру браузера, чтобы у каждого было предварительное представление об общей архитектуре браузера.На самом деле за этим стоит много деталей, поэтому я не буду их раскрывать здесь по одному. Заинтересованные могут рассмотреть повнимательнееэта серия статейа такжеофициальный сайт хромапредставлять.
1.3 Понимание процесса рендеринга страницы
1.3.1 Renderer Process & GPU Process
Из приведенной выше мультиархитектуры мы узнали, что внешний рендеринг и оптимизация производительности в основном связаны с процессом рендерера и процессом графического процессора. Итак, какова их архитектура?
Взгляните на эту картинку, с которой мы все слишком хорошо знакомы.(Фото цитируется Павлом.«Анатомия кадра»)
- Процесс рендеринга: включая 3 потока. Композитный поток (Compositor Thread), основной поток (Main Thread), Compositor Tile Worker.
- Процесс GPU: только поток GPU отвечает за получение текстуры от потока композитора в процессе рендерера и отображение ее на экране.
1.3.2 Подробный процесс визуализации
Роли трех потоков в процессе визуализации:
- Поток компоновщика: сначала получите сигнал vsync (сигнал vsync относится к операционной системе, дающей браузеру указание отрисовать новый кадр), и любые события первыми поступят в поток компоновщика. Если к основному потоку не привязаны никакие события, то поток Compositor будет избегать входа в основной поток и пытаться преобразовать ввод в движения на экране. Он передает обновленную информацию о положении слоя в виде кадра через поток графического процессора на графический процессор для рисования.
Когда пользователь быстро скользит, если основной поток не связывает события, поток Compositor может быстро реагировать и рисовать, что является оптимизацией, выполняемой браузером.
- Основная тема:Основной поток — это поток, с которым знакомы наши фронтенд-инженеры, здесь выполняются такие действия, как парсинг Html, расчет стиля, вёрстка, отрисовка и синтез. Таким образом, проблемы с производительностью произошли здесь. Так что сосредоточься здесь.
- Compositor Tile Worker: Один или несколько рабочих процессов создаются потоком композиции для обработки работы по растеризации.
Сервис-воркеры и веб-воркеры могут временно понять, что они тоже находятся в процессе рендерера, и здесь не будут обсуждаться.
1.3.2.1 Main Thread
Необходимо подчеркнуть основную нить. Потому что это среда, в которой действительно существует наш код.
На диаграмме процесса рендеринга и процесса графического процессора в предыдущем разделе мы видим красную стрелку, указывающую от Recal Styles and Layout к requestAnimationFrame, что означает наличие Forced Synchronous Layout (или Styles) (принудительное переформатирование и перерисовка). ), что особенно важно с точки зрения производительности.
В основной теме есть несколько вещей, на которые стоит обратить внимание:
- requestAnimationFrame: Поскольку расчет макета и стиля происходит после rAF, rAF — идеальное время для внесения изменений в элементы. Если вы измените 100 классов на элемент здесь, 100 вычислений не будут выполнены, они будут обрабатываться позже пакетами. Важно отметить, что любые вычисляемые свойства стиля и макета (например: el.style.backgroundImage или el.style.offsetWidth) нельзя запрашивать в rAF, так как это приведет к перерисовке и перекомпоновке.
- Макет: расчет макета обычно производится для всего документа и пропорционален размеру элемента DOM! (Следует отметить, что если на странице слишком много элементов DOM, это также вызовет проблемы с производительностью.)
Порядок основного потока всегда следующий: обработчик событий ввода->requestAnimationFrame->ParseHtml->ReculateStyles->Layout->Update Layer Tree->Paint->Composite->commit->requestIdleCallback, только, например, спереди назад , сначала надо пересчитать стили, потом макет, потом рисование. Однако, если ему нужно сделать только последний шаг, Paint, то это все, что он делает, и предыдущие ReculateStyles и Layout больше не повторятся.
Здесь на самом деле дает нам подсказку:Если мы хотим сохранить частоту кадров на уровне 60, то есть время выполнения js на кадр меньше 16,66 мс, то наша цель оптимизации производительности — заставить основной поток выполняться как можно меньше..
Основываясь на этих шагах в основном потоке, в идеале мы хотим, чтобы в браузере выполнялся только последний шаг: Composite.
Свойства CSS — это модули, на которые нам нужно обратить внимание. что здесь описаноCSS-свойстваПриводит к перерисовке, перекомпоновке и композитингу. Например, давайте зададим элементу позицию для перемещения:transformа такжеopacityКомпозиция может быть запущена напрямую, ноleftа такжеtopНо это вызовет три действия Layout, Paint, Composite. Поэтому очевидно, что лучшим решением является использование преобразования.
Но это не означает, что мы не должны использовать такие свойства, как left и top, которые могут вызвать перерисовку при перерисовке, но мы должны обратить внимание на влияние каждого свойства на производительность браузера..
2. Ознакомьтесь с классикой: Yahoo Military Rules
Много лет назад Николас С. Закас из Yahoo предложил 35 военных правил в 7 категориях, и до сих пор многие рекомендации по оптимизации внешнего интерфейса вращались вокруг этого. Если мы строго следуем этим правилам, на самом деле нам предстоит много работы по оптимизации.Пока мы тщательно практикуемся, улучшение производительности не является проблемой.
Давайте посмотрим, вокруг чего вращаются его 7 категорий:
- Сервер: связанный с запросом, инициированным страницей;
- Cookie: связанные с запросом, инициированным страницей;
- Мобильный: связанный с запросами страниц;
- Контент: связанный с рендерингом страницы;
- Изображение: связано с рендерингом страницы;
- CSS: связанный с рендерингом страницы;
- Javascript: Относится к рендерингу страницы и взаимодействию.
Как видно из вышеприведенного описания, на самом деле военные уставы Yahoo основаны на моменте, когда страница инициирует запрос, до завершения рендеринга страницы, и страница начинает взаимодействовать, и предлагаются некоторые принципы.
Многие принципы всем знакомы, поэтому я не буду их все раскрывать, желающие могут ознакомиться с ними.оригинальный. Вот некоторые моменты, которые игнорируются, но заслуживают внимания:
- Уменьшите количество узлов DOM
Зачем уменьшать количество узлов DOM? При обходе и запросе 500 и 5000 узлов DOM для привязки событий будет разница. Когда на странице слишком много узлов DOM, следует рассмотреть схему бесконечной прокрутки, чтобы сделать узлы области просмотра управляемыми. может видетьпредложение Google.
- Уменьшить размер файла cookie
Передача файлов cookie приведет к нерациональному использованию полосы пропускания и повлияет на время отклика. Вы можете сделать это следующим образом: удалить ненужные файлы cookie; Статические ресурсы не требуют файлов cookie, можно использовать другие доменные имена, и файлы cookie не будут активно использоваться.
- Избегайте того, чтобы src изображения был пустым
Когда src изображения пуст, разные браузеры будут иметь разные побочные эффекты и будут повторно инициировать запрос вместе.
3. Показатели эффективности
3.1 Какие показатели эффективности действительно могут отражать пользовательский опыт?
| Точки для размышлений | подробности |
|---|---|
| Is it happening? | Была ли навигация успешной и ответил ли сервер |
| Is it useful? | Было ли отрисовано достаточно контента, чтобы пользователь начал взаимодействовать |
| Is it usable? | Может ли пользователь взаимодействовать со страницей и занята ли страница |
| Is it delightful? | Является ли взаимодействие плавным и естественным, без задержек или заиканий |
Обычно есть 2 способа измерения производительности.
- Локальное экспериментальное измерение: локальное моделирование пользовательской сети, оборудования и других условий тестирования. Обычно при разработке новых функций экспериментальное измерение очень важно, потому что мы не знаем, какие проблемы с производительностью будут у этой функции, когда она будет выпущена онлайн, поэтому предварительное тестирование производительности можно предотвратить.
- Онлайн-измерение: хотя экспериментальное измерение может отражать некоторые проблемы, оно не может отражать реальное положение пользователей. Аналогичным образом, на стороне пользователя проблемы с производительностью могут быть связаны с устройством пользователя, условиями сети и тем, как пользователь взаимодействует со страницей.
Существует несколько типов, связанных с воспринимаемой пользователем производительностью.
- Время загрузки страницы: насколько быстро страница загружается и отображает элементы на странице.
- Время отклика после загрузки: сколько времени требуется странице, чтобы реагировать на действия пользователя после загрузки и выполнения кода js.
- Время выполнения: после загрузки страницы интерактивное время ответа пользователю.
- Визуальная стабильность: элементы страницы перемещаются не так, как ожидает пользователь, и мешают взаимодействию с ним.
- Беглость: Отрисовываются ли переходы и анимация с постоянной частотой кадров и плавно ли они переходят из одного состояния в другое.
В соответствии с указанными выше категориями Google и Рабочая группа W3C по производительности предоставляют следующие показатели эффективности:
- First contentful paint (FCP):Измеряет время, когда страница начинает загружаться до тех пор, пока на ней не отобразится определенный фрагмент контента.
- Largest contentful paint (LCP):Измеряет время, необходимое для начала загрузки страницы, пока на ней не отобразится самый большой блок текста или изображения.
- First input delay (FID):Измерьте время с момента, когда пользователь впервые взаимодействует с веб-сайтом (например, щелкнув ссылку, кнопку, пользовательский элемент управления js), до момента, когда браузер действительно отвечает.
- Time to Interactive (TTI):Измерьте время от загрузки страницы до момента, когда визуализация визуализируется, сценарий инициализации страницы загружается, и пользователь может быстро и надежно реагировать.
- Total blocking time (TBT):Измеряет время между FCP и TTI, когда основной поток заблокирован и не может отвечать на ввод пользователя.
- Cumulative layout shift (CLS):Измеряет совокупную оценку непредсказуемых сдвигов макета, происходящих с момента начала загрузки страницы до момента, когда состояние становится скрытым.
Эти показатели могут в определенной степени измерять производительность страницы, но они не обязательно эффективны. Например. Основной пользователь индикатора LCP измеряет, загружается ли основной контент страницы, но в таком случае самый большой элемент не является основным контентом, поэтому индикатор LCP в данный момент не так важен. Каждое отдельное место имеет свою специфику, которую можно измерить с учетом вышеуказанных точек зрения, а также ее необходимо адаптировать к местным условиям.
3.2 Core Web Vitals
Среди показателей, перечисленных выше, Google определяет три основных показателя как Core Web Vitals. Они представляют собой: загрузку, взаимодействие, визуальную стабильность.
- Largest Contentful Paint (LCP): измерение производительности загрузки. Чтобы обеспечить лучший пользовательский интерфейс, индикатор LCP рекомендует, чтобы первая загрузка страницы была завершена в течение 2,5 с.
- First Input Delay (FID): Измеряет интерактивную производительность. Чтобы обеспечить лучший пользовательский опыт, рекомендуется, чтобы время взаимодействия составляло 100 мс или меньше.
- Cumulative Layout Shift (CLS): Измеряет визуальную стабильность. Чтобы обеспечить лучший пользовательский интерфейс, страница должна поддерживать CLS 0,1 или меньше.
Когда 75% просмотров страниц соответствуют указанным выше стандартам Good, производительность считается хорошей.
Core Web Vitals используется как основной показатель эффективности, но важны и другие показатели, как вспомогательные к основным показателям. Например, и TTFB, и FCP можно использовать для измерения производительности загрузки (время отклика сервера и время рендеринга), и они помогают в качестве меры проблемы для LCP. Точно так же TBT и TTI важны для измерения интерактивной производительности и являются дополнением к FID, но они не могут быть измерены онлайн и не отражают результаты, ориентированные на пользователя.
Google официально предоставляетweb-vitalsБиблиотеки, онлайн или локально, могут измерять 3 показателя, упомянутых выше:
import {getCLS, getFID, getLCP} from 'web-vitals';
function sendToAnalytics(metric) {
const body = JSON.stringify(metric);
// Use `navigator.sendBeacon()` if available, falling back to `fetch()`.
(navigator.sendBeacon && navigator.sendBeacon('/analytics', body)) ||
fetch('/analytics', {body, method: 'POST', keepalive: true});
}
getCLS(sendToAnalytics);
getFID(sendToAnalytics);
getLCP(sendToAnalytics);
Ниже мы поговорим о причинах определения этих трех показателей, о том, как их измерить и как их оптимизировать.
3.2.1 Largest Contentful Paint (LCP)
3.2.1.1 Как определяется LCP
(Картинка изLCP)
LCP относится к времени, когда страница начинает загружаться до тех пор, пока содержимое самого большого текстового блока или изображения не отобразится на странице. Итак, какие элементы можно определить как самые большие элементы?
-
<img>Этикетка -
<image>тег изображения в svg -
<video>тег видео - Изображение, загруженное по URL-адресу фона CSS()
- Элементы уровня блока, содержащие встроенный текст или текст
3.2.1.2 Как измерить LCP
Онлайн-инструмент измерения
- Chrome User Experience Report
- PageSpeed Insights
- Search Console (Core Web Vitals report)
- web-vitals JavaScript library
лабораторные инструменты
Измерение нативного JS APILCP также можно измерить с помощью JS API, в основном с помощью интерфейса PerformanceObserver, который в основном поддерживается другими браузерами, за исключением IE, который в настоящее время не поддерживается.
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
console.log('LCP candidate:', entry.startTime, entry);
}
}).observe({type: 'largest-contentful-paint', buffered: true});
Посмотрим, каков результат:
Официальная библиотека Web Vitals от GoogleGoogle также официально предоставляетweb-vitalsБиблиотека нижнего слоя по-прежнему использует этот API, просто помогает нам разобраться с некоторыми сценариями, которые нужно измерять и не измерять, и некоторыми деталями.
3.2.1.3 Как оптимизировать LCP
На LCP могут влиять следующие четыре фактора:
- время ответа сервера
- Заикание рендеринга, вызванное Javascript и CSS
- время загрузки ресурса
- рендеринг на стороне клиента
Более подробные предложения по оптимизации не будут расширены, вы можете обратиться кздесь.
3.2.2 First Input Delay (FID)
3.2.2.1 Как определяется FID
(Картинка изFID)
Мы все знаем о важности первых впечатлений, таких как впечатления, которые формируются, когда мы встречаем кого-то в первый раз, и окажут большое влияние на последующие взаимодействия. То же самое справедливо и для веб-сайта.
То, как быстро веб-сайт загружается до завершения, является одним из показателей, но не менее важно, как быстро он отвечает пользователям после загрузки. FID относится к последним.
Вы можете более подробно увидеть, где находится FID, на следующем рисунке:
(Картинка изFID)
Как видно из приведенного выше рисунка, когда основной поток занят, FID относится к времени задержки с момента, когда браузер получает ввод пользователя, до момента, когда браузер отвечает на ввод пользователя.
как правило,Когда мы пишем код, мы думаем, что пока пользователь вводит информацию, наш обратный вызов события будет реагировать немедленно, но на самом деле это не так. Возможно, основной поток занят, а браузер занят синтаксическим анализом и выполнением других js.Как показано во времени FID выше, основной поток обрабатывает другие задачи.
Когда время FID составляет 100 мс или меньше, это хорошо.
В приведенном выше примере пользователь взаимодействует именно тогда, когда основной поток наиболее загружен, но если пользователь взаимодействует, когда основной поток бездействует, браузер может ответить немедленно. Таким образом, значение FID должно быть сосредоточено на его распространении.
Фактически FID измеряет количество времени, в течение которого входное событие считается бездействующим, пока основной поток не будет бездействовать. Это означает, что FID можно измерить, даже если входные события не зарегистрированы. Потому что пользовательский ввод не обязательно требует выполнения события, но основной поток должен простаивать. Например, все следующие HTML-элементы должны дождаться завершения текущей задачи в основном потоке, прежде чем взаимодействовать с ответом:
- поле ввода, например
<input>,<textarea>,<radio>,<checkbox> - раскрывающийся список, например.
<select> - ссылки, такие как
<a>
Почему вы должны рассмотреть возможность измерения входной задержки в первый раз? Есть следующие причины:
- Потому что первая задержка ввода — это первое впечатление пользователя о вашем сайте, является ли сайт качественным и надежным;
- После первой загрузки самая большая проблема взаимодействия в сети на сегодняшний день;
- Предлагаемые решения того, как сайты должны бороться с высокой задержкой ввода в первый раз (например, разделение кода, уменьшение предварительной загрузки JavaScript) (TTI относится к измерению этой части), не обязательно такие же, как решение проблемы задержки ввода после загрузки страницы (FID относится к измерению этой части) это одно и то же решение. Таким образом, FID является более точным подразделением, основанным на TTI.
Почему FID просто содержит соответствующее время от пользовательского ввода до запуска основного потока? Без включения обработки событий в то время, когда браузер рисует пользовательский интерфейс?
Хотя время обработки и отрисовки основного потока также важно, если FID включает это время, разработчики могут использовать асинхронные API (например,setTimeout,requestAnimationFrame), чтобы разделить эту задачу на следующий кадр с меньшим временем FID, что не только не улучшает взаимодействие с пользователем, но и снижает его.
3.2.2.2 Как измерить FID
FID можно измерить в экспериментальной среде или в онлайн-среде.
Онлайн-инструмент измерения
- Chrome User Experience Report
- PageSpeed Insights
- Search Console (Core Web Vitals report)
- web-vitals JavaScript library
Измерение нативного JS API
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
const delay = entry.processingStart - entry.startTime;
console.log('FID candidate:', delay, entry);
}
}).observe({type: 'first-input', buffered: true});
В настоящее время PerformanceObserver не совместим с IE, а другие браузеры в основном совместимы.
Посмотрим, каков результат:
Официальная библиотека веб-витализаций GoogleGoogle также официально предоставляетweb-vitalsБиблиотека нижнего слоя по-прежнему использует этот API, просто помогает нам разобраться с некоторыми сценариями, которые нужно измерять и не измерять, и некоторыми деталями.
3.2.2.3 Как оптимизировать FID
На FID могут влиять следующие четыре фактора:
- Уменьшите влияние стороннего кода
- Сокращение времени выполнения Javascript
- Минимизируйте работу основного потока
- Уменьшить количество запросов и размер файла запроса
Более подробные предложения по оптимизации см.здесь.
3.2.3 Cumulative Layout Shift (CLS)
3.2.3.1 Как определяется CLS
(Картинка изCLS)
CLS — очень важная мера, ориентированная на пользователя. Он измеряет, является ли страница типографски стабильной.
Перемещение страницы часто происходит, когда ресурсы загружаются асинхронно или когда элементы DOM динамически добавляются к существующим элементам страницы. Этими элементами могут быть изображения, видео, сторонняя реклама или небольшие значки и т. д.
Однако мы можем не заметить эти проблемы в процессе разработки, поскольку изображения кэшируются локально при обновлении страницы в процессе отладки. При отладке интерфейса мы используем mock или в локальной сети, скорость интерфейса очень высокая, и эти задержки могут быть нами проигнорированы.
CLS — это индикатор, который помогает нам обнаружить эти проблемы, которые действительно возникают на стороне пользователя.
CLS — это оценка, которая измеряет каждое неожиданное изменение макета в течение жизни страницы. Перемещение макета происходит, когда визуальный элемент перемещается в другую позицию в следующем кадре.
Оценка CLS 0,1 или ниже считается хорошей.
Так как же рассчитывается оценка неожиданных перемещений макета?
Браузер отслеживает нестабильные элементы, перемещающиеся между кадрами. Доля перемещения макета определяется двумя элементами: долей воздействия и долей расстояния.
layout shift score = impact fraction * distance fraction
В видимой области объединение всех нестабильных элементов между предыдущим кадром и следующим кадром влияет на оценку движения компоновки текущего кадра.
Например, на изображении ниже слева находится элемент в текущем кадре, в следующем кадре элемент сдвинут вниз на 25% высоты видимой области. Красная пунктирная рамка отмечает объединение текущих элементов в двух кадрах, составляющих 75% неба, поэтому в настоящее время импактная фракция составляет 0,75.
Другим фактором, влияющим на долю перемещения макета, является доля расстояния, которая относится к расстоянию, на которое элемент перемещается относительно области просмотра. Будь то горизонтальный или вертикальный, берите максимальное значение.
В приведенном ниже примере вертикальное расстояние больше, и элемент перемещается на 25% расстояния относительно устья, поэтому доля расстояния составляет 0,25. Таким образом, доля перемещения макета равна0.75 * 0.25 = 0.1875.
Но имейте в виду, что не все изменения макета плохи, и многие веб-сайты меняют начало элементов. Плохо только в том случае, если перемещение макета не ожидается пользователем.
Другими словами, когда пользователь нажимает кнопку, макет меняется, что нормально, в JS API CLS есть полеhadRecentInput, используемый для определения наличия пользовательских данных в пределах 500 мс, в зависимости от ситуации этот расчет можно игнорировать.
3.2.3.2 Как измерить CLS
Онлайн-инструмент измерения
- Chrome User Experience Report
- PageSpeed Insights
- Search Console (Core Web Vitals report)
web-vitalsJavaScript library
лабораторные инструменты
Измерение нативного JS API
let cls = 0;
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
if (!entry.hadRecentInput) {
cls += entry.value;
console.log('Current CLS value:', cls, entry);
}
}
}).observe({type: 'layout-shift', buffered: true});
Посмотрим, каков результат:
Официальная библиотека веб-витализаций GoogleGoogle также официально предоставляетweb-vitalsБиблиотека нижнего слоя по-прежнему использует этот API, просто помогает нам разобраться с некоторыми сценариями, которые нужно измерять и не измерять, и некоторыми деталями.
3.2.3.3 Как оптимизировать CLS
Мы можем избежать непреднамеренного перемещения макета, следуя этим принципам:
- Элементы изображения или видео имеют атрибут размера или задают им размер пространства, устанавливают ширину, высоту или используютunsized-media feature policy.
- Не вставляйте содержимое над существующим элементом, за исключением соответствующего пользовательского ввода.
- Используйте анимацию или переходы вместо прямого изменения макета.
Подробнее см.здесь.
4. Инструменты производительности: если работник хочет хорошо выполнять свою работу, он должен сначала заточить свой инструмент.
Разработано GoogleВсе инструментыОба поддерживают измерение Core Web Vitals. Инструменты следующие:
- Lighthouse
- PageSpeed Insights
- Chrome DevTools
- Search Console
- Инструменты измерения, предоставляемые web.dev
- Расширение Web Vitals
- Chrome UX Report API
Эти инструменты поддерживают Core Web Vitals следующим образом:
4.1 Lighthouse
Откройте F12, вы увидите Lighthouse, нажмите «Создать отчет», вы можете создать отчет. Конечно, вы также можете использовать плагины Chrome.
Lighthhouse — это лабораторный инструмент, который тестирует эти аспекты локально, имитируя мобильные устройства и ПК. В то же время Lighthouse также сделает предложения по этим аспектам, которые стоит протестировать перед запуском продукта.
Маяк также предоставляетLighthouse CI, интегрируйте Lighthouse в конвейер непрерывной интеграции. Например, каждый раз перед выходом в интернет запускать пайплайн 50 раз, чтобы протестировать индикаторы Lighthouse и взять среднее значение, как только будет обнаружена аномалия, она будет немедленно проверена. Предварительное устранение неполадок с производительностью перед выпуском. Это будет подробно обсуждаться позже.
4.2 PageSpeed Insights
PageSpeed Insights (PSI) — это инструмент, который может анализировать онлайн и лабораторные данные. Он основан на реальных данных от пользователей онлайн-среды (в отчете Chrome UX) в сочетании с Lighthouse для создания отчета. Подобно Lighthouse, он также даст некоторые аналитические предложения, чтобы узнать, соответствуют ли основные веб-показатели страницы стандартам.
PageSpeed обеспечивает тест производительности только для одной страницы, а Search Console — тест производительности для всего сайта.
PageSpeed Insights также предоставляетAPIдля нашего использования. Точно так же мы можем интегрировать его в CI.
4.3 CrUX
Отчет Chrome UX (CrUX) относится к отчету, который объединяет тысячи наборов данных о пользовательском опыте, это согласие пользователя, прежде чем сообщалось, в настоящее время хранится в Google BigQuery, вы можете использовать запрос на вход в учетную запись. Он измеряет все показатели Core Web Vitals.
Упомянутый выше инструмент PageSpeed Insights — это вывод, сделанный на основе анализа данных CrUX.
Конечно, CrUX теперь также предоставляет нам API для запросов.Данные, которые можно запросить, включают:
- Largest Contentful Paint
- Cumulative Layout Shift
- First Input Delay
- First Contentful Paint
Принцип заключается в следующем:
Данные, запрашиваемые через API, обновляются ежедневно и объединяют данные за последние 28 дней.
Для конкретного использования, пожалуйста, обратитесь к официальномуdemo.
4.4 Панель производительности Chrome DevTools
Производительность — это наш наиболее часто используемый инструмент локального анализа производительности.
Вот несколько функций, на которые можно обратить внимание: Frame, Timings, Main, Layers, FPS. Объясните один за другим ниже.
4.4.1 Frame
После нажатия Frame для расширения вы увидите небольшой красный или зеленый блок, который представляет время использования каждого кадра. В настоящее время частота обновления экрана большинства устройств составляет 60 раз в секунду.Если скорость отображения браузером каждого кадра страницы соответствует частоте обновления экрана устройства, то есть 60 кадров в секунду, мы не будем воспринимать страницу. ситуация с картой.
Поднимем мышку вверх, чтобы увидеть:
Этот опыт гладкий.
Другой пример:
Предполагается, что этот кадр занял 30,9 мс, текущий — 32 кадра в секунду, и кадр отброшен.
4.4.2 Timings
Здесь вы можете увидеть синхронизацию нескольких ключевых индикаторов.
- FP: первая краска;
- FCP: первая содержательная краска;
- LCP: самая большая содержательная краска;
- DCL: событие DOMContentLoaded
- L: Событие при загрузке.
4.4.3 Main
Main — это наиболее часто используемая и самая важная функция в DevTools.
Через запись мы можем просмотреть процесс выполнения всех операций на странице в основном потоке. Это процесс, о котором мы часто говорим:
Если какой-либо процесс занимает слишком много времени или происходит часто, например, обновление дерева слоев занимает слишком много времени, часто появляются RecalcStyles, Layout (перерисовка и перекомпоновка), то необходимо уделить внимание. Пример будет приведен позже.
4.4.4 Layers
Слои — это слои, которые браузер создает в процессе рисования. Потому что суть лежащего в основе рендеринга браузера — вертикальное наслоение и горизонтальная сегментация. Суть этой части в том, что это происходит в процессе Renderer Process. Пример будет приведен позже.
Причина, по которой я хочу упомянуть здесь о слоях, заключается в том, чтоРендеринг слоя также влияет на проблемы с производительностью., и иногда это не так просто заметить!
Панель «Слои» обычно не отображается по умолчанию, щелкните «Дополнительно» -> «Дополнительные инструменты» -> «Слои», чтобы открыть ее.
Щелкните панель «Слои», щелкните нижний левый треугольник, чтобы развернуть кнопку, и вы увидите окончательный составной слой, сгенерированный на странице. В верхнем левом углу справа можно выбрать разные широты для просмотра.
Выбрав слой, вы можете просмотреть причину его создания.
Ядро Chrome Blink дает 54 причины, по которым будет создан составной слой:
constexpr CompositingReasonStringMap kCompositingReasonsStringMap[] = {
{CompositingReason::k3DTransform, "transform3D", "Has a 3d transform"},
{CompositingReason::kTrivial3DTransform, "trivialTransform3D",
"Has a trivial 3d transform"},
{CompositingReason::kVideo, "video", "Is an accelerated video"},
{CompositingReason::kCanvas, "canvas",
"Is an accelerated canvas, or is a display list backed canvas that was "
"promoted to a layer based on a performance heuristic."},
{CompositingReason::kPlugin, "plugin", "Is an accelerated plugin"},
{CompositingReason::kIFrame, "iFrame", "Is an accelerated iFrame"},
{CompositingReason::kSVGRoot, "SVGRoot", "Is an accelerated SVG root"},
{CompositingReason::kBackfaceVisibilityHidden, "backfaceVisibilityHidden",
"Has backface-visibility: hidden"},
{CompositingReason::kActiveTransformAnimation, "activeTransformAnimation",
"Has an active accelerated transform animation or transition"},
{CompositingReason::kActiveOpacityAnimation, "activeOpacityAnimation",
"Has an active accelerated opacity animation or transition"},
{CompositingReason::kActiveFilterAnimation, "activeFilterAnimation",
"Has an active accelerated filter animation or transition"},
{CompositingReason::kActiveBackdropFilterAnimation,
"activeBackdropFilterAnimation",
"Has an active accelerated backdrop filter animation or transition"},
{CompositingReason::kXrOverlay, "xrOverlay",
"Is DOM overlay for WebXR immersive-ar mode"},
{CompositingReason::kScrollDependentPosition, "scrollDependentPosition",
"Is fixed or sticky position"},
{CompositingReason::kOverflowScrolling, "overflowScrolling",
"Is a scrollable overflow element"},
{CompositingReason::kOverflowScrollingParent, "overflowScrollingParent",
"Scroll parent is not an ancestor"},
{CompositingReason::kOutOfFlowClipping, "outOfFlowClipping",
"Has clipping ancestor"},
{CompositingReason::kVideoOverlay, "videoOverlay",
"Is overlay controls for video"},
{CompositingReason::kWillChangeTransform, "willChangeTransform",
"Has a will-change: transform compositing hint"},
{CompositingReason::kWillChangeOpacity, "willChangeOpacity",
"Has a will-change: opacity compositing hint"},
{CompositingReason::kWillChangeFilter, "willChangeFilter",
"Has a will-change: filter compositing hint"},
{CompositingReason::kWillChangeBackdropFilter, "willChangeBackdropFilter",
"Has a will-change: backdrop-filter compositing hint"},
{CompositingReason::kWillChangeOther, "willChangeOther",
"Has a will-change compositing hint other than transform and opacity"},
{CompositingReason::kBackdropFilter, "backdropFilter",
"Has a backdrop filter"},
{CompositingReason::kBackdropFilterMask, "backdropFilterMask",
"Is a mask for backdrop filter"},
{CompositingReason::kRootScroller, "rootScroller",
"Is the document.rootScroller"},
{CompositingReason::kAssumedOverlap, "assumedOverlap",
"Might overlap other composited content"},
{CompositingReason::kOverlap, "overlap",
"Overlaps other composited content"},
{CompositingReason::kNegativeZIndexChildren, "negativeZIndexChildren",
"Parent with composited negative z-index content"},
{CompositingReason::kSquashingDisallowed, "squashingDisallowed",
"Layer was separately composited because it could not be squashed."},
{CompositingReason::kOpacityWithCompositedDescendants,
"opacityWithCompositedDescendants",
"Has opacity that needs to be applied by compositor because of composited "
"descendants"},
{CompositingReason::kMaskWithCompositedDescendants,
"maskWithCompositedDescendants",
"Has a mask that needs to be known by compositor because of composited "
"descendants"},
{CompositingReason::kReflectionWithCompositedDescendants,
"reflectionWithCompositedDescendants",
"Has a reflection that needs to be known by compositor because of "
"composited descendants"},
{CompositingReason::kFilterWithCompositedDescendants,
"filterWithCompositedDescendants",
"Has a filter effect that needs to be known by compositor because of "
"composited descendants"},
{CompositingReason::kBlendingWithCompositedDescendants,
"blendingWithCompositedDescendants",
"Has a blending effect that needs to be known by compositor because of "
"composited descendants"},
{CompositingReason::kPerspectiveWith3DDescendants,
"perspectiveWith3DDescendants",
"Has a perspective transform that needs to be known by compositor because "
"of 3d descendants"},
{CompositingReason::kPreserve3DWith3DDescendants,
"preserve3DWith3DDescendants",
"Has a preserves-3d property that needs to be known by compositor because "
"of 3d descendants"},
{CompositingReason::kIsolateCompositedDescendants,
"isolateCompositedDescendants",
"Should isolate descendants to apply a blend effect"},
{CompositingReason::kFullscreenVideoWithCompositedDescendants,
"fullscreenVideoWithCompositedDescendants",
"Is a fullscreen video element with composited descendants"},
{CompositingReason::kRoot, "root", "Is the root layer"},
{CompositingReason::kLayerForHorizontalScrollbar,
"layerForHorizontalScrollbar",
"Secondary layer, the horizontal scrollbar layer"},
{CompositingReason::kLayerForVerticalScrollbar, "layerForVerticalScrollbar",
"Secondary layer, the vertical scrollbar layer"},
{CompositingReason::kLayerForScrollCorner, "layerForScrollCorner",
"Secondary layer, the scroll corner layer"},
{CompositingReason::kLayerForScrollingContents, "layerForScrollingContents",
"Secondary layer, to house contents that can be scrolled"},
{CompositingReason::kLayerForSquashingContents, "layerForSquashingContents",
"Secondary layer, home for a group of squashable content"},
{CompositingReason::kLayerForForeground, "layerForForeground",
"Secondary layer, to contain any normal flow and positive z-index "
"contents on top of a negative z-index layer"},
{CompositingReason::kLayerForMask, "layerForMask",
"Secondary layer, to contain the mask contents"},
{CompositingReason::kLayerForDecoration, "layerForDecoration",
"Layer painted on top of other layers as decoration"},
{CompositingReason::kLayerForOther, "layerForOther",
"Layer for link highlight, frame overlay, etc."},
{CompositingReason::kBackfaceInvisibility3DAncestor,
"BackfaceInvisibility3DAncestor",
"Ancestor in same 3D rendering context has a hidden backface"},
};
4.4.5 Rendering
Панель Rendering также скрывает множество полезных функций.
4.4.5.1 Paint flashing
Когда установлен флажок Paint flashing, мы увидим, какой контент на странице перерисовывается:
4.4.5.2 Layout Shift Regions
После проверки областей смещения макета, взаимодействия, вы можете увидеть, какие элементы макета были перемещены:
4.4.5.3 Frame Rendering Stats
Этот инструмент имеет виньетку.
Предшественником Frame Rendering Stats является счетчик FPS в версии Google.85.0.4181.0Изменено на статистику рендеринга кадров, но принудительнопользователи жалуются, поменяли еще в 90 версии.
Статистика рендеринга кадров в основном показывает частоту кадров, которая не падает. В то время как FPS фокусируется на частоте обновления дисплея в секунду.
Почему Chrome переключается на отсутствие снижения частоты кадров, потому что считает, что отсутствие снижения частоты кадров может лучше отражать плавность страницы. FPS показывает, что количество кадров, отображаемых в секунду, может в определенной степени отражать плавность страницы, но в некоторых особых случаях, таких как страницы, которые не активированы или простаивают, частота кадров будет относительно низкой, что не отражает реальная ситуация.
(картинка взята изобсуждение на форуме разработчиков Blink)
4.4.6 Memory
В больших проектах также возникают проблемы с памятью. DevTools также предоставляет нам инструменты для анализа памяти.
Щелкните панель «Память» и нажмите кнопку «Запись».
Нажав кнопку записи, вы увидите использование памяти в текущем состоянии.По размеру мы можем определить место с чрезмерным использованием памяти.
4.5 Search Console
Google Search Console — это, по сути, платформа для мониторинга и поддержания присутствия вашего сайта в результатах поиска Google, а также для устранения неполадок. Источник данных — CrUX.
Он будет отображать 3 метрики Core Web Vitals: LCP, FID, CLS. Если вы обнаружите проблему, вы можете использовать ее с PageSpeed для анализа проблемы.
(Картинка взята с сайта vital-tools)
4.6 web.dev
web.dev/measureЭто официальный инструмент измерения производительности, предоставляемый Google, и он также предоставляет индикаторы, аналогичные PageSpeed Insight, а также некоторые конкретные предложения по изменению кода.
4.7 Web Vitals extension
Google также предоставляет расширения для измерения Core Web Vitals. Доступна сStoreв установке.
4.8 Инструменты: размышления и выводы
Когда мы знаем так много инструментов, как мы выбираем? Как использовать эти инструменты для анализа?
- Прежде всего, мы можем использовать Lighthouse для локального измерения и оптимизации в соответствии с некоторыми предложениями, данными в отчете;
- После выпуска мы можем использовать PageSpeed Insights, чтобы увидеть производительность офлайн и онлайн;
- Затем мы можем использовать Chrome User Experience Report API для получения данных за последние 28 дней онлайн;
- Если данные окажутся ненормальными, мы можем использовать инструмент DevTools для конкретного анализа позиционирования кода;
- Используйте отчет Core Web Vitals в Search Console, чтобы увидеть общую функциональность сайта;
- Используйте расширение Web Vitals, чтобы легко увидеть основные показатели страницы;
5. Расскажите о мониторинге
В последней главе мы хотим поговорить о мониторинге.
Когда мы занимаемся оптимизацией производительности, мы часто собираем пользовательские данные и выполняем анализ производительности с помощью различных онлайн-управлений. Да, это средство наблюдения, точнее, средство наблюдения «постфактум».
** Мониторинг «по факту» важен, но мы также должны учитывать мониторинг «до», иначе каждый раз, когда выпускается запрос, заходите в онлайн, чтобы увидеть данные. Эй, я обнаружил, что данные упали, а затем мы идем, чтобы проверить код, проверить данные и проверить причину. Такие оптимизированные по производительности одноклассники всегда в роли «преследователей», всегда следуя за прикладом, чтобы проверить проблемы.
Например, таким образом мы можем проводить мониторинг «до».
Построить конвейерный механизм. Как это сделать на конвейере?
-
Lighthouse CIилиPageSpeed Insights API: интегрируйте API Lighthouse или PageSpeed Insights в конвейер CI и выведите анализ отчета.
-
PuppeteerилиPlaywright: используйте инструмент автоматического тестирования E2E для интеграции в конвейер для имитации пользовательских операций и получения файлов трассировки Chrome, которые загружаются щелчком в левом верхнем углу после того, как мы обычно записываем производительность. И Кукловод, и Драматург основаны наChrome DevTools Protocol.
- Файлы трассировки Chrome: согласноправилоАнализируя файл Trace, вы можете получить время выполнения каждой функции. Если время выполнения функции превышает пороговое значение, может быть сгенерировано исключение. Если время выполнения функции каждый раз превышает порог, то это стоит отметить. Но есть еще один момент, о котором стоит подумать: важно, превышает ли время выполнения функции критическое значение, но важнее то, является ли это функцией ввода-ответа пользователя и связана ли она с пользовательским опытом.
(Изображение от Flo Sloot’s Jank: вы можете измерить, что чувствуют ваши пользователи.)
- Выходной отчет. Определите пороги аномалий. Если исключений слишком много, подумайте, не блокировать ли процесс выпуска.
6. Резюме
Наконец, мы подошли к нашему сводному разделу. Давайте рассмотрим предыдущий контент:
В первой части рассказывается об общей архитектуре браузера и процессах, связанных с рендерингом.Почему эта глава включена в эту статью по оптимизации производительности? Браузер — это песочница или темная коробка для нашей фронтенд-разработки. Мы знаем, что js, html и css можно комбинировать для достижения наших целей, но если мы знаем, как он отображает, выполняет и обрабатывает наш код, будь то для требований или оптимизации производительности, мы можем узнать больше об этом и почему.
Вторая часть, военные спецификации Yahoo, представляет собой очень классическое предложение по оптимизации, сделанное много лет назад. Она и по сей день играет для нас важную направляющую роль. Вы найдете в нем исчерпывающее руководство от загрузки страницы, рендеринга страницы до взаимодействия со страницей. Это все еще похоже на идею Web Vitals, предложенную Chrome и W3c сегодня.
Третья часть, показатели производительности, справочные стандарты и рекомендации отраслевых эталонов, может лучше помочь нам в оптимизации.
Четвертая часть, инструменты производительности. Если рабочий хочет хорошо работать, он должен сначала заточить свои инструменты. Мы все знаем эту истину, и использование хороших инструментов может заставить нас делать больше с меньшими затратами.
В пятой части мониторинг играет очень важную роль в оптимизации производительности, а мониторинг «до» более важен для предотвращения проблем до их возникновения. Сделайте оптимизацию производительности средством предотвращения, а не преследования.
Рори много сказал, конечно, есть еще много деталей оптимизации производительности, которые не были упомянуты, если есть ошибки, пожалуйста, поправьте меня. Или, если у вас есть какие-либо хорошие методы или предложения, пожалуйста, не стесняйтесь общаться в частном чате ~
Справочная статья:Web.Dev/learn-Web-V…
Developers.Google.com/Web/updates…
aero twist.com/blog/ он и-пресс…