csso — минимизируем css

149
CSSO — минимизируем CSS Роман Дворнов Avito Москва 2015

Upload: roman-dvornov

Post on 15-Apr-2017

1.863 views

Category:

Technology


5 download

TRANSCRIPT

Page 1: CSSO — минимизируем CSS

CSSO — минимизируем CSS

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

Москва 2015

Page 2: CSSO — минимизируем CSS

Работаю в Avito

Делаю SPA

Автор basis.js

Я…

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

Page 3: CSSO — минимизируем CSS

О чем поговорим

• Немного истории

• Минификация CSS

• CSSO

• Почему? Как? Зачем?

3

Page 4: CSSO — минимизируем CSS

4

Page 5: CSSO — минимизируем CSS

4

Page 6: CSSO — минимизируем CSS

5

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

Page 7: CSSO — минимизируем CSS

6

Все CSS-минификаторы врут

Page 8: CSSO — минимизируем CSS

Историческая справка

Это был теплый летний вечер в древней Греции…

Page 9: CSSO — минимизируем CSS

8

2000-е

Быстрые браузеры и железо

«тяжелые» сайты,«толстые» клиенты

Page 10: CSSO — минимизируем CSS

8

2000-е

Быстрые браузеры и железо

«тяжелые» сайты,«толстые» клиенты

Page 11: CSSO — минимизируем CSS

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

9

2000-е

Page 12: CSSO — минимизируем CSS

YUI Compressor The Yahoo! JavaScript and CSS Compressor

10

github.com/yui/yuicompressor

середина 2000х

Page 13: CSSO — минимизируем CSS

YUI Compressor• Написан на Java

• Регулярные выражения

11

Page 14: CSSO — минимизируем CSS

YUI Compressor• Написан на Java

• Регулярные выражения

11

Page 15: CSSO — минимизируем CSS

Почему?

Page 16: CSSO — минимизируем CSS

Почему?

Потому что Node.js и AST – наше всё

Page 17: CSSO — минимизируем CSS

CSSO CSS Optimizer от Яндекса

13

github.com/css/csso

2011

Page 18: CSSO — минимизируем CSS

Проект забросили :(

14

2013

Page 19: CSSO — минимизируем CSS

Время шло, проблемы копились…

Page 20: CSSO — минимизируем CSS

Хватит это терпеть!

16

Page 21: CSSO — минимизируем CSS

17

Письмо «счастья»

Так я стал мейтенером CSSO :)

Page 22: CSSO — минимизируем CSS

В то же время, в паралельном мире…

Page 23: CSSO — минимизируем CSS

clean-css Fast and efficient Node.js library for minifying CSS

19

github.com/jakubpawlowicz/clean-css

2011

Page 24: CSSO — минимизируем CSS

Активно набирает популярность и развивается

начиная с 2013

20

Page 25: CSSO — минимизируем CSS

cssnano A modular minifier, built on top of the PostCSS

21

github.com/ben-eb/cssnano

2015

Page 26: CSSO — минимизируем CSS

Главный плюс – PostCSS Cырой, но смелый

22

Page 27: CSSO — минимизируем CSS

23

cssnanocsso clean-cssYUI Compressor fork

ycssmin

Наши герои

Page 28: CSSO — минимизируем CSS

23

cssnanocsso clean-cssYUI Compressor fork

ycssmin

Наши герои

Page 29: CSSO — минимизируем CSS

23

cssnanocsso clean-cssYUI Compressor fork

ycssmin

Наши герои

Page 30: CSSO — минимизируем CSS

23

cssnanocsso clean-cssYUI Compressor fork

ycssmin

Наши герои

Page 31: CSSO — минимизируем CSS

23

cssnanocsso clean-cssYUI Compressor fork

ycssmin

Наши герои

Page 32: CSSO — минимизируем CSS

23

cssnanocsso clean-cssYUI Compressor fork

ycssmin

Наши герои

Page 33: CSSO — минимизируем CSS

23

cssnanocsso clean-cssYUI Compressor fork

ycssmin

Наши герои

Page 34: CSSO — минимизируем CSS

23

cssnanocsso clean-cssYUI Compressor fork

ycssmin

Наши герои

Page 35: CSSO — минимизируем CSS

А если сравнить?

Page 36: CSSO — минимизируем CSS

25

clean-css 3.4.8 cssnano 3.4.0 csso 1.4.4 csso-next

bootstrap.css)147 427 байт

118 186)284 ms

117 440)1 925 ms

121 476)1 104 ms

118 437)507 ms

foundation.css)200 341 байт

142 667)464 ms

145 030)1 992 ms

149 537)1 477 ms

147 943)979 ms

normalize.css)7 707 байт

1792)5 ms

1824)17 ms

1 855)19 ms

1831)18 ms

reset.css)1 092 байт

