Как увеличить плавность анимации в бг
Перейти к содержимому

Как увеличить плавность анимации в бг

  • автор:

Редактирование анимации движения с помощью Редактора движения

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

Редактор движения

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

Зачем нужен редактор движения?

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

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

Вызов панели «Редактор движения»

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

Для открытия редактора движения выполните указанные ниже действия.

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

Кривые свойств

Редактор движения представляет свойства анимации движения с использованием двухмерных графиков, которые называются кривыми свойств. Эти графики строятся по сетке в редакторе движения. Для каждого свойства строится отдельная кривая, причем время представлено горизонтальной осью (слева направо), а изменение значения свойства — вертикальной осью.

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

Обратите внимание, что редактор движения позволяет изменять только такие свойства, которые можно корректировать во время диапазона анимации движения. Например, свойству «Качество» фильтра «Градиентная фаска» может быть присвоено только одно значение в пределах диапазона анимации движения, поэтому его нельзя изменять в редакторе движения.

Узловые точки

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

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

Контрольные точки

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

Редактирование кривых свойств

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

  1. В Animate выберите диапазон анимации движения, щелкните его правой кнопкой мыши > выберите Уточнить анимацию , чтобы вызвать редактор движения (или просто дважды щелкните выбранный диапазон анимации движения).
  2. Прокрутите вниз и выберите свойство, которое требуется изменить. Чтобы инвертировать выделение, щелкните его правой кнопкой мыши и выберите пункт «Инвертировать выделение».
  3. Когда в области просмотра находится кривая выбранного свойства, можно выполнить одно из следующих действий.
    1. Добавьте узловую точку, нажав кнопку и щелкнув на кривой свойства кадр, в котором нужно добавить узловую точку. Или дважды щелкните кривую, чтобы добавить узловую точку.
    2. Выберите и переместите существующую узловую точку в нужный кадр на сетке (в любом направлении). Предел перемещения по вертикали определяется диапазоном значений свойства.
    3. Удалите узловую точку, выделив ее и нажав клавиши Ctrl + Click (Cmd + щелчок на компьютере MAC).

Редактирование кривых свойств с помощью контрольных точек

