78
Степанова Марина Разработчик интерфейсов Как мы заставили API Яндекс.Карт работать быстрее Я.Субботник, Санкт-Петербург , 1 декабря 2012 года

Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

  • Upload
    yandex

  • View
    2.140

  • Download
    16

Embed Size (px)

DESCRIPTION

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

Citation preview

Page 1: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

Степанова Марина Разработчик интерфейсов

Как мы заставили API Яндекс.Карт работать быстрее

Я.Субботник, Санкт-Петербург, 1 декабря 2012 года

Page 2: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

2

Что такое API Яндекс.Карт?

Page 3: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

3

Что такое API Яндекс.Карт?

Page 4: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

4

Что такое API Яндекс.Карт?

Page 5: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

5

Что такое API Яндекс.Карт?

Page 6: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

6

Слишком много вариантов использования API – что измерять и ускорять?

Page 7: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

7

Опираемся на популярные кейсы

Создание карты Схема проезда

1000 простых меток 1000 меток с текстом

Page 8: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

8

Опираемся на популярные кейсы

5000 меток через кластеризатор

Линия на 10 000 точек

1000 линий по 10 точек

Page 9: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

9

Как оцениваем?

– Смотрим на свою скорость

– Сравниваем с конкурентами

Page 10: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

10

Инструменты

Page 11: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

11

Инструменты для измерения скорости веб-страницы

Множество встроенных инструментов в браузерах (Firebug, Speed Tracer и другие)

+

Внутренние инструменты

Page 12: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

12

Интерфейс запуска тестов

Page 13: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

13

Профилирование конкретного теста

Page 14: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

14

Инструмент «Шуттилка»

Внутренний инструмент Яндекса Принцип работы – отслеживание визуальных изменений на странице

Page 15: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

15

Инструмент «Шуттилка»

Начало отрисовки 1060мс

Заливка фоном 1170мс

Первый тайл 1600мс

Последний тайл 1660мс

Page 16: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

16

Инструмент «Шуттилка»

Page 17: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

17

Этапы жизни приложения

Взаимодействие

Создание окружения

Загрузка

Page 18: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

18

Этапы жизни приложения

Взаимодействие

Создание окружения

Загрузка  

Page 19: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

19

Проблемы API 1.1

−  Большой объем загружаемых данных из-за монолитного ядра

Javascript ядро + CSS + Images ≈ 220 Kb *

* gzip + obfuscation

Page 20: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

20

Проблемы API 1.1

−  Большой объем загружаемых данных из-за монолитного ядра

−  Большое количество сетевых запросов

Page 21: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

21

Page 22: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

22

21 служебный запрос из 34

Page 23: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

23

Решение проблем в API 2.0

−  Большой объем загружаемых данных из-за монолитного ядра

Модульность

Page 24: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

24

Модульность

−  Разбиваем код на логические части

−  Позволяем подключить только то, что нужно

Page 25: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

25

js:C

js:Bjs:A

js:D

js:E

Модульная система

Page 26: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

26

js:C

js:Bjs:A css:A

css:Bjs:D

js:E

Модульная система

Page 27: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

27

Модульная система

js:C

js:Bjs:A css:A

css:Bjs:D

js:E

Page 28: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

28

Модульная система

Модулей > 700

js:C

js:Bjs:A css:A

css:Bjs:D

js:E

Page 29: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

29

???

Модульная система

Модулей > 700

js:C

js:Bjs:A css:A

css:Bjs:D

js:E

Page 30: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

30

Модульная система

Модулей > 700

package:A

package:B

js:C

js:Bjs:A css:A

css:Bjs:D

js:E

Page 31: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

31

Модульная система

package:C

package:A

package:B

js:C

js:Bjs:A css:A

css:Bjs:D

js:E

Модулей > 700

Page 32: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

32

Решение проблем в API 2.0

−  Большой объем загружаемых данных из-за монолитного ядра

−  Большое количество сетевых запросов

Объединение запросов

Page 33: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

33

Объединение запросов

−  Объединение загрузки JavaScript

−  CSS пакуем в JavaScript

−  Изображения пакуем в CSS, используя dataUri

Page 34: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

34

Порядок загрузки

http://api-maps.yandex.ru/2.0

Имена и зависимости Код

js:C

js:Bjs:A css:A

css:Bjs:D

js:E

Page 35: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

35

Порядок загрузки

http://api-maps.yandex.ru/2.0

api-maps.yandex.ru/2.0/?lang=ru-RU

Page 36: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

36

http://api-maps.yandex.ru/2.0

api-maps.yandex.ru/2.0/?lang=ru-RU

!"#$%&'() +

Порядок загрузки

Page 37: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

37

Порядок загрузки

http://api-maps.yandex.ru/2.0

2.0/?lang=ru-RU&load=package.A

/combine.xml?modules=...

Page 38: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

38

Порядок загрузки

http://api-maps.yandex.ru/2.0

2.0/?lang=ru-RU&load=package.A

/combine.xml?modules=...

Page 39: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

39

Результат

−  Загружаем только то, что нужно

Usecase Объем  кода  

Отобразить  карту   96Kb

Все  возможности   295Kb