758 )3 ms

773)13 ms

747)20 ms

747)25 ms

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

Page 37: CSSO — минимизируем CSS

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

Page 38: CSSO — минимизируем CSS

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

27

Page 39: CSSO — минимизируем CSS

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

28

Page 40: CSSO — минимизируем CSS

29

clean-css 3.4.8 cssnano 3.4.0 csso 1.4.4 csso-next

ActiAgent.ru)602 233 байт

430 240)1 213 ms

439 730)23 270 ms

439 030)3 460 ms

438 302)1 771 ms

в gzip ~54Kb – фактор сжатия 8 и в теории, результат можно улучшить

Наши цифры

Page 41: CSSO — минимизируем CSS

Минификация

Page 42: CSSO — минимизируем CSS

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

Page 43: CSSO — минимизируем CSS

Виды минификации

• Удаление

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

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

32

Page 44: CSSO — минимизируем CSS

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

33

Page 45: CSSO — минимизируем CSS

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

Page 46: CSSO — минимизируем CSS

Потому что

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

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

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

• Хаки

35

Page 47: CSSO — минимизируем CSS

Самое главное минифицированный CSS

должен делать то же самое, что и оригинальный

36

Page 48: CSSO — минимизируем CSS

Удаление

Page 49: CSSO — минимизируем CSS

Комментарии

Page 50: CSSO — минимизируем CSS

Все просто – удаляем все комметарии!

39

Page 51: CSSO — минимизируем CSS

40

.h/* .. */1:before { con/* .. */tent: "I'm evil";}

Оригинальный CSS (не сработает)Пример №1

Page 52: CSSO — минимизируем CSS

40

.h/* .. */1:before { con/* .. */tent: "I'm evil";}

Оригинальный CSS (не сработает)

.h1:before { content: "I'm evil";}

csso, clean-css (заботает!)

Пример №1

Page 53: CSSO — минимизируем CSS

40

.h/* .. */1:before { con/* .. */tent: "I'm evil";}

Оригинальный CSS (не сработает)

.h1:before { content: "I'm evil";}

csso, clean-css (заботает!)

НЕВЕРН

О

Пример №1

Page 54: CSSO — минимизируем CSS

40

.h/* .. */1:before { con/* .. */tent: "I'm evil";}

Оригинальный CSS (не сработает)

.h1:before { content: "I'm evil";}

csso, clean-css (заботает!)

.h 1:before { content: "I'm evil";}

cssnano (все странно)

НЕВЕРН

О

Пример №1

Page 55: CSSO — минимизируем CSS

40

.h/* .. */1:before { con/* .. */tent: "I'm evil";}

Оригинальный CSS (не сработает)

.h1:before { content: "I'm evil";}

csso, clean-css (заботает!)

.h 1:before { content: "I'm evil";}

cssnano (все странно)

CssSyntaxError

НЕВЕРН

О

Пример №1

Page 56: CSSO — минимизируем CSS

40

.h/* .. */1:before { con/* .. */tent: "I'm evil";}

Оригинальный CSS (не сработает)

.h1:before { content: "I'm evil";}

csso, clean-css (заботает!)

.h 1:before { content: "I'm evil";}

cssnano (все странно)

CssSyntaxError

НЕВЕРН

О

НЕВЕРН

О

Пример №1

Page 57: CSSO — минимизируем CSS

41

.h/* .. */1:before { con/* .. */tent: "I'm evil";}

Оригинальный CSS (не сработает)

Правильно

Удалять то, что явно не сработает (декларации, правила)

Пример №1

Page 58: CSSO — минимизируем CSS

42

@media all and/* .. */(..) { * { color: green; }}

Оригинальный CSS (работает)Пример №2

Page 59: CSSO — минимизируем CSS

42

@media all and/* .. */(..) { * { color: green; }}

Оригинальный CSS (работает)

@media all and(..) { * { color: green; }}

csso, clean-css (не работает)

Пример №2

Page 60: CSSO — минимизируем CSS

42

@media all and/* .. */(..) { * { color: green; }}

Оригинальный CSS (работает)

@media all and(..) { * { color: green; }}

csso, clean-css (не работает)

НЕВЕРН

О

Пример №2

Page 61: CSSO — минимизируем CSS

42

@media all and/* .. */(..) { * { color: green; }}

Оригинальный CSS (работает)

@media all and(..) { * { color: green; }}

csso, clean-css (не работает)

@media all and (..) { * { color: green; }}

cssnano

НЕВЕРН

О

Пример №2

Page 62: CSSO — минимизируем CSS

42

@media all and/* .. */(..) { * { color: green; }}

Оригинальный CSS (работает)

@media all and(..) { * { color: green; }}

csso, clean-css (не работает)

@media all and (..) { * { color: green; }}

cssnano ✔

НЕВЕРН

О

Пример №2

