csso — сжимаем css

116
CSSO — сжимаем CSS Роман Дворнов Avito Минск 2016

Upload: fdconf

Post on 16-Apr-2017

7.697 views

Category:

Education


0 download

TRANSCRIPT

Page 1: CSSO — сжимаем CSS

CSSO — сжимаем CSS

Роман Дворнов Avito

Минск 2016

Page 2: CSSO — сжимаем CSS

Работаю в Avito

Делаю SPA

Автор basis.js

Мейтенер CSSO

За любую движуху, кроме голодовки ;)

Page 3: CSSO — сжимаем CSS

3

Page 4: CSSO — сжимаем CSS

3

Page 5: CSSO — сжимаем CSS

4

«Хэппи-энда» не будет

Page 6: CSSO — сжимаем CSS

5

CSS-минификаторы не нужны!

Page 7: CSSO — сжимаем CSS

5Шутка… почтиCSS-минификаторы не нужны!

Page 8: CSSO — сжимаем CSS

6

Быстрые браузеры

«Тяжелые» сайты

Page 9: CSSO — сжимаем CSS

6

Быстрые браузеры

«Тяжелые» сайты

много CSS – нужно сжимать

Page 10: CSSO — сжимаем CSS

Чем сжимать?

Page 11: CSSO — сжимаем CSS

8

cssnanocsso clean-cssYUI Compressor fork

ycssmin

Герои сегодняшнего дня

Page 12: CSSO — сжимаем CSS

8

cssnanocsso clean-cssYUI Compressor fork

ycssmin

Герои сегодняшнего дня

Page 13: CSSO — сжимаем CSS

8

cssnanocsso clean-cssYUI Compressor fork

ycssmin

Герои сегодняшнего дня

Page 14: CSSO — сжимаем CSS

8

cssnanocsso clean-cssYUI Compressor fork

ycssmin

Герои сегодняшнего дня

Page 15: CSSO — сжимаем CSS

8

cssnanocsso clean-cssYUI Compressor fork

ycssmin

Герои сегодняшнего дня

Page 16: CSSO — сжимаем CSS

8

cssnanocsso clean-cssYUI Compressor fork

ycssmin

Герои сегодняшнего дня

Page 17: CSSO — сжимаем CSS

8

cssnanocsso clean-cssYUI Compressor fork

ycssmin

Герои сегодняшнего дня

Page 18: CSSO — сжимаем CSS

8

cssnanocsso clean-cssYUI Compressor fork

ycssmin

Герои сегодняшнего дня

Page 19: CSSO — сжимаем CSS

9

Минификаторов гораздо больше, но либо не популярны

либо слабо развиваются

Page 20: CSSO — сжимаем CSS

Сравниваем

Page 21: CSSO — сжимаем CSS

11

clean-css 3.4.9 cssnano 3.5.2 csso 2.0.0

bootstrap.css147 427 байт

118 186273 ms

117 4401 813 ms

117 756169 ms

foundation.css200 341 байт

142 667389 ms

145 0301 983 ms

144 262222 ms

normalize.css7 707 байт

17925 ms

182417 ms

1 8314 ms

reset.css1 092 байт

758 3 ms

77313 ms

7473 ms

goalsmashers.github.io/css-minification-benchmark/

Page 22: CSSO — сжимаем CSS

Выглядит как-то так…

Page 23: CSSO — сжимаем CSS

Библиотеки пишутся оптимально,

реальный CSS – нет

13

Page 24: CSSO — сжимаем CSS

14

clean-css 3.4.9 cssnano 3.5.2 csso 2.0.0

ActiAgent.ru602 233 байт (5 мес назад)

430 2401 077 ms

439 02423 270 ms

435 588531 ms

ActiAgent.ru822 021 байт (сейчас)

587 9061 705 ms

604 50348 550 ms

595 834616 ms

В gzip фактор сжатия 8 (~72Kb) Результат можно улучшить!

Наши цифры

Page 25: CSSO — сжимаем CSS

Минификация

Page 26: CSSO — сжимаем CSS

Все минификаторы работают похоже

Page 27: CSSO — сжимаем CSS

Базовая минификация

• Удаление

• Замена значений

