Slide 1

Slide 1 text

Vyng

Slide 2

Slide 2 text

Профайлинг в примерах Ищем бутылочное горлышко в скорости UI Артур Бадретдинов
 GDG lead, Vyng

Slide 3

Slide 3 text

«Работает, и хорошо»

Slide 4

Slide 4 text

«Работает , и хорошо»

Slide 5

Slide 5 text

Vyng Messaging • Нужно больше мессенджеров! • Неделя мессенджеров. Количество слайдов с чатиками увеличивается в 2 раза !5

Slide 6

Slide 6 text

План !6

Slide 7

Slide 7 text

План • Отрисовка: 101 !6

Slide 8

Slide 8 text

План • Отрисовка: 101 • Поиск проблем !6

Slide 9

Slide 9 text

План • Отрисовка: 101 • Поиск проблем • Анализ разметки !6

Slide 10

Slide 10 text

План • Отрисовка: 101 • Поиск проблем • Анализ разметки • Влияние наложения !6

Slide 11

Slide 11 text

План • Отрисовка: 101 • Поиск проблем • Анализ разметки • Влияние наложения • Удалённое наблюдение !6

Slide 12

Slide 12 text

Скорость UI

Slide 13

Slide 13 text

Что же видят люди? !8

Slide 14

Slide 14 text

Что же видят люди? • «Обратная связь» !8

Slide 15

Slide 15 text

Что же видят люди? • «Обратная связь» • Время появления ожидаемых данных !8

Slide 16

Slide 16 text

Что же видят люди? • «Обратная связь» • Время появления ожидаемых данных • FPS - количество кадров в секунду !8

Slide 17

Slide 17 text

FPS

Slide 18

Slide 18 text

Кадры решают всё !10

Slide 19

Slide 19 text

Кадры решают всё !10

Slide 20

Slide 20 text

Кадры решают всё • 10 кадров в секунду !10

Slide 21

Slide 21 text

Кадры решают всё • 10 кадров в секунду • 24 кадра в секунду !10

Slide 22

Slide 22 text

Кадры решают всё • 10 кадров в секунду • 24 кадра в секунду • 60 кадров в секунду !10

Slide 23

Slide 23 text

Кадры решают всё • 10 кадров в секунду • 24 кадра в секунду • 60 кадров в секунду • 120 кадров в секунду !10

Slide 24

Slide 24 text

0 кадров в секунду

Slide 25

Slide 25 text

16 мс

Slide 26

Slide 26 text

16 мс ~ 1000 мс / 60 кадров

Slide 27

Slide 27 text

VSync

Slide 28

Slide 28 text

Screen tearing

Slide 29

Slide 29 text

Choreographer and VSync !15

Slide 30

Slide 30 text

Choreographer and VSync • Ввод !15

Slide 31

Slide 31 text

Choreographer and VSync • Ввод • Анимации !15

Slide 32

Slide 32 text

Choreographer and VSync • Ввод • Анимации • Создание View !15

Slide 33

Slide 33 text

Choreographer and VSync • Ввод • Анимации • Создание View • Отрисовка View !15

Slide 34

Slide 34 text

!16 Display Lists

Slide 35

Slide 35 text

!16 Display Lists • Кэш операций рендеринга API 11 (Android 3.0)

Slide 36

Slide 36 text

!16 Display Lists • Кэш операций рендеринга • Не содержит логики API 11 (Android 3.0)

Slide 37

Slide 37 text

!16 Display Lists • Кэш операций рендеринга • Не содержит логики • Каждой View - по Display List! https://www.youtube.com/watch?v=v9S5EO7CLjo API 11 (Android 3.0)

Slide 38

Slide 38 text

Display List Save 3 DrawPatch Save 3 ClipRext 20.00, 4.00, 99.00, 44.00, 1 Translate 20.00, 12.00 DrawText 9, 18, 9, 0.00, 19.00, 0x17e898 Restore RestoreToCount 0 !17

Slide 39

Slide 39 text

Buffer updates !18 Dropped Frame Build frame 16 ? ? 16 ? ? 16 ? ? Draw Draw Build frame Build frame Draw

Slide 40

Slide 40 text

Dropped frames !19 Build frame Build frame 16 ? ? 16 ? ? 16 ? ? Draw Draw? Nope! Dropped Frame Draw

Slide 41

Slide 41 text

Причины !20

Slide 42

Slide 42 text

