"Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

56
Где еще живет скорость в Web MoscowJS #24 Олег Елифантьев, @oelifantiev

Transcript of "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Page 1: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Где еще живет скорость в WebMoscowJS #24

Олег Елифантьев, @oelifantiev

Page 2: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Олег ЕлифантьевКомпания Тензор, г. Ярославль

Веб-разработчик (JavaScript, Node.JS)

Организатор Yaroslavl Frontend Meetup (http://yarfrontend.ru)

@oelifantiev

2

Page 3: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Давайте нарисуем снежинки?Менеджер: К новому году на сайт клиента нужны снежинки!

Dev: Okay boss!

3

Page 4: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Снежинка?• Простая текстовая нода

• position: absolute

• Анимируем через left, top

4

Page 5: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

$('.snowflake').each(function(){

var pos = $(this).offset();

$(this).css({

top: pos.top + ...,

left: pos.left + ...

});

});

setTimeout(animate, 0);

5

Page 6: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24
Page 7: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Нужно больше

снежинок!

Page 8: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24
Page 9: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

=(

Page 10: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Может быть проблема в JavaScript?

10

Page 11: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

jQuery тормозит.

Расходимся.

Page 12: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

=)

Page 13: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Анимировать будем так...function animate() {

var col = document.querySelectorAll('.snowflake');

for (var i = 0; i < col.length; i++) {

var rect = col[i].getBoundingClientRect();

col[i].style.top = ..., col[i].style.left = ...

}

setTimeout(animate, 0);

}

13

Page 14: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24
Page 15: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Что происходит?Как обычно, нам поможет DevTools

• Поймем что мерять

• Локализуем проблему

• Полечим

15

Page 16: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Будем мерять FPS

16

Page 17: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Маловато!• Приемлемо — хотя бы 30fps (33 ms/frame!)

• Идеально — 60fps (16.6 ms/frame!)

17

Page 18: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Почему так получилось?Запишем все происходящее

18

Page 19: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24
Page 20: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

223 ms!

Page 21: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Style

recalculation

Page 22: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Style recalculation — вычисление стилей, применяемых к конкретному

элементу.

Это дешевая операция .

22

Page 23: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Layout

Page 24: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

HTML�<body>

�<p>

�Длинный текст

�<img align="right" src="..."/>

�Еще текст

�</p>

�</body>

01.

02.

03.

04.

05.

06.

07.

24

Page 25: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

HTML превращается в DOM-дерево

+ body

+-- p

+-- #text

+-- img

+-- #text

25

Page 26: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Есть еще "дерево рендеринга"Это длинный текст, который браузер

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

каждую строку) в зависимости от

размеров родительского блока, размера

шрифта, гарнитуры и даже этого кота.

Набор этих прямоугольников составит

"дерево рендеринга". Тут еще немного текста чтобы получилось

красиво…

26

Page 27: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Есть еще "дерево рендеринга"Это длинный текст, который браузер

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

каждую строку) в зависимости от

размеров родительского блока, размера

шрифта, гарнитуры и даже этого кота.

Набор этих прямоугольников составит

"дерево рендеринга". Тут еще немного текста чтобы получилось

красиво…

27

Page 28: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Layout — пересчет дерева рендеринга на основании стилей элементов

и других входных параметров, например размера окна браузера.

Это дорогая операция!

28

Page 29: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Что приводит к инвалидации дереварендеринга?

• Изменение определенных стилей элемента

• Размер, гарнитура шрифта

• Геометрия (width, height, margin, etc…)

• etc…

• Изменение DOM-дерева

29

Page 30: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Оптимизации…Браузер всячески старается оптимизировать процесс. Например, он

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

окончания синхронного блока JavaScript. Таким образом он

"пакетирует" несколько изменений в один расчет.

30

Page 31: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Ложка дегтяНо если в коде мы начинаем читать стилевую информацию, браузеру

приходится применить все отложенные расчеты здесь и сейчас для

того, чтобы ответить на наш запрос.

Это происходит синхронно. Все прочие процессы блокируются!

Эффект сравним с работой Garbage Сollector.

31

Page 32: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24
Page 33: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Что приводит к "чтению стилей"• getComputedStyle(elt)

• elt.style.???

• elt.getBoundingClientRect()

33

Page 34: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Вернемся к нашей анимацииvar col = document.querySelectorAll('.snowflake');

for (var i = 0; i < col.length; i++) {

// read one, forced layout

var rect = col[i].getBoundingClientRect();

// write one, layout invalidated

col[i].style.top = ..., col[i].style.left = ...

}

34

Page 35: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Как исправить?Все очень просто!

Нужно сначала все прочитать, а потом все записать!

Спасибо, Кэп!

35

Page 36: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

function animate() {

var col = document.querySelectorAll('.snowflake');

[].slice.call(col)

// read all

.map(readCoordinates)

.map(applyAnimationStep)

// write all

.forEach(applyToDOM);

setTimeout(animate, 0);

}

36

Page 37: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24
Page 38: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Было

Page 39: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24
Page 40: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Стало

Page 41: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24
Page 42: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24
Page 43: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Paint

Page 44: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Еще раз посмотрим на Timeline

Включаем "Show paint rectangles"

44

Page 45: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24
Page 46: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Что делать? Заставим трудиться GPU!Вместо left и top для перемещения используем CSS Transforms

transform: translate3d(x, y, z);

46

Page 47: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24
Page 48: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Экономная

анимация

Page 49: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

requestAnimationFrame!• Экономит CPU

• Делает анимацию более плавной

• Дает "привязку ко времени"

49

Page 50: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Используем знание о времени!function animate(ts) {

var col = document.querySelectorAll('.snowflake');

[].slice.call(col)

.map(calculateNextPosition(ts))

.forEach(applyToDOM);

requestAnimationFrame(animate);

}

50

Page 51: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

will-change

Page 52: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

CSS-свойство "will-change"Позволяет подсказать браузеру, что будет происходить с элементом.

Браузер может использовать для оптимизаций

.someElt { ... }

.someElt:hover { will-change: transform; }

.someElt:active { transform: rotate(90deg); }

52

Page 53: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

will-change ?Опыт автора: Chrome 43 — эффект сомнительный.

53

Page 54: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Disclaimer :)Почти все это актуально не только для анимации! Любой код,

работающий с DOM, может выиграть!

• Сначала чтение, затем запись

• transform: translate3d

• requestAnimationFrame

• will-change

• И не забывайте про DevTools!

54

Page 55: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24
Page 56: "Где еще живет скорость в web", Олег Елифантьев, MoscowJS 24

Спасибо за внимание!Доп. материалы: http://bit.ly/render-speed

Вопросы?

MoscowJS #24

Елифантьев Олег, Тензор

@oelifantiev

56