• Структурная оптимизация

17

Page 28: CSSO — сжимаем CSS

Кажется, минификация CSS – это про знание спецификаций

18

Page 29: CSSO — сжимаем CSS

На деле – постоянно что-то вылазит

Page 30: CSSO — сжимаем CSS

Потому что

• Спецификации меняются

• Разная поддержка браузерами

• Баги браузеров

• Хаки

20

Page 31: CSSO — сжимаем CSS

Самое главное минификатор не должен ломать или чинить CSS

21

Page 32: CSSO — сжимаем CSS

Удаление

Page 33: CSSO — сжимаем CSS

Удаляем• Пробелы и комментарии (основной выигрыш)

• Правила с неверными селекторами

• Пустые правила

• Неверные декларации

• Неверно расположенные @import, @charset

• …

23

Page 34: CSSO — сжимаем CSS

Но нужно учитывать особенности спецификаций

24

Page 35: CSSO — сжимаем CSS

25

calc(4 * 2em - 10% / 3)Оригинальный CSS

Не правильно

calc(4*2em-10%/3)

Правильно

calc(4*2em - 10%/3)

Удаление пробелов

Page 36: CSSO — сжимаем CSS

Еще примеры• Единицы измерения у нулей0px ! 0

• Кавычки[attr="name"] ! [attr=name] url('image.png') ! url(image.png)

• …

26

Page 37: CSSO — сжимаем CSS

Но всегда есть нюансы…• 0px ! 0 можно

27

Page 38: CSSO — сжимаем CSS

Но всегда есть нюансы…• 0px ! 0 можно

• 0deg ! 0 нельзя, так как не длина

27

Page 39: CSSO — сжимаем CSS

Но всегда есть нюансы…• 0px ! 0 можно

• 0deg ! 0 нельзя, так как не длина

• flex: 1 0 0px ! flex: 1 0 0 нельзя, сломается в IE

27

Page 40: CSSO — сжимаем CSS

Замена

Page 41: CSSO — сжимаем CSS

Замена значений на более короткие эквиваленты

29

Page 42: CSSO — сжимаем CSS

Наиболее интересное: цвет• hsl ! rgb, hsla ! rgba

• rgb(100%, 0, 0) ! rgb(255, 0, 0)

• rgba(a, b, c, 1) ! rgb(a, b, c)

• нормализация: rgb(500, -100, 0) ! rgb(255, 0, 0)

• rgb(255, 0, 0) ! #ff0000

• #aabbcc ! #abc

• #ff0000 ! red, darkslateblue ! #483d8b30

Page 43: CSSO — сжимаем CSS

Что еще• Нормализация чисел: 0.00 ! 0 или 0.123 ! .123

• Специфика для свойств

• font-weight:bold ! font-weight:700

• background:none ! background:0 0

• from ! 0%, 100% ! to в @keyframes

• …

31

Page 44: CSSO — сжимаем CSS

Не сильно эффективно

Page 45: CSSO — сжимаем CSS

Структурная оптимизация

Page 46: CSSO — сжимаем CSS

Слияние и перемещение деклараций и правил

34

Page 47: CSSO — сжимаем CSS

Самая сложная и ресурсоемкая оптимизация

Page 48: CSSO — сжимаем CSS

36

.foo { color: red; color: green;}

.foo { color: green;}

Удаление ненужных деклараций

color: red никогда не будет использовано браузером – можно удалить

Page 49: CSSO — сжимаем CSS

Внимание! Викторина Насколько вы хороший минификатор ;)

37

Page 50: CSSO — сжимаем CSS

38

.foo { color: red; color: rgba(…);}

.foo { color: rgba(…);}

Удаление ненужных деклараций

Правильно?

Page 51: CSSO — сжимаем CSS

38

.foo { color: red; color: rgba(…);}

.foo { color: rgba(…);} НЕВ

ЕРНО

В старых браузерахне поддерживается rgba()

Удаление ненужных деклараций

Правильно?

Page 52: CSSO — сжимаем CSS

39

.foo { color: red;}.bar { color: green;}.qux { color: red;}

.foo, .qux { color: red;}.bar { color: green;}

ПерегруппировкаПравильно?

