Рендеринг страницы: анализ производительности

JavaScript браузер Ajax CSS

Список эффектов рендеринга свойств CSS>>


Введение в производительность


Панель производительности Chrome DevTools записывает и анализирует все действия на странице во время выполнения.

В режиме инкогнито вы можете избежать влияния плагинов Chrome.

График частоты кадров

1. Просмотр записи

Вышеупомянутая часть представляет собой информацию о номере кадра:

  • 1312.3ms: время одного кадра
  • 1fps: кадров в секунду

Следующая часть представляет собой снимок веб-страницы, который браузер делает через определенные промежутки времени.

2. Просмотр в реальном времени

горячая клавишаctrl + shift + pЧастоту кадров можно просматривать в режиме реального времени.

Возможны и другие конфигурации

  • Paint Flashing выделяет части веб-страницы, которые необходимо перекрасить.
  • Границы слоя Отображает границы слоя.
  • Измеритель FPS Сведения о кадре каждой секунды, распределение информации о кадре кадров и использование памяти ГПУ.
  • Проблемы производительности прокрутки анализируют проблемы с производительностью при прокрутке с помощью мыши, показывая области, которые замедляют прокрутку экрана.
  • Эмуляция мультимедиа CSS Имитация типов мультимедиа CSS для просмотра эффектов стилей CSS на разных устройствах Возможные варианты типов мультимедиа: печать, экран

график пламени

  • Загрузка: сетевое взаимодействие и парсинг HTML
  • Сценарии: выполнение Javascript
  • Рендеринг: расчет стиля и верстка, т.е. перестановка
  • Живопись: перерисовать Соответствующее подробное событие>>>

Как обнаружить проблемы с производительностью?

1. Маленький красный треугольник

Общие причины:

  • обработчик занял xxx мс Операция заняла слишком много времени
  • принудительное переформатирование, вероятно, является узким местом производительности. «Принудительная синхронизация макета» может вызвать проблемы с производительностью, обычно потому, что свойство считывается после изменения стиля, что приводит к повторной визуализации браузера для получения последнего значения свойства.

2. Дрожание макета

«Дрожание макета» относится к повторяющимся случаям «принудительной синхронизации макета». Это происходит, когда JavaScript постоянно выполняет запись и чтение из DOM, заставляя браузер постоянно пересчитывать макет. Дрожание макета также может вызывать длинные кадры, из-за чего страницы заикаются.

3. Длинная рама

Длинный кадр означает, что кадр занимает слишком много времени, что повлияет на скорость загрузки страницы и плавность анимации, в это время вы почувствуете, что страница загружается медленно или анимация зависает.

Количество кадров в секунду при воспроизведении анимации желательно должно достигать 60 кадров, что составляет 16,6 мс на кадр.


Пример


1. Разобрать html (исключая внешние файлы js css)

  • readystatechange (первый) (документ загружен и проанализирован) В этот момент состояние является интерактивным, то есть документ был загружен и проанализирован, но ресурс все еще загружается, за чем обычно следует DomContentLoaded.
  • DOMContentLoaded (построение дерева DOM завершено) Запускается, когда html-документ успешно загружен и проанализирован, когда построение дерева DOM завершено.
  • Пересчитать стиль (сборка CSSOM завершена) Изменение DOM путем добавления и удаления элементов, изменения свойств, классов или с помощью анимации приводит к тому, что браузер пересчитывает стили элементов и, во многих случаях, компоновку (то есть автоматическое перекомпоновку) страницы или ее частей. Шаги по пересчету стилей можно разделить на два шага:
  1. Браузер определяет, какие классы, псевдоселекторы и идентификаторы следует применять к указанному элементу.
  2. Получите все правила стиля из соответствующего селектора и рассчитайте окончательный стиль для этого элемента.
  • readystatechange (второй) (документ загружен и проанализирован, а ресурс загружен) На этом этапе состояние завершено, что указывает на то, что документ и ресурсы были загружены, и это состояние обычно запускает загрузку сразу после этого.
  • событие загрузки Запускается, когда и документ, и ресурс закончили загрузку. Больше событий завершения загрузки страницы>>.
  • Макет Макеты почти всегда применяются ко всему документу, но все же в основном зависят от количества затронутых узлов.