Причины • Деятельность в главном потоке !20

Slide 43

Slide 43 text

Причины • Деятельность в главном потоке • IO !20

Slide 44

Slide 44 text

Причины • Деятельность в главном потоке • IO • «Дорогие» операции !20

Slide 45

Slide 45 text

Причины • Деятельность в главном потоке • IO • «Дорогие» операции • Проблемы разметки !20

Slide 46

Slide 46 text

Причины • Деятельность в главном потоке • IO • «Дорогие» операции • Проблемы разметки • Большая вложенность !20

Slide 47

Slide 47 text

Причины • Деятельность в главном потоке • IO • «Дорогие» операции • Проблемы разметки • Большая вложенность • Наложение !20

Slide 48

Slide 48 text

Причины • Деятельность в главном потоке • IO • «Дорогие» операции • Проблемы разметки • Большая вложенность • Наложение • Прозрачность !20

Slide 49

Slide 49 text

Причины • Деятельность в главном потоке • IO • «Дорогие» операции • Проблемы разметки • Большая вложенность • Наложение • Прозрачность • Большое количество view !20

Slide 50

Slide 50 text

Сложности разметки

Slide 51

Slide 51 text

Инструменты • Profile GPU rendering • HierarchyViewer • Debug GPU overdraw • SysTrace • TraceView !22

Slide 52

Slide 52 text

Очерчиваем проблему Сложности разметки

Slide 53

Slide 53 text

Инструменты • Profile GPU rendering • Gfxinfo • SysTrace !24

Slide 54

Slide 54 text

Профилируем отрисовку GPU !25

Slide 55

Slide 55 text

Профилируем отрисовку GPU !26

Slide 56

Slide 56 text

Информация профилирования !27 https://developer.android.com/studio/profile/inspect-gpu-rendering.html

Slide 57

Slide 57 text

Информация профилирования • Ожидание главного потока !27 https://developer.android.com/studio/profile/inspect-gpu-rendering.html

Slide 58

Slide 58 text

Информация профилирования • Ожидание главного потока • Measure/layout/animation/input handling !27 https://developer.android.com/studio/profile/inspect-gpu-rendering.html

Slide 59

Slide 59 text

Информация профилирования • Ожидание главного потока • Measure/layout/animation/input handling • Обновление DisplayLists (onDraw()) !27 https://developer.android.com/studio/profile/inspect-gpu-rendering.html

Slide 60

Slide 60 text

Информация профилирования • Ожидание главного потока • Measure/layout/animation/input handling • Обновление DisplayLists (onDraw()) • Передача изображений (bitmaps) в GPU !27 https://developer.android.com/studio/profile/inspect-gpu-rendering.html

Slide 61

Slide 61 text

Информация профилирования • Ожидание главного потока • Measure/layout/animation/input handling • Обновление DisplayLists (onDraw()) • Передача изображений (bitmaps) в GPU • Отображение DisplayLists на экран !27 https://developer.android.com/studio/profile/inspect-gpu-rendering.html

Slide 62

Slide 62 text

Информация профилирования • Ожидание главного потока • Measure/layout/animation/input handling • Обновление DisplayLists (onDraw()) • Передача изображений (bitmaps) в GPU • Отображение DisplayLists на экран • Смена буфера GPU !27 https://developer.android.com/studio/profile/inspect-gpu-rendering.html

Slide 63

Slide 63 text

Профилируем отрисовку GPU • Оранжевый — смена буфера GPU • Тёмно-зелёный - ожидание, пока главный поток освободится !28

Slide 64

Slide 64 text

GPU monitor • До Android Studio 3.0 !29 https://developer.android.com/studio/profile/am-gpu.html Возможная причина: https://stackoverflow.com/a/36345160/3675659

Slide 65

Slide 65 text

!30 Gfxinfo > adb shell dumpsys gfxinfo 
 framestats

Slide 66

Slide 66 text

!30 Gfxinfo > adb shell dumpsys gfxinfo 
 framestats

Slide 67

Slide 67 text

!30 Gfxinfo > adb shell dumpsys gfxinfo 
 framestats

Slide 68

Slide 68 text

Агрегированные данные • Total frames rendered: 1836 • Janky frames: 1344 (73.20%) • 90th percentile: 31ms • 95th percentile: 40ms • Number Slow UI thread: 187 • Number Slow bitmap uploads: 17 • Number Slow issue draw commands: 1145 !31

Slide 69