Page 53: CSSO — сжимаем CSS

39

.foo { color: red;}.bar { color: green;}.qux { color: red;}

.foo, .qux { color: red;}.bar { color: green;}

НЕВЕРН

О

Разный эффект, например:<div class="bar qux">

ПерегруппировкаПравильно?

Page 54: CSSO — сжимаем CSS

40

span { color: red;}div { color: green;}ul { color: red;}

span, ul { color: red;}div { color: green;}

ПерегруппировкаПравильно?

Page 55: CSSO — сжимаем CSS

40

span { color: red;}div { color: green;}ul { color: red;}

span, ul { color: red;}div { color: green;}

Правильно, у элементов одно имя

ПерегруппировкаПравильно?

Page 56: CSSO — сжимаем CSS

41

.foo { color: red;}span { color: green;}.bar { color: red;}

.foo, .bar { color: red;}span { color: green;}

ПерегруппировкаПравильно?

Page 57: CSSO — сжимаем CSS

41

.foo { color: red;}span { color: green;}.bar { color: red;}

.foo, .bar { color: red;}span { color: green;}

Правильно,разная специфичность –порядок не важен

ПерегруппировкаПравильно?

Page 58: CSSO — сжимаем CSS

42

.foo { color: red;}.bar:not(.baz) { color: red;}

.foo,

.bar:not(.baz) { color: red;}

ПерегруппировкаПравильно?

Page 59: CSSO — сжимаем CSS

42

.foo { color: red;}.bar:not(.baz) { color: red;}

.foo,

.bar:not(.baz) { color: red;}

ПерегруппировкаПравильно?

Старые браузеры не поддерживают :not()

НЕВЕРН

О

Page 60: CSSO — сжимаем CSS

43

И т.д. и т.п.

Page 61: CSSO — сжимаем CSS

44

.foo { color: red; width: 100px;}.bar { color: green; width: 100px;}

.foo, .bar { width: 100px;}.foo { color: red;}.bar { color: green;}

Вынос общих частей

Page 62: CSSO — сжимаем CSS

Выносить можно в каждом случае по-разному

45

Page 63: CSSO — сжимаем CSS

46

.foo { color: red;}.bar { color: red; color: rgba(..);}

.foo, .bar { color: red;}.bar { color: rgba(..);}

Вынос общих частей

В данном примере можно только в начало

Page 64: CSSO — сжимаем CSS

47

.foo { color: rgba(..);}.bar { color: red; color: rgba(..);}

.bar { color: red;}.foo, .bar { color: rgba(..);}

Вынос общих частей

В данном примере можно только в конец

Page 65: CSSO — сжимаем CSS

Очень много нюансов, нужно знать специфику свойств и селекторов

48

Page 66: CSSO — сжимаем CSS

Базовая оптимизация• Похожие методы

• Основной выигрыш дает удаление пробелов

• Много хаков

• У всех есть ошибки

49

Page 67: CSSO — сжимаем CSS

Продвинутые оптимизации

Page 68: CSSO — сжимаем CSS

Usage data

Usage data

Page 69: CSSO — сжимаем CSS

52

.foo { color: red;}.bar { color: green;}.qux { color: red;}

.foo, .qux { color: red;}.bar { color: green;}

Трансформация не безопасна, так как мы не знаем как используется CSS в разметке

Вспомним пример

Page 70: CSSO — сжимаем CSS

Но что, если мы знаем как используется?

53

Page 71: CSSO — сжимаем CSS

Фильтрация

Page 72: CSSO — сжимаем CSS

55

{ "classes": ["foo", "bar"], "tags": ["ul", "li"]}

.foo { color: red }div.bar { color: green }ul li, ol li { color: blue }

usage.json

CSS

+ .foo { color: red }ul li { color: blue }

Результат

Page 73: CSSO — сжимаем CSS

Scopes

Page 74: CSSO — сжимаем CSS

Пример

57

.module1-foo { background: red; }

.module1-bar { font-size: 1.5em; background: yellow; }

.module2-baz { background: red; }

.module2-qux { font-size: 1.5em; background: yellow; width: 50px; }

Нельзя объединить .module1-foo и .module2-baz,

