Улучшение производительности анимации

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

Выберите Best Redraw Policy for Your OS X Views

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

Для получения дополнительной информации о политиках перерисовки представления посмотрите Политику Перерисовки Уровня для Производительности Влияния Представлений OS X.

Уровни обновления в OS X для оптимизации пути рендеринга

В OS X v10.8 и позже, представления имеют две опции для обновления содержания нижележащего слоя. При обновлении поддержанного уровнем представления в OS X v10.7 и ранее уровень получает команды рисования от представления drawRect: метод в отступающее растровое изображение. Кэширование команд рисования является эффективным, но не является самой эффективной опцией во всех случаях. Если Вы знаете, как обеспечить содержание уровня непосредственно, фактически не представляя их, можно использовать updateLayer метод, чтобы сделать так.

Для получения информации о различных путях для рендеринга, включая тех, которые включают updateLayer метод, посмотрите Используя Делегата для Обеспечения Содержания Уровня.

Общие советы и приемы

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

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

Установка opaque свойство Вашего уровня к YES позволяет Базовой Анимации знать, что она не должна поддерживать альфа-канал для уровня. Не наличие альфа-канала означает, что наборщик не должен смешивать содержание Вашего уровня с его фоновым содержанием, экономящим время во время рендеринга. Однако это свойство важно прежде всего для уровней, которые являются частью поддержанного уровнем представления или ситуаций, где Базовая Анимация создает битовый массив нижележащего слоя. Если Вы присваиваете изображение непосредственно уровню contents свойство, альфа-канал того изображения сохраняется независимо от значения в opaque свойство.

Используйте более простые пути для объектов CAShapeLayer

CAShapeLayer класс создает свое содержание путем рендеринга пути, который Вы обеспечиваете в растровое изображение в составное время. Преимущество состоит в том, что уровень всегда рисует путь в самом лучшем разрешении, но что преимущество прибывает за счет дополнительного времени рендеринга. Если путь, который Вы обеспечиваете, сложен, растеризирование того пути могло бы стать слишком дорогим. И если размер изменений слоя часто (и таким образом должен часто перерисовываться), количество времени потратил получение, может сложить и стать узким местом производительности.

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

Установите содержание уровня явно для идентичных уровней

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

Всегда устанавливайте размер уровня в интегральные значения

Для лучших результатов, всегда устанавливает ширину и высоту Ваших расположенных на слое объектов к интегральным значениям. Несмотря на то, что Вы указываете ширину и высоту границ Вашего уровня с помощью чисел с плавающей точкой, границы слоев в конечном счете используются для создания растрового изображения. Указание интегральных значений для ширины и высоты упрощает работу, которую Базовая Анимация должна выполнить, чтобы создать и управлять запоминающим устройством и другой информацией об уровне.

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

Любое получение, которое Вы делаете в своем делегате drawLayer:inContext: метод или Ваше представление drawRect: метод обычно происходит синхронно на основном потоке Вашего приложения. В некоторых ситуациях, тем не менее, получающих Ваше содержание синхронно, не мог бы предложить лучшую производительность. Если Вы замечаете, что Ваши анимации не выполняют хорошо, Вы могли бы попытаться включить drawsAsynchronously свойство на Вашем уровне для перемещения тех операций в фоновый поток. Если Вы делаете так, удостоверьтесь, что Ваш код для прорисовки ориентирован на многопотоковое исполнение. И как всегда, необходимо всегда измерять производительность рисования асинхронно прежде, чем поместить его в производственный код.

Укажите теневой путь при добавлении тени к уровню

Разрешение Базовой Анимации определить форму тени может быть дорогим и повлиять на производительность Вашего приложения. Вместо того, чтобы позволять Базовой Анимации определить форму тени, укажите теневую форму явно с помощью shadowPath свойство CALayer. Когда Вы указываете объект контуров для этого свойства, Базовое использование Анимации, формирующее, чтобы нарисовать и кэшировать эффект тени. Для уровней, форма которых никогда не изменяется или редко изменяется, это значительно улучшает производительность путем сокращения суммы рендеринга сделанного Базовой Анимацией.