Slide 69 text

Ничто не идеально !32

Slide 70

Slide 70 text

Ничто не идеально !32

Slide 71

Slide 71 text

Ничто не идеально !32

Slide 72

Slide 72 text

Тут нормально, там не очень… !33

Slide 73

Slide 73 text

–Nimbledroid «86% Пользователей удаляют медленные приложения сразу после установки». http://blog.nimbledroid.com/2015/09/03/why-you-should-care-about-app-performance.html

Slide 74

Slide 74 text

— Peter Drucker, Writer, Management Consultant “What gets measured gets managed”

Slide 75

Slide 75 text

Hierarchy Viewer Сложности разметки

Slide 76

Slide 76 text

Hierarchy Viewer

Slide 77

Slide 77 text

Запуск Hierarchy Viewer 1. Tools -> Android -> Enable ADB integration 2. Tools -> Android -> Android Device Monitor 3. Запуск профилировки !38

Slide 78

Slide 78 text

Запуск Hierarchy Viewer 1. Tools -> Android -> Enable ADB integration 2. Tools -> Android -> Android Device Monitor 3. Запуск профилировки !38

Slide 79

Slide 79 text

Цветные кружочки

Slide 80

Slide 80 text

Цветные кружочки • Measure • Layout • Draw !40

Slide 81

Slide 81 text

Цветные кружочки • Зеленый - быстрее 50% • Жёлтый - медленнее 50% • Красный - самый медленный !41

Slide 82

Slide 82 text

Всё относительно • 1 view • Measure: 0,023 ms • Layout: 0,001 ms • Draw: 0,426 ms !42 0.5 мс

Slide 83

Slide 83 text

Всё относительно • 138 views • Measure: 4,461 ms • Layout: 1,026 ms • Draw: 14,723 ms !43 20 мс

Slide 84

Slide 84 text

300 спартанцев • 327 views • Measure: 21,420 ms • Layout: 17,690 ms • Draw: 3,863 ms !44 20 мс

Slide 85

Slide 85 text

Раз экранчик, два экранчик… !45

Slide 86

Slide 86 text

Раз экранчик, два экранчик… • 498 views • Measure: 4,101 ms • Layout: 106,855 ms • Draw: 9,173 ms !46 120 мс

Slide 87

Slide 87 text

To push or not to push? • 31 views • Measure: 0,427 ms • Layout: 4,818 ms • Draw: 0,923 ms !47 6 мс

Slide 88

Slide 88 text

To push or not to push? void setCurrentChatView(…) { … // Подготовка транзакции router.pushController(transaction); } Аналогично fragmentTransaction.add() !48

Slide 89

Slide 89 text

ViewStub !49 setVisibility(int) inflate()

Slide 90

Slide 90 text

ViewStub vs Dynamic !50

Slide 91

Slide 91 text

ViewStub vs Dynamic • Вся разметка в одном месте !50

Slide 92

Slide 92 text

ViewStub vs Dynamic • Вся разметка в одном месте • Проще установить позицию в разметке !50

Slide 93

Slide 93 text

ViewStub vs Dynamic • Вся разметка в одном месте • Проще установить позицию в разметке • Видно в предпросмотре !50

Slide 94

Slide 94 text

ViewStub vs Dynamic • Вся разметка в одном месте • Проще установить позицию в разметке • Видно в предпросмотре • Размер - 0 !50

Slide 95

Slide 95 text

ViewStub vs Dynamic • Вся разметка в одном месте • Проще установить позицию в разметке • Видно в предпросмотре • Размер - 0 • Пустые onDraw/onLayout/onMeasure !50

Slide 96

Slide 96 text

Лишние контейнеры

Slide 97

Slide 97 text

Лишние контейнеры

Slide 98

Slide 98 text

Lint check • Android > 
 Lint > 
 Performance !53

Slide 99

Slide 99 text

Оптимизация? !54

Slide 100

Slide 100 text

Тестируйте на слабых устройствах !55 • Эмулятор 
 Macbook Pro 2017 • 280 views • ~ 11 ms

Slide 101

Slide 101 text

Тестируйте на слабых устройствах !55 • Эмулятор 
 Macbook Pro 2017 • 280 views • ~ 11 ms • Samsung 
 Galaxy J2 • 167 views • ~ 96 ms

Slide 102

Slide 102 text

Доверяй, но проверяй @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); SystemClock.sleep(1000); } !56