Для редактирования кривых свойств с помощью контрольных точек выполните следующие действия.

  1. В Animate выберите диапазон анимации движения, щелкните его правой кнопкой мыши > выберите Уточнить анимацию , чтобы вызвать редактор движения (или дважды щелкните выбранный диапазон анимации движения).
  2. Прокрутите вниз и выберите свойство, которое требуется изменить. Чтобы инвертировать выделение, щелкните его правой кнопкой мыши и выберите пункт «Инвертировать выделение».
  3. Когда в области просмотра находится кривая выбранного свойства, можно выполнить одно из следующих действий.
    1. Добавьте узловую точку, нажав кнопку и щелкнув в сетке кадр, в котором нужно добавить узловую точку.Или дважды щелкните кривую, чтобы добавить узловую точку.

    Копирование кривых свойств

    В редакторе движения можно копировать кривые свойств от одного свойства к другому.

    Чтобы копировать кривую свойства, выполните следующие действия.

    1. В Animate выберите диапазон анимации движения, щелкните его правой кнопкой мыши > выберите Уточнить анимацию , чтобы вызвать редактор движения (или дважды щелкните выбранный диапазон анимации движения).
    2. Выберите свойство, кривую которого требуется копировать, затем щелкните его правой кнопкой > выберите Копировать ИЛИ нажмите клавиши Ctrl + C (Cmd + C на компьютере MAC).
    3. Чтобы поместить кривую в нужный диапазон с абсолютными значениями, выберите свойство, в которое требуется вставить скопированную кривую, затем щелкните его правой кнопкой мыши > выберите Вставить или нажмите клавиши Ctrl + V (Cmd + V на компьютере Mac).
    4. Чтобы поместить кривую в диапазон целевой кривой, выберите свойство, в которое требуется вставить скопированную кривую, затем щелкните его правой кнопкой мыши > выберите «Вставить с учетом текущего диапазона» .

    Обращение кривой свойства

    Чтобы обратить кривую свойства, выполните следующие действия.

    1. В редакторе движения выберите свойство.
    2. Щелкните его правой кнопкой мыши > выберите В обратном направлении , чтобы обратить кривую свойств.

    Применение набора настроек и пользовательского замедления

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

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

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

    Пользовательские настройки замедления

    В редакторе движения можно создавать собственное замедление с помощью кривой «Пользовательское замедление». Затем такое замедление можно применить к любому свойству в выбранной анимации движения.

    График пользовательского замедления представляет величину движения на протяжении времени. Кадры представлены на горизонтальной оси, а процент изменения анимации движения представлен на вертикальной оси. Первое значение анимации находится на уровне 0 %, а для последнего кадра можно задать значение от 0 до 100 %. Скорость изменения экземпляра анимации движения выражается наклоном кривой. Если на графике создается горизонтальная линия (без наклона), то скорость равна нулю. Если на графике создается вертикальная линия, то скорость изменения мгновенна.

    Применение кривой замедления к кривой свойства

    Чтобы добавить замедление в свойство анимации, выполните следующие действия.

    1. В редакторе движения выберите свойство, к которому требуется применить замедление, и нажмите кнопку Добавить замедление , чтобы вызвать панель «Замедление».
    2. На панели «Замедление» можно выполнить следующие действия:
      1. Примените стандартное замедление, выбрав набор настроек на левой панели. Укажите интенсивность замедления, задав значение в поле «Замедление».
      2. Создайте собственное замедление, выбрав вариант «Пользовательское замедление» на левой панели и изменив кривую замедления. Дополнительные сведения см. в разделе Создание и применение пользовательских кривых замедления.

      Создание и применение пользовательских кривых замедления

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

      1. В редакторе движения выберите свойство, к которому требуется применить пользовательское замедление, и нажмите кнопку «Добавить замедление», чтобы вызвать панель «Замедление».
      2. На панели «Замедление» можно изменить пользовательскую кривую замедления по умолчанию, выполнив следующие действия.
        1. Щелкните кривую, удерживая клавишу Alt, чтобы добавить на нее узловые точки. Затем можно перемещать эти точки в любое место на сетке.
        2. Активируйте контрольные точки (щелкните узловую точку, удерживая клавишу Alt), чтобы сгладить сегменты по обеим сторонам от узловой точки.

        Копирование кривых замедления

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

        1. На панели «Замедление» выберите кривую замедления, которую требуется копировать, и нажмите клавиши Ctrl + C (Cmd + C на компьютере MAC).
        2. Выберите свойство, в которое требуется вставить скопированную кривую замедления, затем нажмите клавиши Ctrl + V (Cmd + V на компьютере MAC).

        Применение замедления к нескольким свойствам

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

        Обратите внимание, что после применения замедления к группе свойств можно также редактировать подсвойства по отдельности. Это также означает, что можно применить к подсвойству замедление, отличное от примененного к группе.

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

        1. В редакторе движений выделите группу свойств и нажмите кнопку «Добавить замедление» для отображения панели «Замедление».
        2. На панели «Замедление» выберите набор настроек замедления или создайте пользовательское замедление. Щелкните любое место за пределами панели «Замедление», чтобы применить выбранное замедление к группе свойств.

        Результирующая кривая

        Когда к кривой свойства применяется кривая замедления, отображается визуальное наложение, которое называется результирующей кривой. Результирующая кривая является точным представлением эффекта замедления, примененного к кривой свойства. Она позволяет судить о конечном виде анимации движения объекта. Результирующая кривая помогает понять, как будет выглядеть эффект в рабочей области при тестировании анимации.

        Управление отображением редактора движения

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

        • В новом редакторе движения отображаются только те свойства, которые применены к анимации движения.
        • Можно использовать переключатель «Подгонка к виду» (), чтобы подогнать область редактора движения по ширине временной шкалы.
        • Можно настроить размер области редактора движения и выбрать меньше () или больше () отображаемых кадров с помощью элементов управления для изменения масштаба временной шкалы. Также можно использовать ползунок для настройки вида редактора движения.
        • В редакторе движения также предусмотрен переключатель для изменения масштаба по вертикали. Функцию изменения масштаба по вертикали также можно использовать для отображения подходящего диапазона значений свойств в редакторе движения. Увеличение масштаба также позволяет вносить более точные и целенаправленные изменения в кривую свойства.
        • По умолчанию свойства отображаются в развернутом виде на левой панели редактора движения. Однако детализированный список можно свернуть, щелкнув имя свойства.

        Комбинации клавиш

        Двойной щелчок кривой свойства для добавления узловой точки.

        Alt+перетаскивание узловой точки для активации контрольных точек.

        Alt+перетаскивание для изменения выбранной контрольной точки (одностороннее редактирование).

        Alt-щелчок узловой точки для деактивации контрольных точек (угловых точек).

        Shift+перетаскивание для линейного перемещения узловой точки.

        Command/Control+щелчок для удаления узловой точки.

        Клавиши со стрелками вверх и вниз для перемещения выбранной узловой точки по вертикали.

        Command/Control+C/V для копирования и вставки выбранной кривой.

        Command/Control+R для обращения выбранной кривой.

        Command/Control+прокручивание для увеличения или уменьшения масштаба.

        Скорость

        При анимации свойства в редакторе диаграмм можно просмотреть и изменить скорость изменения свойства в на диаграмме скорости. Можно также настроить скорость для пространственных свойств на пути движения на панели «Композиция» или «Слой».

        На панели «Композиция» или «Слой» расстояние между точками на пути движения означает скорость. Каждая точка представляет кадр на основании частоты кадров композиции. Равномерные промежутки означают постоянную скорость, а более широкие промежутки — более высокую скорость. У ключевых кадров с интерполяцией нулевого порядка нет точек, так как между значениями ключевых кадров нет промежуточного перехода. Слой просто отображается в положении, указанном следующим ключевым кадром. (См. раздел Пути движения.)

        Управление скоростью между ключевыми кадрами: сравнение пути движения на панели «Композиция» (вверху) с диаграммой скорости в редакторе диаграмм (внизу)

        A. Точки находятся ближе друг к другу, что означает более низкую скорость (вверху). Скорость постоянная (внизу). B. Точки находятся далеко друг от друга, что означает более высокую скорость (вверху). Скорость постоянная (внизу). C. Разное расстояние между точками указывает на изменение скорости (вверху). Скорость уменьшается, а затем увеличивается (внизу).

        Сведения об интерполяции ключевого кадра см. в разделе Интерполяция ключевого кадра.

        Ниже перечислены факторы, влияющие на скорость, при которой изменяется значение свойства.

        • Разница во времени между ключевыми кадрами на панели «Таймлайн». Чем короче промежуток времени между ключевыми кадрами, тем быстрее происходит изменение слоя для достижения значения следующего ключевого кадра. Если промежуток больше, слой изменяется медленнее, потому что изменение должно произойти за более длинный период времени. Скорость изменения можно настроить, переместив ключевые кадры вперед или назад на таймлайне.
        • Различие между значениями соседних ключевых кадров. При большой разнице между значениями ключевых кадров, например 75 % и 20 % для непрозрачности, изменение происходит более быстро, чем при небольшой разнице, например в 30 % и 20 % для непрозрачности. Скорость изменения можно настроить, увеличив или уменьшив значение свойства слоя в ключевом кадре.
        • Тип интерполяции, примененный к ключевому кадру. Например, если для ключевого кадра задана линейная интерполяция, значение будет трудно изменить плавно. Но можно в любое время переключиться на интерполяцию по кривой Безье, которая обеспечивает плавное изменение в ключевом кадре. При использовании интерполяция по кривой Безье можно более точно настроить скорость изменения с помощью дескрипторов направления.

        Линейная интерполяция (вверху) дает более резкие изменения, а интерполяция по кривой Безье (внизу) — более плавные изменения

        Управление скоростью между ключевыми кадрами без использования диаграммы скорости

        • На панели «Композиция» или «Слой» отрегулируйте пространственное расстояние между двумя ключевыми кадрами на пути движения. Чтобы увеличить скорость, перетащите ключевой кадр дальше от другого кадра, чтобы уменьшить скорость перетащите ключевой кадр ближе к другому кадру.

        Чем больше расстояние в пространстве между ключевыми кадрами, тем выше скорость слоя

        • В режиме панели «Слой» или в редакторе диаграмм отрегулируйте разницу во времени между двумя ключевыми кадрами. Чтобы уменьшить скорость, перетащите ключевой кадр дальше от другого кадра, чтобы увеличить скорость перетащите ключевой кадр ближе к другому кадру.

        Чем меньше расстояние во времени между ключевыми кадрами, тем выше скорость слоя

        • Задействуйте помощник в работе с ключевыми кадрами «Плавное замедление», который автоматически регулирует скорость изменения по мере приближения к ключевому кадру и удалению от него.

        Сведения о диаграмме скорости

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

        Изменение высоты диаграммы скорости указывает на изменение скорости. Горизонтальные значения означают постоянную скорость, более высокие значения означают увеличенную скорость.

        Чтобы открыть диаграмму скорости, выберите в меню «Выберите тип диаграммы» команду «Изменить диаграмму скорости» .

        Элементы управления диаграммы скорости

        A. Значение в точке индикатора текущего времени B. Диаграмма скорости C. дескриптор направления (управляет скоростью)

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

        дескрипторы направления на диаграммах скорости

        A. Входящий дескриптор направления B. Управление скоростью C. Исходящий дескриптор направления

        Примечание.

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

        Анимации на GPU: делаем это правильно

        Думаю, все уже знают, что современные браузеры умеют рисовать некоторые части страницы на GPU. Особенно это заметно на анимациях. Например, анимация, сделанная с помощью CSS-свойства transform выглядит гораздо приятнее и плавнее, чем анимация, сделанная через top/left . Однако на вопрос «как правильно делать анимации на GPU?» обычно отвечают что-то вроде «используй transform: translateZ(0) или will-change: transform ». Эти свойства уже стали чем-то вроде zoom: 1 для IE6 (если вы понимаете, о чём я 😉 для подготовки слоя для анимации на GPU или композиции (compositing), как это предпочитают называть разработчики браузеров.

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

        One big disclaimer

        Самое важное, что хочется сказать прежде, чем мы приступим к изучению деталей GPU-композиции: это всё один огромный хак. Вы не найдёте в спецификациях W3C (по крайней мере пока) описания процесса GPU-композиции, способов явного переноса элемента на отдельный слой или даже самого режима композиции. Это всего лишь способ ускорить некоторые типовые задачи и каждый разработчик браузеров делает это по-своему. Всё, что вы прочитаете в этой статье — ни в коем случае не официальное объяснение, а результаты экспериментов и наблюдений, приправленных здравым смыслом и знаниями о работе некоторых подсистем браузера. Что-то может оказаться неправдой, а что-то изменится со временем — я вас предупредил!

        Как работает композиция

        Чтобы правильно подготовить страницу к GPU-анимации, очень важно не столько следовать советам, найденным интернете или в этой статье, сколько понимать, как это работает внутри браузера.

        Предположим, у нас есть страница с элементами A и B , у которых указано position: absolute и разный z-index . Браузер отрисует всю страницу на CPU, отправит полученное изображение на GPU, а оттуда оно попадёт к нам на экран.

         #a, #b < position: absolute; >#a < left: 30px; top: 30px; z-index: 2; >#b 
        A
        B

        example 1

        Мы решили анимировать перемещение элемента A через CSS-свойство left c помощью CSS Animations:

          
        A
        B

        В этом случае на каждый кадр анимации браузер со стороны CPU пересчитывает геометрию элементов (reflow), отрисовывает новое изображение с актуальным состоянием страницы (repaint), так же отправляет его на GPU, после чего оно отображается на экране. Мы знаем, что repaint — довольно дорогая операция, однако все современные браузеры достаточно умны, чтобы перерисовывать не всё изображение целиком, а только изменившиеся части. И делают они это достаточно быстро, но анимациям всё равно не хватает плавности.

        Пересчёт геометрии и перерисовка, хоть и частичная, всей страницы на каждый шаг анимации: выглядит как очень трудоёмкая операция, особенно на больших и сложных сайтах. Гораздо эффективнее было бы один раз нарисовать два изображения: элемент A и саму страницу без элемента A , а потом просто перемещать эти изображения друг относительно друга. Иначе говоря, нужно делать композицию закэшированных изображений элементов. И именно с такой задачей лучше всего справляется GPU. Более того, он умеет это делать с субпиксельной точностью, что и придаёт ту самую плавность анимации.

        Чтобы применить оптимизацию с композицией, браузер должен быть уверен, что анимируемые CSS-свойства:

        1. никак не влияют на поток документа;
        2. никак не зависят от потока документа;
        3. не потребуют перерисовки самого элемента.

        Со стороны может показаться, что свойства top и left вместе с position: absolute/fixed не зависят от внешних факторов, но это не так. Например, свойство left может принимать значения в процентах, которые зависят от размера .offsetParent , а также единицы em , vh и т.д., которые зависят от окружения. Поэтому именно CSS-свойства transform и opacity подходят под описание.

        Переделаем нашу анимацию: вместо left будем анимировать transform :

          
        A
        B

        Обратите внимание на код. Мы декларативно описали всю анимацию: её начало, конец, длительность и т.д. А это позволяет браузеру ещё до начала анимации определить, какие именно CSS-свойства элемента будут меняться. Увидев, что среди этих свойств нет тех, что влияют на reflow/repaint, браузер может применить оптимизацию с композицией: нарисовать два изображения и передать их GPU.

        Преимущества такой оптимизации:

        • Очень плавная анимация с субпиксельным сглаживанием: ей теперь занимается графический процессор, специально оптимизированный под такие задачи.
        • Анимация не зависит от CPU: даже если в этот момент мы будем выполнять очень интенсивные вычисления, анимация попрежнему будет плавной, так как выполняется полностью на GPU.

        Казалось бы, всё просто и понятно, какие могут возникнуть проблемы? Давайте рассмотрим, что на самом деле делает такая оптимизация.

        Возможно, для некоторых это будет открытием, но GPU является отдельным компьютером. Да-да, неотъемлемая часть всех современных устройств на самом деле является самостоятельной подсистемой со своими процессорами, памятью и способами обработки информации. И браузер, как и любая другая программа или игра, вынужден общаться с GPU именно как с отдельным устройством.

        Чтобы лучше понять это, просто вспомните AJAX. Например, вам нужно зарегистрировать пользователя по данным, которые он ввёл в форме авторизации. Вы не можете сказать удалённому серверу «эй, возьми данные из вот этих полей и ещё вон ту переменную и сохрани их в базе», потому что у сервера нет доступа к памяти браузера. Вместо этого вы собираете необходимые данные со страницы в некую полезную нагрузку с простым форматом данных (например, JSON) и отправляете её на сервер.

        То же самое происходит и во время композиции. Так как GPU, по сути, является удалённым сервером, браузер со стороны CPU вынужден сначала подготовить специальную полезную нагрузку, а затем отправить её на устройство. Да, GPU находится совсем рядом c CPU, однако если 2 секунды на отправку и получение ответа через AJAX зачастую являются вполне приемлемыми, то лишние 3–5 миллисекунд на передачу данных на GPU могут серьёзно ухудшить качество анимации.

        Что из себя представляет полезная нагрузка для GPU? Как правило, это изображения слоёв и дополнительные инструкции, которые определяют размеры слоёв, их расположение друг относительно друга, инструкции для анимации и т.д. Вот как приблизительно выглядит процесс создания нагрузки и её передачи на GPU:

        • Отрисовка каждого композитного слоя в отдельное изображение.
        • Подготовка данных о слоях (расположение, размер, прозрачность и т.д.).
        • Подготовка шейдеров для анимации (если используется CSS Transitions или Animations).
        • Отправка данных на GPU.

        Таким образом, каждый раз, когда вы добавляете магическое transform: translateZ(0) или will-change: transform элементу, вы запускаете весь это процесс. Вы уже знаете, что repaint является достаточно ресурсоёмкой задачей. Но в данном случае всё ещё хуже: довольно часто браузер не может применить инкрементальный repaint и перерисовать только изменившуюся часть. Он должен заново отрисовать те части, которые были скрыты новым слоем:

        example 3

        Неявная композиция

        Давайте вернёмся к нашему примеру с элементами A и B . Ранее мы анимировали элемент A , который находится поверх всех остальных элементов на странице. В результате получили композицию из двух слоёв: слой с A и слой с B и фоном страницы.

        А теперь поменяем задачу: будем анимировать элемент B …

        …и у нас возникает логическая проблема. Элемент B должен быть на отдельном композитном слое, финальная композиция изображения, которое увидит пользователь, происходит на GPU. Но элемент A , который мы вообще никак не трогаем, визуально должен находиться поверх элемента B .

        Вспоминаем One Big Disclaimer — в CSS нет специального режима для GPU-композиции, это просто оптимизация для решения специфических задач. Мы должны получить элементы A и B именно в том порядке, который был задан через z-index . Как в этом случае должен поступить браузер?

        Совершенно верно: он перенесёт элемент A на отдельный композитный слой! Добавив тем самым ещё один тяжёлый repaint:

        Это называется неявная композиция: один или несколько не-композитных элементов, которые по z-index находятся выше композитного элемента, также становятся композитными, то есть отрисовываются в отдельное изображение, которое затем отправляется на GPU.

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

        • 3D-трансформации: translate3d , translateZ и т.д.
        • Элементы , , .
        • Анимация transform и opacity через Element.animate() .
        • Анимация transform и opacity через СSS Transitions и Animations.
        • position: fixed .
        • will-change .
        • filter .

        Подробнее можете посмотреть в файле CompositingReasons.h проекта Chromium.

        На первый взгляд может показаться, что главная проблема у GPU-анимаций — неожиданные тяжёлые repaint. Но это не так. Самой большой проблемой является…

        Потребление памяти

        И вновь вспоминаем, что GPU — это отдельный компьютер. Отрисованные изображения слоёв нужно не только передать на GPU, но и хранить там, чтобы потом красиво анимировать.

        Сколько весит изображение одного слоя? Давайте рассмотрим пример. Попробуйте угадать размер обычного прямоугольника, размером 320×240, залитого сплошным цветом #ff0000 .

        rect

        Обычно веб-разработчики думают так: «это одноцветное изображение… сохраню-ка я его в PNG и проверю размер, должен быть меньше килобайта». И будут правы: это изображение действительно весит всего 104 байта в PNG.

        Но проблема в том, что PNG (как и JPEG, GIF и т.д.) — это формат хранения и передачи данных. Чтобы отрисовать такое изображение на экране, компьютер должен распаковать его и представить в виде массива пикселей. Таким образом, наше изображение в памяти компьютера будет занимать 320×240×3 = 230 400 байт. То есть мы умножаем ширину изображения на его высоту — так мы получим количество пикселей. Затем количество пикселей умножаем на 3, так как цвет каждого пикселя описывается 3-мя байтами: RGB. Если бы изображение было полупрозрачным, мы бы умножили на 4, так как нужен ещё один байт для описания значения прозрачности (RGBA): 320×240×4 = 307 200 байт.

        Браузер всегда отрисовывает композитные слои в RGBA-изображения: судя по всему, нет достаточно быстрого и эффективного способа автоматически определить, есть ли у отрисовываемого DOM-элемента прозрачные области.

        Рассмотрим типичный пример: карусель из 10 фотографий размером 800×600. Вы решили сделать плавную смену изображений в карусели, поэтому заранее каждой фотографии указали will-change: transform , а потом с помощью JS анимируете переходы на действие пользователя, например, перетаскивание. Посчитаем, сколько дополнительной памяти потребуется, чтобы просто отобразить такую страницу: 800×600×4 × 10 ≈ 19 МБ.

        19 МБ дополнительной памяти потребовалось для отрисовки всего лишь одного контрола на странице. А учитывая любовь современных разработчиков к SPA-страницам с множеством анимированных контролов, параллакс-эффектам, retina-изображениям и прочим визуальным штукам, дополнительные 100–200 МБ на страницу — далеко не предел. Добавьте сюда неявную композицию (признайтесь, вы ведь об этом раньше даже не задумывались? 🙂 и мы получим совсем печальную картину.

        Причём, довольно часто эта дополнительная память расходуется впустую, просто для отображения точного такого же результата:

        example 5

        И если для десктопных клиентов это ещё не так сильно заметно, то для мобильных устройств эта проблема стоит особенно остро. Во-первых, практически на всех современных устройствах используются экраны c высокой плотностью пикселей: умножаем изображения слоёв ещё на 4–9. Во-вторых, на таких устройствах довольно мало памяти, по сравнению с десктопами. Например, у ещё-не-такого-старого iPhone 6 всего 1 ГБ памяти, причём она общая для RAM и VRAM (память для GPU). Учитывая, что в лучшем случае треть этой памяти будет использоваться самой системой и фоновыми процессами, ещё треть — на браузер и текущую страницу (и это при условии, что вы не пользуетесь десятком фрэймворков и очень сильно всё оптимизируете), то для GPU-спецэффектов останется порядка 200—300 МБ. Причем, iPhone 6 относится к дорогим high-end устройствам, на более доступных устройствах памяти гораздо меньше.

        У вас может возникнуть резонный вопрос: а можно ли на GPU хранить картинки в формате PNG, чтобы сэкономить память? Да, технически это возможно, однако особенность работы GPU такова, что каждый слой рисуется попиксельно. А это означает, что для отрисовки одного пикселя на экране нужно будет каждый раз заново декодировать PNG-изображение, чтобы получить нужный цвет. В таком случае скорость самой простой анимации вряд ли будет подниматься выше 1 fps.

        Стоит отметить, что на GPU существуют свои форматы сжатия изображений, однако они даже близко не сравнимы с PNG или JPEG по степени сжатия, а возможность их применения в том числе ограничена поддержкой самого GPU.

        За и против

        Теперь, когда мы рассмотрели теоретическую часть работы анимаций на GPU, давайте для удобства соберём все «за» и «против» их использования.

        За

        • Очень плавные анимации с субпиксельной точностью и скоростью в 60 fps.
        • Правильно сделанные анимации работают в отдельном потоке и не блокируются тяжелыми JS-операциями.
        • «Дешёвые» 3D-преобразования.

        Против

        • Для выноса элемента на композитный слой требуется дополнительный repaint, иногда он может быть очень медленным (полная отрисовка элемента вместо инкрементальной).
        • Отрисованный слой нужно передать на GPU: чем больше слоёв и чем больше их размер, тем больше времени требуется на передачу. На средних и слабых мобильных устройствах можно заметить «моргание», когда элемент пропадает и тут же появляется.
        • Каждый композитный слой занимает дополнительную память. Память — очень ограниченный ресурс на мобильных устройствах. Чрезмерное потребление памяти может привести к крэшу браузера!
        • Неявная композиция: если не следить за ней, увеличивается время на repaint, потребление памяти и шансы «уронить» браузер.
        • Визуальные артефакты: отрисовка текста в Safari, исчезающие или искажённые фрагменты страницы.

        Как видите, при всех своих уникальных достоинствах, у GPU-анимации есть ряд очень существенных недостатков, главные из которых — repaint и потребление памяти. Поэтому все наши оптимизации как раз будут связаны именно с этими двумя пунктами.

        Настраиваем окружение

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

        Safari

        В Safari Web Inspector встроен отличный инструмент, который позволяет увидеть все композитные слои на странице, потребляемую ими память, а также — что не менее ценно — показать причину выноса элемента на отдельный слой. Чтобы увидеть этот инструмент:

        1. В Safari откройте Web Inspector c помощью ⌘⌥I. Если не получается, попробуйте в Preferences > Advanced включить опцию Show Develop Menu in menu bar и попробовать снова.
        2. В Web Inspector откройте вкладку Elements и в правой колонке выберите пункт Layers.
        3. Теперь, когда вы будете кликать по элементам в основной части вкладки Elements, справа вы увидите информацию о композитном слое для этого элемента (если он есть), а также список всех дочерних элементов со своими слоями.
        4. Если кликнуть по дочернему слою, то отобразится причина композиции — почему браузер решил вынести элемент на отдельный композитный слой.

        Safari with Web Inspector

        Google Chrome

        В DevTools также есть похожий инструмент, однако для его включения нужно выставить специальный флаг:

        Chrome with DevTools

        1. В браузере перейдите на chrome://flags/#enable-devtools-experiments и включите флаг Developer Tools experiments.
        2. Откройте DevTools с помощью ⌘⌥I (Mac) или Ctrl-Shift-I (PC), нажмите на иконку в правом верхнем углу и перейдите в раздел Settings.
        3. Выберите раздел Experiments в меню и включите Layers panel.
        4. Закройте и снова откройте DevTools: вам будет доступна панель Layers.

        Chrome with DevTools

        В этой панели отображаются все активные композитные слои страницы в виде дерева. Если выбрать слой, будет доступна информация о нём: размер, объем занимаемой памяти, количество перерисовок, а также причина выноса на композитный слой.

        Оптимизация

        Итак, мы настроили окружение и теперь можем приступить непосредственно к оптимизации. Мы уже определили две основные проблемы с использованием композитных слоёв: лишний repaint, после которого изображение слоя нужно передать на GPU, и потребление памяти. Поэтому все наши оптимизации будут направлены на сокращение циклов перерисовки и снижение потребления памяти.

        Избегайте неявной композиции

        Очень простая, очевидная, но самая важная оптимизация. Напомню, что неявная композиция — это вынос на отдельный композитный слой элементов только для того, чтобы правильно скомпоновать его на GPU с другим, явным композитным слоем (видео, CSS анимация и т.д.). Особенно сильно эта проблема может ощущаться на мобильных устройствах при старте анимации.

        Рассмотрим небольшой пример.

        У нас есть элемент A , который мы хотим анимировать по действию пользователя. Если посмотреть на страницу с помощью инструмента Layers, мы увидим, что на ней нет никаких дополнительных слоёв. Однако сразу после нажатия на кнопку Play появится несколько композитных слоёв, которые исчезнут к концу анимации. Если посмотреть на инструмент Timeline, будет видно, что начало и конец анимации сопровождаются repaint значительных областей страницы:

        Chrome timeline

        Давайте рассмотрим пошагово, что сделал браузер в этом примере.

        1. Как только мы загрузили страницу, браузер не нашёл никаких признаков для дополнительной композиции, поэтому нарисовал всё содержимое страницы на одном единственном слое. Это — самое эффективное и наименее затратное с точки зрения ресурсов отображение страницы.
        2. После нажатия на Play мы добавили признак композиции элементу A — CSS Transition свойства transform . Однако браузер определил, что по z-index элемент A находится ниже элемента B . Поэтому он принимает решение вынести оба элемента на отдельные композитные слои.
        3. Вынос элемента на композитный слой всегда сопровождается repaint. Во-первых, нужно создать отдельное изображение-текстуру самого элемента, а во-вторых — удалить этот элемент из предыдущего слоя. В нашем случае этим слоем был основной холст страницы.
        4. Отрисованные изображения слоёв нужно отправить на GPU, где уже и будет произведена финальная композиция изображения страницы, которое видит пользователь. В зависимости от размеров слоёв, их количества и сложности внутреннего содержимого, перерисовка и отправка слоёв на GPU может занимать значительное время. Именно поэтому иногда можно наблюдать «моргание» в начале или конце анимации: фрагменты страницы пропадают и через некоторое время вновь появляются.
        5. После завершения анимации мы удаляем признак композиции у элемента A . В этом случае браузер понимает, что больше нет смысла тратить драгоценные ресурсы на содержание элементов на отдельных слоях, поэтому он возвращается к самому оптимальному варианту – отображение элементов A и B на основном холсте. А это значит, что элементы нужно заново отрисовать на нём (ещё один repaint) и отправить полученное изображение на GPU. Этот процесс так же, как и в п.4, может сопровождаться «морганием».

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

        • Старайтесь держать анимируемые объекты как можно выше по z-index . В идеале эти объекты должны находится прямо внутри . Конечно же, это не всегда возможно из-за особенностей вёрстки, когда анимируемый элемент находится глубоко в DOM-дереве и зависит от потока. В таких случаях можно создавать копию элемента, который нужно анимировать, и размещать его прямо в .
        • Можно заранее подсказать браузеру, что вы собираетесь использовать композицию, с помощью CSS-свойства will-change . В этом случае браузер может заранее (но не всегда!) вынести элемент на композитный слой и анимация всегда будет начинаться быстро. Этим свойством стоит пользоваться очень аккуратно, иначе рискуете многократно повысить потребление памяти.

        Анимируйте только свойства transform и opacity

        Именно эти свойства гарантированно не влияют на геометрию элемента и не зависят от окружения, в котором находится анимируемый элемент, поэтому могут полностью работать на GPU. Фактически это означает, что эффективно вы можете анимировать только перемещение, масштаб, вращение, прозрачность, а также искажения, в том числе в 3D-пространстве. Однако с их помощью вы можете эмулировать некоторые другие анимации.

        Рассмотрим классический пример: смена цвета фона у элемента. Чтобы анимированно поменять цвет фона, достаточно написать вот так:

          #bg-change < width: 100px; height: 100px; background: red; transition: background 0.4s; >#bg-change:hover 

        Но такая анимация работает на CPU, вызывает repaint на каждый шаг и не достаточно плавная. Мы можем оптимизировать её и вынести на GPU: достаточно создать дополнительный слой поверх элемента с нужным цветом и менять у него прозрачность:

          #bg-change < width: 100px; height: 100px; background: red; >#bg-change::before < background: blue; opacity: 0; transition: opacity 0.4s; >#bg-change:hover::before 

        Такая анимация будет работать гораздо быстрее и плавнее, но стоит помнить про неявную композицию и повышенное потребление памяти. Хотя последний параметр мы всё-таки сможем немного оптимизировать.

        Уменьшайте габариты композитных слоёв

        Посмотрите на картинку ниже. Видите ли вы разницу между ними?

        example 6

        Это два визуально идентичных композитных слоя, однако первый весит 40 000 байт (39 КБ), а второй — в 100 раз меньше, всего 400 байт. Почему? Посмотрите на код этих слоёв:

          #a, #b < will-change: transform; >#a < width: 100px; height: 100px; >#b 

        Разница в том, что у элемента #a физические габариты — 100×100 пикселей (100×100×4 = 40 000 байт), а у элемента #b — 10×10 пикселей (10×10×4 = 400 байт), увеличенные до 100×100 с помощью transform: scale(10) . Но так как #b является композитным слоем из-за will-change , свойство transform в данном случае будет примеряться уже на GPU в момент отрисовки финального изображения.

        Суть трюка очень проста: с помощью width и height уменьшаем физические габариты элемента, а с помощью transform: scale(…) масштабируем уже отрисованную текстуру до нужного размера. Конечно же, разницу по весу в несколько порядков можно получить только для очень простых одноцветных слоёв. Но, например, если вам нужно анимировать большие фотографии, можно запросто уменьшить их габариты на 5–10% и компенсировать это за счёт масштаба: потеря качества не сильно должна бросаться в глаза, но зато сэкономите драгоценные ресурсы.

        По возможности используйте CSS Transitions и Animations

        Мы уже выяснили, что анимации свойств transform и opacity через CSS Transitions или Animations автоматически создаёт композитный слой и выполняет анимацию на GPU. Также мы можем делать анимацию и с помощью JS, однако в этом случае, как правило, нам нужно приложить чуть больше усилий, чтобы элемент оказался на композитном слое: указать translateZ(0) у transform , will-change: transform, opacity или другие свойства, которые создают композицию.

        Под JS-анимацией подразумевается та анимация, где на каждый requestAnimationFrame вручную высчитывается новый кадр. Использование Element.animate() является вариацией декларативной CSS-анимации.

        С одной стороны CSS Transitions/Animations довольно просто создать и переиспользовать, с другой — через JS движения по сложным траекториям делаются гораздо легче, чем в CSS, а также это единственный способ реагировать на пользовательский ввод.

        Какой из этих способов лучше и универсальнее? Может, стоит оставить только JS и использовать какую-нибудь библиотеку для анимации всего?

        На самом деле у CSS-анимаций есть одно очень важное преимущество: они полностью работают на GPU. Так как вы декларативно объявляете, где анимация начнётся и где закончится, браузер может предварительно подготовить весь набор необходимых инструкций и отправить их на GPU. В случае императивного JS единственное, что может знать браузер — это состояние текущего кадра. Для плавной анимации мы должны как минимум 60 раз в секунду в основном потоке браузера (а JS работает именно в нём) высчитывать данные для нового кадра и пересылать их на GPU, где этот кадр отрисуется. Помимо того, что эти расчёты и отправка данных работают намного медленнее, чем CSS-анимации, они ещё зависят и от загруженности основного потока:

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

        Поэтому по возможности старайтесь делать анимации через CSS, особенно прелоудеры и индикаторы прогресса. Такие анимации не только будут работать быстрее, но и не будут блокировать тяжёлыми расчётами на JS.

        Пример оптимизации

        На самом деле вся эта статья является результатом исследования и экспериментов, которые я провёл для оптимизации сайта Chaos Fighters. Это отзывчивый промо-сайт для мобильной игры с большим количеством анимаций. Когда я только начинал его делать, я всего лишь знал, как сделать анимации плавными на разных устройствах за счёт GPU, но не понимал, как именно это работает. В итоге первая версия сайта стабильно крэшила iPhone 5 — а это была самая последняя новинка от Apple на тот момент — всего через пару секунд пользования сайтом. Но сейчас этот сайт довольно плавно работает даже на менее мощных устройствах.

        Предлагаю рассмотреть самый, на мой взгляд, интересный пример оптимизации с этого сайта.

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

        На первый взгляд всё просто и задача решена. Только вот изображение солнца получилось довольно большим — мобильные пользователи будут не очень этому рады.

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

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

        Результат визуально такой же, как и раньше, однако объём передаваемых по сети данных гораздо меньше. Но размер композитной текстуры остался прежним: 500×500×4 ≈ 977 КБ.

        Для наглядности изображение солнца в нашем примере достаточно небольшое, всего 500×500 пикселей, но на реальном сайте, с учётом разных размеров у мобильных устройств (телефоны и планшеты) и плотностью пикселей, текстура солнца весила примерно 3000×3000×4 = 36 МБ! И это всего лишь один анимированный объект на странице…

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

        Более того, бесполезных данных в текстуре гораздо больше, чем полезных! Не самый лучший способ потратить драгоценные ресурсы устройства, которых и так крайне мало.

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

        • Весь контейнер: 500×500×4 ≈ 977 КБ
        • Только 12 лучей: 250×40×4 × 12 ≈ 469 КБ

        Потребление памяти сократится в 2 раза. Чтобы это произошло, мы должны анимировать не весь контейнер с солнцем, а каждый луч по отдельности. Если мы будем анимировать только лучи, то именно изображения лучей попадут на GPU, промежутки между ними не будут занимать ресурсы.

        Нам нужно ещё немного усложнить разметку для независимой анимации лучей, но теперь CSS нам скорее мешает, чем помогает. Для начального размещения луча мы уже воспользовались свойством transform . Нам нужно начать анимацию именно с этого угла и совершить оборот в 360˚. Фактически это означает, что для каждого луча нужно сделать свою секцию @keyframes , а это очень много кода.

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

        Визуально мы получили абсолютно ту же самую анимацию, но потребление памяти сократили в 2 раза.

        Но и это ещё не всё. С точки зрения композиции всего сайта анимированное солнце — не центральный, а фоновый, вспомогательный элемент. Да и сами лучи не содержат чётких контрастных элементов. А это означает, что мы можем немного ухудшить качество изображения луча и это будет практически незаметно для пользователя. Таким образом мы cможем отправить на GPU текстуру меньшего размера, а затем отмасштабировать её до нужного значения: это позволит нам ещё немного сократить потребляемую память.

        Попробуем сократить размер текстуры луча на 10%. Физический размер текстуры будет 250×0.9 × 40×0.9 = 225×36 пикселей. Соответственно, чтобы визуально она была размером 250×20 пикселей, нам нужно выставить ей коэффициент масштабирования 250/225 ≈ 1.111.

        Добавляем несколько важных штрихов в наш код: background-size: cover; у .sun-ray , чтобы фоновая картинка подстраивалась под размер контейнера, и добавим transform: scale(1.111) при анимации луча.

        Обратите внимание, что мы меняем только размеры у элемента, размер самой PNG-картинки луча остался прежним. Именно прямоугольник, описанный элементом, отрисовывается в текстуру, а не PNG-картинка.

        В итоге размер всей композиции солнца в памяти GPU составляет 225×36×4 × 12 ≈ 380 КБ (было 469 КБ). Потребление памяти сократилось на 19% и мы получили довольно гибкий код, где изменяя параметр downscale можно добиваться нужного соотношения качества картинки и потребления памяти. Если остановиться на значении 0.1 , то получается, что с помощью усложнения такой, казалось бы, простой анимации вращения объекта мы сократили потребляемую память в 977 / 380 ≈ 2.5 раза!

        Думаю, многие заметили, что у предложенного решения есть один недостаток: анимация теперь работает на CPU, а значит будет блокироваться тяжёлыми JS-вычислениями. Поэтому тем, кто хочет закрепить полученный материал, предлагаю сделать небольшое домашнее задание. Сделайте форк последнего примера и доработайте его таким образом, чтобы вся анимация работала на GPU, но при этом не потерялось эффективность и гибкость решения. Результаты размещайте в комментариях.

        Усвоенные уроки

        Исследование, проведённое для оптимизации проекта Chaos Fighters, заставило меня полностью пересмотреть процесс создания современных сайтов. Вот мои основные правила:

        • Всегда обговаривайте с заказчиком и дизайнером, какие анимации и спецэффекты будут на сайте. От этого будет зависеть разметка макета и эффективность композиции.
        • С самого начала нужно следить за количеством и размером композитных слоёв с помощью инструмента Layers, особенно за неявной композицией.
        • Современные браузеры достаточно активно используют композицию не только для анимации, но и для оптимизации отрисовки некоторых частей страницы. Например, position: fixed , , также выносятся на отдельный слой.
        • Размеры композитного слоя зачастую являются более важным критерием, чем количество слоёв. Иногда браузеры пытаются сократить количество слоёв (см. Layer Squashing) — это позволяет значительно сэкономить ресурсы, особенно если композитные элементы пересекаются. Но иногда получается обратный эффект: вместо нескольких небольших слоёв получается один большой слой, потребляющий намного больше памяти. Чтобы отключить такую оптимизацию, я добавляю небольшое уникальное значение translateZ() каждому элементу. Например: translateZ(0.0001px) , translateZ(0.0002px) и т.д. Браузер решит, что слои находятся в разных плоскостях и отключит оптимизацию.
        • Нельзя просто так взять и добавить transform: translateZ(0) или will-change: transform куда попало, чтобы ускорить анимации или избавиться от визуальных артефактов. У выноса элементов на GPU есть огромное количество недостатков и подводных камней, которые стоит учитывать. Неумелое использование композиции в лучшем случае приведёт в обратному эффекту: общему замедлению сайта. В худшем — просто «уронит» браузер.

        В очередной раз напомню про One Big Disclaimer: нет единой спецификации по GPU-композиции и каждый производитель браузеров одни и те же проблемы может решать по-своему. Возможно, часть информации из этой статьи в скором времени потеряет актуальность. Например, разработчики Google Chrome исследуют способы по ускорению передачи данных с CPU на GPU, вплоть до использования общей памяти, когда никуда ничего передавать не нужно. А Safari уже сейчас для некоторых простых случаев (например, обычный элемент с background-color и без содержимого) вместо отрисовки текстуры на CPU отрисовывает элемент на GPU в реальном времени, сводя размер потребляемой памяти практически к нулю.

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

        Как ускорить анимацию и улучшить плавность работы MIUI 13?

        Ольга Короткова

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

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

        • Прежде всего, включите параметры разработчика, перейдя в раздел «О телефоне» и трижды нажав на версию MIUI.
        • Теперь перейдите в «Дополнительные настройки» и выберите «Для разработчиков», в которых необходимо настроить три значения уровня анимации следующим образом:
          — Уровень анимации окна: 0,5X;
          — Уровень анимации переходов: 0,5X;
          — Уровень продолжительности анимации: 0,5X.

        Кроме того, эти настройки помогут сэкономить ресурсы, что еще больше улучшит общую производительность пользовательского интерфейса вашего устройства с MIUI 13. MIUI 13 пока что является самым сложным скином, предлагаемым Xiaomi, и не зря пользователи очень спешат его получить. Мы будем предоставлять больше сведений о разработке MIUI 13, как только станет доступна новая информация.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *