Красиво и не тормозит!
Анимация без ущерба
производительности приложений
Сергей Токарев,
старший ios-разработчик
Ожидание: Реальность:
Проблемы:
Почему список тормозит?
Почему картинки не отображаются?
Как увеличить скорость отклика приложения?
Немного статистики*
Только
79%пользователей вернутся
в приложение ещё один
или два раза, если оно упало
при первом запуске.
25%пользователей выйдут
из приложения,
если оно не загрузится
за 3 секунды.
31%пользователей расскажет
о незапустившемся
или упавшем приложении
своим друзьям.
*по данным статистики Hewlett Packard Enterprise Software Solutions
осознав проблему...
Доктор, я теряю
пользователей!
Новая задача
Пути улучшения:
Работа с анимацией
Работа с потоками
1
2
Этапы выполнения анимации
Layout
Display
Prepare
Commit
Calculates
Render
1
2
3
4
5
6
СPU
GPU
Этапы выполнения анимации
CPU
GPU
Layout
Display
Prepare
Commit
Calculates
Render
1
2
3
4
5
6
Что замедляет GPU
Слишком много геометрических вычислений
Слишком много перерисовок
Закадровые отрисовки
Слишком большие изображения
Что замедляет CPU
Преобразования изображений
Вычисления layout
Lazy load view
drawRect()
-(void)drawRect:(CGRect)rect {
float fontSize = 13;
CGFloat emailWidth = rect.size.width;
UIFont *emailFont=[UIFont boldSystemFontOfSize: fontSize];
NSDictionary *attrs = @{ NSFontAttributeName: emailFont };
[self.email drawInRect:CGRectMake(28, 4, emailWidth, 16)
withAttributes:attrs];
}
Результат
До: После:
Результат
Время
отрисовки,
нс
Количество
ячеек
170 000
1 3 62 54 7
17 000
До: После:
ShadowPath
UIView *view = [UIView new];
UIBezierPath *path = [UIBezierPath bezierPathWithRect:view.bounds];
backgroundView.layer.shadowPath = path.CGPath;
Контроль FPS
53 FPS
pod 'XFPS'
половина дела сделана
Стало заметно
быстрее работать!
Многопоточность
NSThread
NSOperation
GCD
многопоточность
А можете
синхронно?
NSThread
SJPhotoModel *model = [SJPhotoModel new];
[model performSelectorInBackground:@selector(downloadPhoto)
withObject:nil];
Grand Central Dispatch
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0ul);
dispatch_async(queue, ^(void) {
// загрузка фото
NSData *imageData = [NSData dataWithContentsOfURL:url];
UIImage* image = [[UIImage alloc] initWithData:imageData];
if (image) {
dispatch_async(dispatch_get_main_queue( ), ^{
// преобразование фото
});
}
});
NSOperation
NSOperation *networkingOperation = …;
NSOperation *resizingOperation = …;
[resizingOperation addDependency:networkingOperation];
NSOperationQueue *operationQueue = [NSOperationQueue mainQueue];
[operationQueue addOperations:@[networkingOperation, resizingOperation]
waitUntilFinished:NO];
THE END
...

Красиво и не тормозит! Анимация без ущерба для производительности приложений / Сергей Токарев (SuperJob)