Slide 103

Slide 103 text

Доверяй, но проверяй @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); SystemClock.sleep(1000); } !56

Slide 104

Slide 104 text

Такое разное время !57

Slide 105

Slide 105 text

Такое разное время • Wall clock time !57

Slide 106

Slide 106 text

Такое разное время • Wall clock time • Thread time !57

Slide 107

Slide 107 text

Hierarchy Viewer - thread time @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); fib(39); } public static int fib(int n) { if (n == 0 || n == 1) { return 1; } else { return fib(n - 1) + fib(n - 2); } } !58

Slide 108

Slide 108 text

Display lists Root (ConversationListItemView 0x85463300) (Translate (left, top) 0, 869) (ClipRect 0, 0, 1080, 212) RenderNodeOp [1080.00 x 212.00] (ColorDrawable 0x86660880) RectOp [1080.00 x 212.00] /RenderNode(ColorDrawable 0x86660880) RenderNodeOp [1080.00 x 212.00] (FrameLayout 0x85464480) (ClipRect 0, 0, 1080, 212) RenderNodeOp [1080.00 x 212.00] (ColorDrawable 0x86660c00, empty) /RenderNode(ColorDrawable 0x86660c00) RenderNodeOp [1080.00 x 212.00] (LinearLayout 0x85464800) (ClipRect 0, 0, 1080, 212) RenderNodeOp [1080.00 x 212.00] (RippleDrawable 0x86660f80, empty) /RenderNode(RippleDrawable 0x86660f80) !59

Slide 109

Slide 109 text

Display lists Root (ConversationListItemView 0x85463300) (Translate (left, top) 0, 869) (ClipRect 0, 0, 1080, 212) RenderNodeOp [1080.00 x 212.00] (ColorDrawable 0x86660880) RectOp [1080.00 x 212.00] /RenderNode(ColorDrawable 0x86660880) RenderNodeOp [1080.00 x 212.00] (FrameLayout 0x85464480) (ClipRect 0, 0, 1080, 212) RenderNodeOp [1080.00 x 212.00] (ColorDrawable 0x86660c00, empty) /RenderNode(ColorDrawable 0x86660c00) RenderNodeOp [1080.00 x 212.00] (LinearLayout 0x85464800) (ClipRect 0, 0, 1080, 212) RenderNodeOp [1080.00 x 212.00] (RippleDrawable 0x86660f80, empty) /RenderNode(RippleDrawable 0x86660f80) !59

Slide 110

Slide 110 text

Hierarchy Viewer. Заключение !60

Slide 111

Slide 111 text

Hierarchy Viewer. Заключение • 10 измерений — 10 уникальных результатов !60

Slide 112

Slide 112 text

Hierarchy Viewer. Заключение • 10 измерений — 10 уникальных результатов • Красный != плохо !60

Slide 113

Slide 113 text

Hierarchy Viewer. Заключение • 10 измерений — 10 уникальных результатов • Красный != плохо • Оптимизации нужно подтверждать числами !60

Slide 114

Slide 114 text

Hierarchy Viewer. Заключение • 10 измерений — 10 уникальных результатов • Красный != плохо • Оптимизации нужно подтверждать числами • Метрики снимаются только вручную… !60

Slide 115

Slide 115 text

Немного о грустном Hierarchy Viewer is no longer being developed !61

Slide 116

Slide 116 text

Layout inspector

Slide 117

Slide 117 text

Overdraw Сложности разметки

Slide 118

Slide 118 text

Профилируем отрисовку GPU !64

Slide 119

Slide 119 text

Слои. Photoshop? Не только !65 https://www.youtube.com/watch?v=T52v50r-JfE

Slide 120

Slide 120 text

Отрисовка виджетов • onMeasure() - желаемый размер • onLayout() - фактический размер, положение • onDraw() - отрисовка в Display Lists !66

Slide 121

Slide 121 text

Ну и что? • Перерисовывка много раз • Каскадный вызов 
 requestLayout() !67 https://medium.com/google-developers/simplify-complex-view-hierarchies-5d358618b06f

Slide 122

Slide 122 text

Hierarchy View → Photoshop !68

Slide 123

Slide 123 text

Hierarchy View → Photoshop • Простая визуализация !68

Slide 124

Slide 124 text

Hierarchy View → Photoshop • Простая визуализация • Легко найти лишние слои !68

Slide 125

Slide 125 text