Page 40: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

40

Результат

−  Загружаем только то, что нужно

−  За минимальное количество запросов

Page 41: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

41

Результат

−  Загружаем только то, что нужно

−  За минимальное количество запросов

5 служебных запросов из 22

Page 42: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

42

Этапы жизни приложения

Взаимодействие

Создание окружения

Загрузка

Page 43: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

43

Пара историй про создание окружения

Page 44: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

44

проблеме организации данных и алгоритмов на примере менеджера событий API 2.0

Page 45: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

45

Менеджер событий API 1.1 Организация данных [observer0, observer1, observer2, ...]

Использование var observer = Events.observe(obj, 'click', cb, ctx); Events.notify(obj, 'click'); observer.cleanup();

Page 46: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

46

Менеджер событий API 1.1

Недостатки

−  Неудобный синтаксис

−  Медленное удаление слушателей

Page 47: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

47

Менеджер событий API 2.0 Организация данных

Использование

obj.events

.add('click', callback, ctx) .fire('click') .remove('click', callback, ctx);

Page 48: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

48

Менеджер событий API 2.0

Добавление Удаление

API 1.1 API 1.1

Page 49: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

49

Эгей, значит будем использовать списки!

Page 50: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

50

Page 51: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

51

−  Генерация строковых ID ─ дорого

−  Настройка связей между элементами двусвязного списка ─ дорого

Мы хотели оптимизировать удаление, а это оказалось не критично

Слишком медленно добавляются слушатели в список L

Page 52: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

52

Возвращаемся к массивам Организация данных [callback0, context0, callback1, context1,...]

Сохраняем обработчики и контексты исполнения в общем плоском массиве

Page 53: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

53

Массивы быстрее на добавление и удаление, если слушателей < 1000

Page 54: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

54

Получили очень хорошие результаты −  Добавление слушателей ускорилось в десятки раз

−  Создание геообъектов ускорилось в 2 раза

Page 55: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

55

Делаем выводы

−  Проверяем эффективность алгоритмов в реальных условиях

−  Избегаем преждевременных оптимизаций

Page 56: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

56

Делаем выводы

−  Проверяем эффективность алгоритмов в реальных условиях

−  Избегаем преждевременных оптимизаций

Page 57: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

57

взаимодействии с DOM на примере util.nodeSize

Page 58: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

58

util.nodeSize

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

Page 59: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

59

util.nodeSize

util.nodeSize

computeSize()

DOM-элемент

Параметры

Размеры

Page 60: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

60

util.nodeSize

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

Вызов util.nodeSize влечет за собой reflow

Page 61: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

61

Speed Tracer (by Google)

Диаграмма медлительности

Page 62: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

62

Добавление 1000 меток с содержимым

Page 63: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

63

Используем requestAnimationFrame API

для оптимизации количества reflow

Page 64: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

64

util.nodeSize стал асинхронным

util.nodeSize

computeSize()

DOM-элемент

Параметры

Размеры

callback

Page 65: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

65

Действия с DOM накапливаются и выполняются разом

Page 66: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

66

Делаем выводы

Используем возможности браузеров для оптимизации работы с DOM

Page 67: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

67

Этапы жизни приложения

Взаимодействие

Создание окружения

Загрузка

Page 68: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

68

Основные проблемы

−  Блокировки браузера из-за продолжительных действий

−  Большое количество DOM-элементов

Page 69: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

69

Как решаем проблемы блокировок

Способ Пример из API

Чанкинг – выполняем операции пачками через таймаут

Добавление на карту меток

Фильтрация потока событий

Обрабатываем не все mousemove

Page 70: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

70

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

Асинхронное

Page 71: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

71

Как решаем проблемы большого количества DOM-элементов Способ Пример применения в API

Уменьшить число элементов

Технология хотспотов, canvas

Page 72: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

72

Контейнеры карты

Page 73: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

73

Принцип работы canvas и хотспотов

Контейнер событий,

реализующий интерактивность с помощью активных

областей

graphics pane

event pane

Контейнер графики

Page 74: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

74

Как решаем проблемы большого количества DOM-элементов Способ Пример применения в API

Уменьшить число элементов

Технология хотспотов, canvas

Оптимизировать анимацию

Используем css transform и css transition где это возможно

Page 75: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

75

Поддержка технологий в браузерах Браузер/платформа Позиционирование Анимация

Safari, iOS, Bada, Chrome transform3d transform3d +

transition

Firefox top/left transform3d + transition

Opera, Android transform2d transform2d + transition

IE9 transform2d Пошаговая

IE6-8 top/left Пошаговая

Page 76: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

76

Итоговые рекомендации

−  Избегайте преждевременных оптимизаций

−  Регулярно отслеживайте показатели скорости работы

−  Уделяйте внимание конкретным случаям

−  Используйте возможности современных браузеров

Page 77: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

77

Полезные ссылки API

api.yandex.ru/maps

ymapsapi.ya.ru

facebook.com/ymapsapi

Page 78: Марина Степанова "Как мы заставили API Яндекс.Карт работать быстрее"

Марина Степанова Разработчик интерфейсов

[email protected]

@ya_mstepanova

[email protected]