2. Разобрать html (включая внешние файлы js css)

  • Оценить скрипт (выполнить js)
  • макет становится не выполненным в ParseHtml Это может быть связано с тем, что загрузка файлов CSS или файлов JS блокирует процесс рендеринга всей страницы, поскольку и js, и css могут стилизовать теги. Если файл не существует, нет проблем с ожиданием загрузки.

3. Изменить цвет фона (перерисовать)

4. Изменить высоту (переставить)

По сравнению с перерисовкой есть еще один Layout

5. Загрузка ресурса изображения (img или bg)

Если размер метки изображения не изменится, это вызовет перерисовку


принципы, которым нужно следовать


1. О блокировке

  • Загрузка CSS не будет блокировать синтаксический анализ дерева DOM, синтаксический анализ CSS будет заблокирован;
  • Загрузка и парсинг CSS заблокирует js (поэтому встроенные стили не обязательно грузить с высокой производительностью, подходят для первого экрана)
  • js заблокирует синтаксический анализ дерева DOM (поскольку js изменит содержимое дерева DOM)
  • Загрузка файлов шрифтов, представленных CSS, также будет блокировать рендеринг JS и страницы

2. О ипроцесс рендеринга страницысоответствующий

  1. js время выполнения: В настоящее время следует построить только дерево dom и дерево CSSOM из предыдущей части, потому что js необходимо управлять содержимым и стилем тегов в предыдущей части через dom api и CSSOM api.
  2. Построение DOM-дерева завершеноСобытие :DomContentLoaded
  3. Построение CSSOM завершено, построение Render Tree завершено: Пересчитать стиль
  4. Layout: событие макета
  5. paint: Paint (рисование слоя изображения) и Composite Layers (объединение слоев изображения),Изменение любого свойства, кроме свойств преобразования или непрозрачности, всегда вызывает отрисовку Paint..
  6. перестановка оплавления: 3 4 5 шагов
  7. перекрашивать перекрашивать: 35 шагов, чтобы пройти снова
  8. Изменение свойства, которое не отображает и не отрисовывает: 3 шага + составные слои, это поведение имеет наименьшие накладные расходы из 678 шагов повторного рендеринга и подходит для анимации или прокрутки, например для преобразования непрозрачности.

3. Некоторые особенности браузера Chrome

  • Очередь рендеринга: в браузере есть очередь рендеринга, которая превращает несколько последовательных операций переупорядочения и перерисовки в одну. Когда вы читаете DOM, если очередь не пуста, хром очистит очередь и немедленно переупорядочит или перерисует; если она пуста, хром не будет выполнять дополнительные операции.
  • Макет: во время макета или перекомпоновки браузеру необходимо рассчитать размер пространства, которое будет занимать элемент, и его положение на экране.Режим макета веб-страницы означает, что один элемент может влиять на другие элементы, такие как<body>Ширина элемента обычно влияет на ширину его дочерних элементов и узлов по всему дереву.
  • Рисование и компоновка. Рисование обычно выполняется на нескольких поверхностях (часто называемых слоями), поэтому браузеру необходимо отрисовывать их на экране в правильном порядке, чтобы страница отображалась правильно.
  • Селектор CSS: для сложных селекторов CSS браузеру нужно тратить больше времени на определение стиля элемента, поэтому принцип написания CSS, ориентированный на классы, более соблюдается иностранцами, например: псевдокласс nth-last-child может быть используется независимо (Иначе его называют псевдоклассом ( ̄▽ ̄)").

оптимизация производительности


блокировка оптимизации

  • js есть проблема: 1) Загрузка и выполнение JS блокирует синтаксический анализ DOM и рендеринг страницы. 2) При ссылке на сторонний скрипт, когда сторонний поставщик услуг запрашивает отсрочку, страница будет пустой; js-решение: Страницы могут загружать js асинхронно, добавляя ключевые слова defer и async.

  1. Оба загружаются асинхронно, разница в следующем: async (обратитесь к ajax): синтаксический анализ DOM и рендеринг страницы не будут заблокированы во время асинхронной загрузки; время выполнения — когда загрузка завершена; он будет заблокирован во время выполнения, но в это время DOM может быть проанализирован и даже страница отрендерилась, кроме того, это повлияет на порядок исполнения js-файлов. defer: синтаксический анализ DOM и рендеринг страницы не будут блокироваться во время асинхронной загрузки; время выполнения — после завершения синтаксического анализа DOM и до события DOMContentLoaded (поэтому событие DCLoad и событие готовности jquery будут заблокированы); DOM был проанализирован во время выполнения, и будет заблокирован только рендеринг страницы.
  2. порядок загрузки файла js Синхронный > Асинхронный То же самое асинхронно в порядке завершения загрузки Такая же отсрочка в порядке введения асинхронная отсрочка обычно не используется вместе