Hierarchy View → Photoshop • Простая визуализация • Легко найти лишние слои !68

Slide 126

Slide 126 text

Слои виджетов !69

Slide 127

Slide 127 text

Слои виджетов !69

Slide 128

Slide 128 text

Слои виджетов !70

Slide 129

Slide 129 text

До и после !71

Slide 130

Slide 130 text

До и после !71

Slide 131

Slide 131 text

Аватарки. Велосипед • Overdraw - красный !72

Slide 132

Slide 132 text

Аватарки. Велосипед • Overdraw - красный !72

Slide 133

Slide 133 text

Аватарки. Велосипед • Overdraw - красный • Реализация - 4 слоя !72

Slide 134

Slide 134 text

Аватарки. Велосипед • Overdraw - красный • Реализация - 4 слоя • 4,2 мс на отрисовку !72

Slide 135

Slide 135 text

Аватарки. Готовое решение !73

Slide 136

Slide 136 text

Аватарки. Готовое решение • Библиотека от Tango Agency !73

Slide 137

Slide 137 text

Аватарки. Готовое решение • Библиотека от Tango Agency • Статья о решении* !73 *https://medium.com/tangoagency/avatar-view-for-android-apps-c00091e85ab8

Slide 138

Slide 138 text

Аватарки. Готовое решение • Библиотека от Tango Agency • Статья о решении* • Overdraw - синий !73 *https://medium.com/tangoagency/avatar-view-for-android-apps-c00091e85ab8

Slide 139

Slide 139 text

Аватарки. Готовое решение • Библиотека от Tango Agency • Статья о решении* • Overdraw - синий • Отрисовка… 50 мс! !73 *https://medium.com/tangoagency/avatar-view-for-android-apps-c00091e85ab8

Slide 140

Slide 140 text

Привет, Кэп! !74

Slide 141

Slide 141 text

Привет, Кэп! • Иногда готовое решение лучше • Но велосипеды бывают неплохими • Главное - измерять! !74

Slide 142

Slide 142 text

Scalpel !75

Slide 143

Slide 143 text

Scalpel • Не нужно Фотошопа !75

Slide 144

Slide 144 text

Scalpel • Не нужно Фотошопа • Требует добавления специальную ViewGroup !75

Slide 145

Slide 145 text

Scalpel • Не нужно Фотошопа • Требует добавления специальную ViewGroup • Решение:
 https://github.com/gaket/scalpel !75

Slide 146

Slide 146 text

Overdraw !76

Slide 147

Slide 147 text

Overdraw • Легко проверить !76

Slide 148

Slide 148 text

Overdraw • Легко проверить • Легко исправить !76

Slide 149

Slide 149 text

Overdraw • Легко проверить • Легко исправить • Не стоит впадать в крайности !76

Slide 150

Slide 150 text

Отступать некуда Позади Москва

Slide 151

Slide 151 text

Android vitals !78

Slide 152

Slide 152 text

Android vitals !78

Slide 153

Slide 153 text

Android vitals !78

Slide 154

Slide 154 text

Android vitals !78

Slide 155

Slide 155 text

Android vitals !78

Slide 156

Slide 156 text

Frozen Frames

Slide 157

Slide 157 text

Render time

Slide 158

Slide 158 text

Render time anomaly

Slide 159

Slide 159 text

Подводя итоги

Slide 160

Slide 160 text

• SysTrace • TraceView (CPU Monitor) За кадром

Slide 161

Slide 161 text

— Instagram Engineering blog «At Instagram we’ve spent the last year reimagining and redesigning our Android app to work better for our users». https://engineering.instagram.com/building-a-better-instagram-app-for-android-c08f973662b

Slide 162

Slide 162 text

• Оптимизации - не всегда • Рука на пульсе - обязательно! Стоит ли овчинка выделки

Slide 163

Slide 163 text

Slide title Vyng Is Hiring • Remote positions • Senior Android Developer • Senior Back-End Developer (NodeJs, React) 
 Details:
 Telegram: @gaket, @travelernote
 https://www.linkedin.com/in/gaket/ [email protected] Startup in California, We are making ringtones fun again :)


Slide 164

Slide 164 text

That’s all folks !87

Slide 165

Slide 165 text

Профайлинг в примерах Артур Бадретдинов, Vyng Telegram: @gaketo, @travelernote Facebook: https://www.facebook.com/gakett LinkedIn: https://www.linkedin.com/in/gaket !88