так как между ними .module1-bar

Page 75: CSSO — сжимаем CSS

Пример

58

.module1-foo { background: red; }

.module1-bar { font-size: 1.5em; background: yellow; }

.module2-baz { background: red; }

.module2-qux { font-size: 1.5em; background: yellow; width: 50px; }

Минификатор не знает, что имена не смешиваются

и можно безопасно перемещать

Page 76: CSSO — сжимаем CSS

Usage data

59

{ "scopes": [ ["module1-foo", "module1-bar"], ["module2-baz", "module2-qux"] ]}

Так мы гарантируем, что классы module1-* и module2-*

не встречаются на одном элементе

Page 77: CSSO — сжимаем CSS

Результат с usage data

60

.module1-foo,.module2-baz{background:red}

.module1-bar,.module2-qux{font-size:1.5em;background:#ff0}

.module2-qux{width:50px}

На 29 байт меньше, чем без usage data

Page 78: CSSO — сжимаем CSS

61

Уже поддерживается в CSSO!

Page 79: CSSO — сжимаем CSS

Что это дало нашему проекту

• 823 Kb Оригинальный CSS

• 596 Kb Базовая минификация

• 437 Kb Минификация с usage data

62

Улучшение результата на 159Kb (26%)

Page 80: CSSO — сжимаем CSS

Как генерировать usage data?

63

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

Page 81: CSSO — сжимаем CSS

Rename

Rename

Page 82: CSSO — сжимаем CSS

65

.foo { color: red }

.foo.bar { color: green }

.a { color: red }

.a.b { color: green }

{ "foo": "a", "bar": "b"}

rename map

Результат

CSS+

Page 83: CSSO — сжимаем CSS

66

• 823 Kb Оригинальный CSS

• 596 Kb Базовая минификация

• 385 Kb Rename (пока вне CSSO)

Улучшение результата на 211Kb (35%)

Что это дало нашему проекту

Page 84: CSSO — сжимаем CSS

67

Улучшение результата на 364Kb (61%)

Все вместе

• 823 Kb Оригинальный CSS

• 596 Kb Базовая минификация

• 232 Kb Rename + Usage data

Page 85: CSSO — сжимаем CSS

Должно ли это быть в минификаторе?

68

Page 86: CSSO — сжимаем CSS

69

.foo,

.bar { color: red;}.foo:hover,.bar:hover { color: green}

.a { color: red }

.a:hover { color: green }

{ "foo": "a", "bar": "a"}

rename map

РезультатCSS

+

Page 87: CSSO — сжимаем CSS

Кто будет писать такой CSS?

70

Usage data!

Page 88: CSSO — сжимаем CSS

71

.foo { color: red;}.foo:hover { color: green}

.bar { color: red;}.bar:hover { color: green}

РезультатCSS + usage data.foo,.bar { color: red;}.foo:hover,.bar:hover { color: green}

Page 89: CSSO — сжимаем CSS

В разработке – скоро в CSSO

Page 90: CSSO — сжимаем CSS

73

• ~10 Kb дополнительного выигрыша (~3-4%)

• 1431 удаленный селектор из 6904

Селекторов стало на ~20% меньше

Что это дало нашему проектупредварительные оценки

Page 91: CSSO — сжимаем CSS

74

Сжимать или не сжимать?

Page 92: CSSO — сжимаем CSS

На что влияет минификация?

75

Page 93: CSSO — сжимаем CSS

76

Network

Paint

Parse Stylesheet

Recalculate Style

Layout

Как CSS превращается в картинку

Page 94: CSSO — сжимаем CSS

77

Network

Paint

Parse Stylesheet

Recalculate Style

Layout

Влияние характеристик CSS на скорость

Влияют количественные характеристики CSS (размер, кол-во селекторов и т.д.)

Влияют качественные характеристики CSS (сложность расчетов и отрисовки)

Page 95: CSSO — сжимаем CSS

78

Network

Paint

Parse Stylesheet

Recalculate Style

Layout

Автоматизация улучшений

Компрессия может оказать положительный эффект

Пока нет предпосылок, что задача решается

Page 96: CSSO — сжимаем CSS

79

Network

Paint

Parse Stylesheet

Recalculate Style

Layout

Network

Решение: gzip, SDCH …

Имеет эффект только для холодной загрузки

Неоптимизированный CSS сжимается лучше

Page 97: CSSO — сжимаем CSS

80

Network

Paint

Parse Stylesheet

Recalculate Style

Layout

Parse Stylesheet

Решение: сжатие CSS

Тут gzip уже не играет роли, выполняется всегда на старте + мутация DOM

Меньше текста – меньше парсить

Page 98: CSSO — сжимаем CSS

Без сжатия 823 Kb – 35ms Базовое сжатие 596 Kb – 29ms

Rename 385 Kb – 24ms Rename + usage data 232 Kb – 22ms

81

Наколеночные тестВлияние разного уровня сжатия на время парсинга

Размер уменьшился в ~4 раза, но время лишь на ~50%

(Chrome на MacBook Air)

Page 99: CSSO — сжимаем CSS

Win10 Desktop 19ms → 11ms Nexus 5X 68ms → 44ms

Samsung Galaxy Note 2 158ms → 108ms 82

Наколеночные тесты

Ранее, на других устройствах, были получены более обнадеживающие цифры при улучшении сжатия

CSS 316Kb 215Kb (-39.5%)+ usage data

Page 100: CSSO — сжимаем CSS

83

Network

Paint

Parse Stylesheet

Recalculate Style

Layout

Parse Stylesheet

Решение: rename и др.

Уменьшение кол-ва селекторов, их сложности

Пока гипотезы, цифр нет, но будут как только фича появится в CSSO ;)

