предисловие
В этой статье будет представлено понятие фрейма (Frame) в браузере и на что похож его процесс.
Что касается отправной точки написания этой статьи, мне любопытно, на что похож рабочий процесс пикселя в браузере, когда он начался и каков конечный результат.
Основываясь на этом любопытстве, я ознакомился с некоторыми материалами на иностранном языке.Эта статья содержит некоторые ссылки.Ссылка на ссылку находится в конце статьи.
Недавно я сделал карту разума для оптимизации производительности, которая все еще выводится.кликните сюда
причина
Прежде чем говорить о концепции фреймов, мы должны начать с предыстории, то есть с того, каковы ключевые пути в процессе рендеринга страницы.
Пять критических путей рендеринга
Вывод пикселей на страницу, должно быть, прошел через множество процессов.Как фронтенд-инженеры, на какие моменты мы должны обратить внимание в нашей работе?Вот ссылки:
Мы должны обратить внимание на эти пять основных частей, потому что у нас больше всего контроля. Что касается конкретного процесса каждого процесса, если вам не ясно, вы можете обратиться к следующему рисунку:
Таким образом, в таком пиксельном конвейере каждая часть может вызывать заикание, поэтому нам нужно уделять им особое внимание, в конце концов, если эта часть неправильная, это приведет к ненужным потерям производительности.
Три метода вывода
Мой вопрос в то время был: Всегда ли каждый кадр проходит через обработку каждой части конвейера? На самом деле это не так. С визуальной точки зрения обычно есть три способа запуска конвейера для указанный кадр:
Если мы обновим представление третьим способом, изменив свойство, которое не выложено и не отрисовано, браузер перейдет только к компоновке.
запустить демо
Чтобы более конкретно проверить описанный выше процесс, вы можете запустить демонстрацию, чтобы проверить его.
демонстрационный адрес:Google chrome.GitHub.IO/Инструменты для разработчиков — Посыпать…
Мы добавляем несколько элементов dom для анимации, и эффект становится лучше и очевиднее. Затем мы открываем процесс «Производительность и запись». Нам нужно сосредоточиться на вкладке «Главная», которая является основным потоком. Когда мы приближаем задачу внутри , имеем следующую картину:
Процесс, который я испытал, также очень ясен: Обновить дерево слоев -->> Макет -->> Рисовать -->> Составные слои.
Если вам не совсем понятно значение имени в Performance, вы можете обратиться к следующей статье:кликните сюда:
Далее нажимаем кнопку Оптимизировать, повторяем предыдущий процесс и после Записи обнаруживаем, что что-то не так, и это тот же подэтап.В чем проблема?Мне стало интересно,открыл панель Источники и обнаружил:
Его анимация оптимизации исходного кода использует rAF, и те, кто знает это, не будут незнакомы, вы можете просто понять это: перерисовывать веб-страницу за кадром. Это приводит к понятию фрейма, которое будет объяснено позже.
Подробное введение rAF будет разобрано в будущем, и вы можете продолжать уделять ему внимание.
Как избежать перекомпоновки и перерисовки
Возвращаясь к тому моменту, который мы представили ранее, как мы можем гарантировать, что мы сразу перейдем к процессу синтеза и избежим Layout и Paint?Конечно, нам нужно преобразовать функцию обновления в app.js, используяtransform: translateX(0px);Сделав анимацию, закончив обработку логики функции обновления, снова смотрим запись:
Из подзадачи Task мы можем узнать, чтоLayout -->> Paint, процесс компоновки и рисования пропускается. Вот почему мы часто говорим, что нам нужно избегать перекомпоновки и перерисовки. С точки зрения основного потока, этих процессов можно полностью избежать, и можно избежать больших вычислительных затрат.
Вот почему вы часто видите такие предложения:
- Придерживайтесь изменений свойств преобразования и непрозрачности для анимации.
- использовать
will-change
илиtranslateZ
Поднимите движущиеся элементы.
Что касается использования will-change и translatez для улучшения слоев, это еще один пункт знаний, поэтому я не буду его здесь раскрывать.
Представленные здесь, мы ясно поняли смысл избегать перекомпоновки и перерисовки, затем мы упомянулиРамкаа такжеrAFКакое это имеет отношение к пути рендеринга?
Рамка
Первым делом я погуглил, и Википедия выдала следующее определение:
существуетвидеополе,Фильм,телевидение,цифровое видеоможно рассматривать как ряд изображений, непрерывно меняющихся во времени, гдеРамкаотносится к каждой картинке.
Ну, я не очень хорошо это понимал, пока не нашел эту картинку, она разрешила мое замешательство:
это в самом делеОдна картинка стоит тысячи слов.
По этому рисунку можно понять полный процесс достижения пикселей на экране. Вы, должно быть, очень запутались из-за некоторой критической информации внутри и дайте здесь некоторые пояснения.
Потом большая часть контента переведена, больше не резюмирую, желающие могут посмотреть в оригинале.
ПРОЦЕССЫ (процесс)
Приветственный процесс:
-
Renderer Process: Процесс рендеринга.
- Окружающий контейнер этикетки.
- Он состоит из нескольких потоков, которые совместно отвечают за различные аспекты отображения вашей страницы на экране.
- Эти темысинтетическая нить(Композитор),Поток растеризации плитки(Tile Worker) и основной поток.
-
GPU Process: Процесс графического процессора.
- Это единый процесс, который обслуживает все вкладки и окружающие процессы браузера.
- Когда кадр отправляется, процесс графического процессора загрузит все плитки и другие данные (например, 4D-вершины и матрицы) в графический процессор, чтобы фактически вывести пиксели на экран.
- Процесс GPU содержит один поток, называемый потоком GPU, который фактически выполняет работу.
ПОТОКИ ПРОЦЕССА РЕНДЕРЕРА (потоки в процессе рендерера)
Теперь давайте посмотрим на потоки в процессе визуализации.
-
Compositor Thread(составная тема):
- Это первый поток, который будет уведомлен о событии vsync (именно так ОС говорит браузеру создать новый кадр).
- Он также будет получать любые входные события.
- Поток компоновщика будет избегать входа в основной поток, если это возможно, и попытается преобразовать ввод (скажем, прокрутку) в движение на экране. Это будет сделано путем обновления положения слоя и отправки кадра непосредственно в графический процессор через поток графического процессора.
- Если это невозможно из-за обработчиков событий ввода или другой визуальной работы, вам нужно использовать основной поток.
-
Main Thread(основной поток):
- Именно здесь браузеры выполняют задачи, которые мы все знаем и любим. JavaScript, стилизация, верстка и рисование. (в будущемHoudini, это изменится, и мы сможем запускать некоторый код в потоке Compositor. )
- Эта ветка получила награду «Скорее всего вызывает дерьмо», в основном потому, что здесь происходит много всего. (Jank стоитТрепет страницы)
- Compositor Tile Worker(s) (Поток растеризации составного тайла):
- Один или несколько потоков, производных от потока композиции, для обработки задач растеризации. Мы обсудим это позже.
Во многих отношениях вы должны думать о потоке Compositor как о «большом боссе». Хотя он не запускает JavaScript, Layout, Paint или что-то еще, именно поток полностью отвечает за запуск основного потока и последующую доставку кадра на экран. Если ему не нужно ждать обработчика входных событий, он может отправлять кадры, ожидая, пока основной поток завершит свою работу.
Вы также можете представить Service Workers и Web Workers, живущих в процессе, но я не включил их, потому что это еще больше усложняет ситуацию.
ПОТОК ВЕЩЕЙ (процесс основного потока)
Начнем с основного потока.
Давайте пройдемся по процессу шаг за шагом, от вертикальной синхронизации до пикселей, и поговорим о том, как все работает в «полноценной» версии событий. Стоит помнить, что браузерам не нужно выполнять все эти шаги, в зависимости от того, что необходимо. Например, если нет нового HTML для синтаксического анализа, синтаксический анализ HTML не начнется. На самом деле, во многих случаях лучший способ повысить производительность — просто исключить необходимость запуска некоторых частей процесса!
Также стоит отметить, что красная стрелка в разделе «Стили и макет», по-видимому, указывает наrequestAnimationFrame. В вашем коде вполне возможно случайное срабатывание обоих. Это называется макетом с принудительной синхронизацией (или стилем, в зависимости от обстоятельств), и обычно это плохо сказывается на производительности.
-
Frame Start(начать новый кадр):
-
Сигнал вертикальной синхронизации запускается, чтобы начать рендеринг нового кадра изображения.
-
-
Input event handlers(Обработка входных событий).
-
- Входные данные передаются из потока компоновщика любым обработчикам входных событий в основном потоке.
-
Все обработчики событий ввода (касание, перемещение, прокрутка, щелчок) должны срабатывать первыми, один раз за кадр, но это не обязательно.
-
Планировщик делает все возможное, и вероятность успеха зависит от операционной системы. Также существует некоторая задержка между взаимодействием с пользователем и поступлением события в основной поток для обработки.
-
-
requestAnimationFrame
:-
Это идеальное место для визуальных обновлений на экране, так как у вас есть свежие входные данные, и это самое близкое к вертикальной синхронизации место.
-
Другие задачи видения, такие как расчет стиля, выполняются после этой задачи, поэтому ее идеальное местонахождение — мутирующий элемент.
-
Если вы измените, скажем, 100 классов, это не приведет к 100 расчетам стилей, они будут объединены в пакеты и обработаны позже. Единственное предостережение заключается в том, что вы не запрашиваете никакие вычисляемые свойства стиля или макета (например, el.style.backgroundImage или el.style.offsetWidth).
-
Если вы сделаете это, вы выдвинете пересчитанные стили, макеты или и то, и другое, что приведет к вынужденным синхронным макетам или, что еще хуже, к загроможденным макетам.
-
-
Parse HTML (Разобрать HTML):
-
Любой вновь добавленный HTML обрабатывается и создаются элементы DOM.
-
Вы можете увидеть больше этого во время загрузки страницы или после таких действий, как appendChild.
-
-
Recalc Styles(Пересчитать стили):
-
Стили рассчитываются для всего, что было добавлено или изменено, это может быть все дерево или диапазон, в зависимости от того, что изменилось.
-
Это может быть все дерево или уменьшение объема, в зависимости от того, что было изменено.
-
Например, изменение класса тела может иметь далеко идущие последствия, но стоит отметить, что браузеры очень умны, чтобы автоматически ограничивать объем вычислений стилей.
-
-
Layout(рисовать):
-
Рассчитайте геометрическую информацию (положение и размер каждого элемента) каждого видимого элемента. Обычно он выполняет вычисления по всему документу, обычно делая стоимость вычислений пропорциональной размеру DOM.
-
-
Update Layer Tree(Обновите дерево слоев):
- Процесс создания контекстов наложения и элементов сортировки по глубине.
-
Paint:
- Это первая часть процесса, состоящего из двух частей: Рисование — это вызов отрисовки, который записывает любые новые или визуально изменяющиеся элементы (заполнение прямоугольника здесь, запись текста там).
- Вторая часть — растеризация (см. ниже), при которой выполняются вызовы отрисовки и заполняются текстуры. Эта часть представляет собой запись вызовов отрисовки и обычно выполняется намного быстрее, чем растеризация, но эти две части часто вместе называются «рисованием».
-
Composite(синтез):
-
Информация о слоях и тайлах вычисляется и передается обратно в поток компоновщика для обработки.
-
Это будет учитывать, среди прочего, такие вещи, как изменение, перекрывающиеся элементы и любые холсты с аппаратным ускорением.
-
-
Raster Scheduled(Планирование растеризации) а такжеRasterize(Растрированный):
-
Вызовы отрисовки, записанные в задаче Paint, теперь выполняются. Это делается в Compositor Tile Workers, количество которых зависит от возможностей платформы и устройства.
-
Например, на Android вы обычно найдете одного работника, на десктопе иногда бывает четыре. Растеризация выполняется слоями, и каждый слой состоит из тайлов.
-
-
Конец кадра:
-
Когда тайлы для каждого слоя растеризованы, все новые тайлы передаются потоку графического процессора вместе с входными данными (которые могли быть изменены в обработчике событий).
-
-
Frame Ships(отправить кадр):
- И последнее, но не менее важное: тайлы загружаются в GPU потоком GPU. Графический процессор использует квадраты и матрицы (все обычные возможности GL) для отрисовки тайлов на экране.
В общем, весь процесс описан выше.
requestIdleCallback
Сказать это, мы должны взятьrequestAnimationFrameДля аналогии, requestAnimationFrame перерисовывает экран.ДоИсполнение вышеупомянутого RAF, то делают оптимизацию анимации, поэтому он подходит для анимации.
Если вы ищете requestIdleCallback через Task в основном потоке, вы обнаружите, что он рендерит экранПозжеИсполнение, найденное по консультированию статьи, обычно зависит от того, является ли браузер бездействовать.
Там, где место ограничено, вы хотите это понять, тогда и порекомендуйтестатья:
Суммировать
Я недавно просмотрел иностранную литературу и обнаружил, что есть слишком много вещей, чтобы учиться.Если эта статья неправильно написана или переведена, пожалуйста, укажите.
Исходный начальный адрескликните сюда, Добро пожаловать в публичный аккаунт "TianTianUp".
Я тяньтянь, мы увидим следующий период! ! !
Ссылаться на
[1] w3c-longTasks: GitHub.com/my3from/длинный диван…
[2] chrome-fps-meter: developer.chrome.com/docs/Dev тоже…
[3] devtools-samples: Google chrome.GitHub.IO/Инструменты для разработчиков — Посыпать…
[4] Analyze runtime performance: developer.chrome.com/docs/Dev тоже…
[5] Timeline Event Reference: developer.chrome.com/docs/Dev тоже…
[6] The Anatomy of a Frame: aero twist.com/blog/ он и-пресс…
[7] performance-rendering: Developers.Google.com/Web/Женщины большие…
[8] Википедия: zh.wikipedia.org/wiki/