уменьшить повторный рендеринг

О CSS

  • Используйте простую таблицу стилей. Чем проще таблица стилей, тем быстрее она будет перекомпоновываться и перерисовываться. Конкретно:
  1. Уменьшите сложность селекторов и используйте меньше псевдоклассов, используйте методы, ориентированные на классы, такие как БЭМ;
  2. Чтобы уменьшить количество элементов, стили которых должны быть рассчитаны, количество элементов, объявленных недействительными, должно быть сведено к минимуму.
  • Уменьшите иерархию элементов DOM. Чем выше уровень элементов DOM для перекомпоновки и перерисовки, тем выше стоимость.
  • Использовать display:none more. Элементы с display:none не находятся в дереве рендеринга, поэтому они не будут перекомпоновываться и перерисовываться.
  • Используйте анимацию CSS вместо анимации JS. Анимация CSS лучше, чем анимация JS, потому что CSS изменяет значение перевода и не вызывает изменения значений позиции, таких как offsetLeft и offsetTop.
  • Используйте absolute вместо float. Элементы, чей атрибут position является абсолютным или фиксированным, менее затратны в перекомпоновке, чем float, потому что им не нужно учитывать его влияние на другие элементы.
  • Используйте div вместо таблицы. Потому что небольшое изменение может привести к перестройке всей таблицы, например, изменение содержимого td.

О JS

  • Многократные чтения (или множественные записи) DOM должны быть сгруппированы, а не перемежаться. потому чтоНепрерывно устанавливая стили элементов (операции записи), браузер выполнит однократное выполнение, то есть вызовет только перекомпоновку или перерисовкуОднако, если стиль чтения вставлен между несколькими операциями записи, браузер должен немедленно переставить или перерисовывать.
  • Меняйте стили сразу. Не меняйте стили один за другим, а изменяйте класс или свойство el.style.csstext.
  • Используйте автономный DOM для изменения стилей элементов. НапримерcloneNode()клонируйте узел, а затем замените узел элемента илиdisplay:none → 改动 → 显示.
  • Максимально измените низкоуровневую модель DOM.
  • Не считывайте повторно значения атрибутов узла DOM в цикле.
  • Используйте window.requestAnimationFrame(), window.requestIdleCallback() для управления повторным рендерингом.

Увеличение fps (кадров в секунду)

Каждый кадр веб-анимации является повторным рендерингом, и кадры отправляются на экран в следующем порядке:

Зависимость между количеством кадров и плавностью анимации следующая:

  • 30–60 кадров в секунду: плавнее
  • 70--80: Голубь продольный наслаждается новой шелковистой Принимая во внимание большую часть частоты обновления дисплея 60 Гц, т.е. обновляется 60 раз в секунду, если более 60 кадров в секунду, вывод выше 60 на экран, то еслиfps > 刷新频率, на многовыходной картинке будет недопустимое количество кадров, и беглость не улучшится, но и вреда нет (вручную прикол д:).

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

Ручное управление повторным рендерингом

Метод window.requestAnimationFrame() может унифицировать некоторый код для выполнения при следующем повторном рендеринге. В частности, код js выполняется в начале следующего кадра. Если мы используем setTimeout или setInterval для выполнения визуального изменения, такого как анимация, его обратный вызов может быть выполнен в какой-то момент кадра, возможно, в конце, что приведет к потере кадров и вызовет заикание.

  1. Обработка «дрожания макета» Многократное чтение и запись свойств может вызвать дрожание макета, что приведет к увеличению длины кадров.
function doubleHeight(element) {
    var currentHeight = element.clientWidth;
    element.style.width = (currentHeight / 2) + 'px';
    element.style.height = '80px';
}
var elements = document.getElementsByTagName('tr');
for (var i = 0; i < elements.length; i++) {
    doubleHeight(elements[i]);
}