Page 63: CSSO — минимизируем CSS

Пробельные символы

Page 64: CSSO — минимизируем CSS

Основной выигрыш

44

Page 65: CSSO — минимизируем CSS

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

45

Page 66: CSSO — минимизируем CSS

46

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

Не правильно

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

Правильно

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

Page 67: CSSO — минимизируем CSS

Другое

Page 68: CSSO — минимизируем CSS

Чтобы бы еще такого удалить?• Правила с неверными селекторами

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

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

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

• …

48

Page 69: CSSO — минимизируем CSS

Чтобы бы еще такого удалить?• Единицы измерения у нулей0px " 0

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

• …

49

Page 70: CSSO — минимизируем CSS

Нюансы, нюансы…• 0px " 0 можно

50

Page 71: CSSO — минимизируем CSS

Нюансы, нюансы…• 0px " 0 можно

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

50

Page 72: CSSO — минимизируем CSS

Нюансы, нюансы…• 0px " 0 можно

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

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

50

Page 73: CSSO — минимизируем CSS

Замена

Page 74: CSSO — минимизируем CSS

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

52

Page 75: 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 " #483d8b53

Page 76: CSSO — минимизируем CSS

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

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

• font-weight:bold " font-weight:700

• background:none " background:0 0

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

• …

54

Page 77: CSSO — минимизируем CSS

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

Page 78: CSSO — минимизируем CSS

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

Page 79: CSSO — минимизируем CSS

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

57

Page 80: CSSO — минимизируем CSS

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

Page 81: CSSO — минимизируем CSS

59

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

.foo { color: green;}

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

Page 82: CSSO — минимизируем CSS

60

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

.foo { color: rgba(…);}

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

Правильно?

Page 83: CSSO — минимизируем CSS

60

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

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

ЕРНО

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

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

Правильно?

Page 84: CSSO — минимизируем CSS

61

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

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

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

Page 85: CSSO — минимизируем CSS

61

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

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

НЕВЕРН

О

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

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

Page 86: CSSO — минимизируем CSS

62

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

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

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

Page 87: CSSO — минимизируем CSS

62

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

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

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

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

Page 88: CSSO — минимизируем CSS

63

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

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

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

Page 89: CSSO — минимизируем CSS

63

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

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

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

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

Page 90: CSSO — минимизируем CSS

64

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

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

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

Page 91: CSSO — минимизируем CSS

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

65

Page 92: CSSO — минимизируем CSS

66

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

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

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

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

Page 93: CSSO — минимизируем CSS

67

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

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

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

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

Page 94: CSSO — минимизируем CSS

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

68

Page 95: CSSO — минимизируем CSS

Подводя итоги• Похожие методы

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

• Реструктуризация делается в лоб → ошибки изменения семантики

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

69

Page 96: CSSO — минимизируем CSS

70

Так почему же CSSO?

Page 97: CSSO — минимизируем CSS

71

Page 98: CSSO — минимизируем CSS

Смотрим под капот

Page 99: CSSO — минимизируем CSS

73

CSS

сжатый CSS

Процесс минификации

Page 100: CSSO — минимизируем CSS

73

CSS

сжатый CSS

Парсер

Процесс минификации

Page 101: CSSO — минимизируем CSS

73

CSS

сжатый CSS

ASTПарсер

Процесс минификации

Page 102: CSSO — минимизируем CSS

73

CSS

сжатый CSS

ASTПарсер

Компрессор

Процесс минификации

Page 103: CSSO — минимизируем CSS

73

CSS

сжатый CSS

AST

AST

Парсер

Компрессор

Процесс минификации

Page 104: CSSO — минимизируем CSS

73

CSS

сжатый CSS

AST

AST

Парсер

Компрессор

Транслятор

Процесс минификации

Page 105: CSSO — минимизируем CSS

73

CSS

сжатый CSS

AST

AST

Парсер

Компрессор

Транслятор

Процесс минификации

Page 106: CSSO — минимизируем CSS

73

CSS

сжатый CSS

AST

AST

Парсер

Компрессор

Транслятор

Процесс минификации

Минификатор

Page 107: CSSO — минимизируем CSS

74

AST

Наш процесс сборки

Компрессор

Минификатор

Page 108: CSSO — минимизируем CSS

74

AST

Наш процесс сборки

Компрессор

Минификатор

Page 109: CSSO — минимизируем CSS

74

AST

Наш процесс сборки

Анализ …Обработка ссылок

Компрессор

Сокращение имен

Сборщик

Минификатор

Page 110: CSSO — минимизируем CSS

74

AST

Наш процесс сборки

Анализ …Обработка ссылок

Компрессор

Сокращение имен

Сборщик

Минификатор

Транслятор

Page 111: CSSO — минимизируем CSS

Минификатор должен быть опциональным и предоставлять возможность вмешательства