Page 101: CSSO — сжимаем CSS

Сжимать или не сжимать?

84

Page 102: CSSO — сжимаем CSS

Сжимать или не сжимать?

84

Да! Хуже не будетХотя эффект – предмет для исследований

Page 103: CSSO — сжимаем CSS

CSSO – новая жизнь

Page 104: CSSO — сжимаем CSS

Что изменилось• В 10+ раз быстрее

• В 8+ раз меньше потребление памяти

• Исправлена большая часть проблем и багов

• Улучшена кодовая база и API

• Больше скачиваний и звезд на GitHub ;)86

Page 105: CSSO — сжимаем CSS

87

Врем

я сж

атия

CSS

(600

Kb)

500 ms

1 000 ms

1 500 ms

2 000 ms

2 500 ms

3 000 ms

3 500 ms

4 000 ms

4 500 ms

5 000 ms

5 500 ms

6 000 ms

Версия CSSO

1.4.0 1.5.0 1.6.0 1.7.0 1.8.0 2.0

1 050 msclean-css

Изменение по скорости

csso500 ms

cssnano23 250 ms

Page 106: CSSO — сжимаем CSS

postcss-csso

88

Плагин для PostCSS, aльтернатива cssnano

Работает почти также быстро как CSSO отдельно

Под капотом конвертация AST

github.com/lahmatiy/postcss-csso

Page 107: CSSO — сжимаем CSS

89

1 300 000+ скачиваний в месяцx9 с октября 2015

Page 108: CSSO — сжимаем CSS

Новое• Source Maps

• Usage data

• Лучше поддержка "новых" частей в CSS

• Лучше сообщения об ошибках

• Поддержка stdin

• Новый формат AST

90

Page 109: CSSO — сжимаем CSS

Планы

Page 110: CSSO — сжимаем CSS

Главная цель – лучший минификатор

Page 111: CSSO — сжимаем CSS

Coming soon• Новые оптимизации и алгоритмы: быстрее и правильно

• Учет поддерживаемых браузеров

• Семейства свойств и сортировка деклараций

• Нормализация имен и переименование

• Понимание структуры shorthand-значений

• Применение статистики

93

Page 112: CSSO — сжимаем CSS

В заключении

Page 113: CSSO — сжимаем CSS

Любите CSS, читайте спеки

Page 114: CSSO — сжимаем CSS

96Используйте CSSO :)

Page 115: CSSO — сжимаем CSS

97

Все новое в твитере @cssoptimizer

Page 116: CSSO — сжимаем CSS

Роман Дворнов @rdvornov

[email protected]

Вопросы?

github.com/css/csso