Измените функцию doubleHeight на следующую:

function doubleHeight(element) {
    var currentHeight = element.clientHeight;
    window.requestAnimationFrame(function () {
      element.style.height = (currentHeight * 2) + 'px';
    });
}

2) событие прокрутки страницы (прокрутка)

$(window).on('scroll', function() {
   window.requestAnimationFrame(scrollHandler);
});

3) Лучше всего подходит для анимации

комбинированный проект

Теперь в проекте страница (в качестве примера возьмем страницу «задача») будет запрашивать некоторые данные ajax при загрузке, такие как datagrid, данные дерева и т. д., а некоторые данные ajax загружаются только предварительно. Если эти ajax завершат запрос до рендеринга страницы, он заблокирует рендеринг страницы. Таким образом, одна и та же страница будет иметь два порядка рендеринга при разных скоростях сети:

  • выполнить после рендеринга

  • выполнить перед рендерингом

Решение

  1. Сделайте запрос ajax после загрузки всех ресурсов. Поместите загрузку данных элементов управления, таких как datagrid, в событие $(window).load().
  2. Ленивая инициализация контента в модальном режиме

Эффект


вопрос


Q: При запросе файлов js, каков порядок запроса и выполнения?

Ответ: Запросы выдаются вместе, порядок выполнения в порядке введения, и не будет выполняться первым, потому что последний сначала возвращает данные.

В: Будет ли ajax заранее запрашивать какие-то данные при загрузке страницы, повлияет ли это на производительность?

О: Может быть, может быть, нет. Ajax-запрос не влияет на производительность, а callback-функция выполняется после запроса. Функция обратного вызова ajax будет выполнена после завершения запроса и запуска основной программы js. Когда мы сможем увидеть страницу, нам нужно пройти два процесса анализа страницы и рендеринга. Если обратный вызов ajax выполняется до страницы рендерится, он блокирует процесс рендеринга.

Q: Почему jquery обычно выполняет код в готовом методе?

Ответ: ready отслеживает событие DOMContentLoaded, то есть отслеживает завершение построения DOM-дерева.

приложение


событие загрузки

мероприятие описывать
Parse HTML Браузер выполняет разбор HTML-файла
Parse Stylesheet Браузер выполняет синтаксический анализ файла CSS (одиночный относится к внешнему файлу CSS)
Finish Loading событие завершения сетевого запроса
Receive Data Событие получения запрошенных данных ответа, которое может инициироваться несколько раз, если данные ответа большие (неупакованные).
Receive Response Запускается при поступлении сообщения заголовка ответа
Send Request Запускается при отправке сетевого запроса

Событие сценария

мероприятие описывать
Animation Frame Fired Запускается, когда возникает определенный кадр анимации и начинается обработка обратного вызова
Cancel Animation Frame Запускается при отмене кадра анимации
GC Event Срабатывает при сборке мусора
DOMContentLoaded Запускается, когда содержимое DOM на странице загружается и анализируется
Evaluate Script A script was evaluated.
Event js-событие
Function Call Запускается только тогда, когда браузер входит в движок js
Install Timer Запускается при создании таймера (вызываются setTimeout() и setInterval())
Request Animation Frame A requestAnimationFrame() call scheduled a new frame
Remove Timer Запускается, когда таймер очищается
Time Вызовите console.time() для запуска
Time End Вызовите console.timeEnd() для запуска
Timer Fired Запускается после того, как таймер активирует обратный вызов
XHR Ready State Change Запускается, когда асинхронный запрос готов
XHR Load Запускается после завершения загрузки асинхронного запроса.

Рендеринг события

мероприятие описывать
Invalidate layout Запускается, когда изменение DOM делает недействительным макет страницы
Layout Запускается, когда выполняется расчет макета страницы
Recalculate style Запускается, когда Chrome пересчитывает стили элементов
Scroll Запускается при прокрутке встроенного окна просмотра

Событие рисования

мероприятие описывать
Composite Layers Запускается, когда механизм рендеринга Chrome завершает объединение слоев изображения.
Image Decode Запускается после декодирования ресурса изображения
Image Resize Запускается при изменении размера изображения
Paint Запускается после того, как объединенный слой отображается в соответствующей области отображения.