75

Page 112: CSSO — минимизируем CSS

В этом плане• CSSO – детальное AST (gonzales), хорошо подходит для этой задачи

• clean-css – использует внутреннее представление, не подходит

• cssnano – лишь компрессор, использует AST PostCSS, сам парсит селекторы и значения

76

Page 113: CSSO — минимизируем CSS

CSSO – рефакторинг

Page 114: CSSO — минимизируем CSS

Этап 1 – 1.3.12• Первый патч

• Разобрал PR

• Разобрал и классифицировал тикеты

78

Page 115: CSSO — минимизируем CSS

Этап 2 – 1.4• Перенес наши фиксы в CSSO

• Обновление API и инфраструктуры

• Реорганизация файлов

• Исправлено множество багов (60+ тикетов)

• Базовый рефакторинг компрессора79

Page 116: CSSO — минимизируем CSS

Этап 3 – в работе• Рефакторинг компрессора

• Внутренний формат AST

• Ускорение компрессии в 2-3 раза

80

Page 117: CSSO — минимизируем CSS

Планы

Page 118: CSSO — минимизируем CSS

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

Page 119: CSSO — минимизируем CSS

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

• Режим линтера

• Source Maps

• Новые оптимизации

• Новый парсер

• Инструменты83

Page 120: CSSO — минимизируем CSS

Новые оптимизации

Page 121: CSSO — минимизируем CSS

85

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

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

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

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

Page 122: CSSO — минимизируем CSS

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

86

Page 123: CSSO — минимизируем CSS

Это позволит• Делать больше структурных изменений

• Удалять мертвый код

• Девать советы о неоптимальном CSS (лишний код, слишком сильный селектор и т.д.)

87

Page 124: CSSO — минимизируем CSS

88

clean-css 3.4.8 cssnano 3.4.0 csso 1.4.4 csso-next

ActiAgent.ru)602 233 байт

430 240)1 213 ms

439 730)23 270 ms

439 030)3 460 ms

438 302)1 771 ms

Наколеночный тест – 307 041)в gzip 48kb, фактор сжатия 6.4 (было 8)

Вспомним таблицу

Page 125: CSSO — минимизируем CSS

Специфично для проекта, зависит от стека и подходов

создания CSS

89

Page 126: CSSO — минимизируем CSS

Новый парсер

Page 127: CSSO — минимизируем CSS

Чтобы лучше понимать CSS, нужно много деталей

о свойствах, значениях и селекторах

91

Page 128: CSSO — минимизируем CSS

Такие детали может предоставлять парсерНо такого пока нет

92

Page 129: CSSO — минимизируем CSS

Начало работы github.com/lahmatiy/css-parser

93

Первые результаты оптимистичные

Page 130: CSSO — минимизируем CSS

Цели перед парсером• Скорость и эффективность по памяти

• Толерантность к ошибкам

• Детальное AST (информация о свойствах, значениях, селекторах и @-правилах)

• Поддержка поточности

94

Page 131: CSSO — минимизируем CSS

Инструменты

Page 132: CSSO — минимизируем CSS

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

96

Page 133: CSSO — минимизируем CSS

Все плохо• Нет хорошего детального парсера

• Нет стандарта AST

• Нет инструментов для анализа

• Нет инструментов для сравнения

• Даже линтеров нет (кроме проверки стиля)

97

Page 134: CSSO — минимизируем CSS

AST

Page 135: CSSO — минимизируем CSS

AST

Форматирование

Page 136: CSSO — минимизируем CSS

AST

Компрессор

Форматирование

Page 137: CSSO — минимизируем CSS

AST

Компрессор

Форматирование

AST

Page 138: CSSO — минимизируем CSS

AST

Компрессор

Линтер

Форматирование

AST

Page 139: CSSO — минимизируем CSS

AST

Компрессор

Линтер

Форматирование

AST

Page 140: CSSO — минимизируем CSS

AST

Компрессор

Линтер

Форматирование

Анализ

AST

Page 141: CSSO — минимизируем CSS

AST

Компрессор

Линтер

Форматирование

Анализ

AST

Отчет

Page 142: CSSO — минимизируем CSS

AST

Компрессор

Линтер

Форматирование

Анализ

и т.д.

AST

Отчет

Page 143: CSSO — минимизируем CSS

99

github.com/lahmatiy/css-ast-explorer

Инструменты для инструментов

Page 144: CSSO — минимизируем CSS

В заключении

Page 145: CSSO — минимизируем CSS

Выбирайте с умом

Page 146: CSSO — минимизируем CSS

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

Page 147: CSSO — минимизируем CSS

103

Делайте инструменты

Page 148: CSSO — минимизируем CSS

Сделаем CSS лучше!

Page 149: CSSO — минимизируем CSS

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

[email protected]

Вопросы?