CSSO — сжимаем CSS (часть 2)
-
Upload
roman-dvornov -
Category
Technology
-
view
852 -
download
0
Transcript of CSSO — сжимаем CSS (часть 2)
CSSO — сжимаем CSS
Роман Дворнов Avito
Минск 2016
Работаю в Avito
Делаю SPA
Автор basis.js
Мейтенер CSSO
За любую движуху, кроме голодовки ;)
3
3
4
«Хэппи-энда» не будет
5
CSS-минификаторы не нужны!
5Шутка… почтиCSS-минификаторы не нужны!
6
Быстрые браузеры
«Тяжелые» сайты
6
Быстрые браузеры
«Тяжелые» сайты
много CSS – нужно сжимать
Чем сжимать?
8
cssnanocsso clean-cssYUI Compressor fork
ycssmin
Герои сегодняшнего дня
8
cssnanocsso clean-cssYUI Compressor fork
ycssmin
Герои сегодняшнего дня
8
cssnanocsso clean-cssYUI Compressor fork
ycssmin
Герои сегодняшнего дня
8
cssnanocsso clean-cssYUI Compressor fork
ycssmin
Герои сегодняшнего дня
8
cssnanocsso clean-cssYUI Compressor fork
ycssmin
Герои сегодняшнего дня
8
cssnanocsso clean-cssYUI Compressor fork
ycssmin
Герои сегодняшнего дня
8
cssnanocsso clean-cssYUI Compressor fork
ycssmin
Герои сегодняшнего дня
8
cssnanocsso clean-cssYUI Compressor fork
ycssmin
Герои сегодняшнего дня
9
Минификаторов гораздо больше, но либо не популярны
либо слабо развиваются
Сравниваем
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/
Выглядит как-то так…
Библиотеки пишутся оптимально,
реальный CSS – нет
13
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) Результат можно улучшить!
Наши цифры
Минификация
Все минификаторы работают похоже
Базовая минификация
• Удаление
• Замена значений
• Структурная оптимизация
17
Кажется, минификация CSS – это про знание спецификаций
18
На деле – постоянно что-то вылазит
Потому что
• Спецификации меняются
• Разная поддержка браузерами
• Баги браузеров
• Хаки
20
Самое главное минификатор не должен ломать или чинить CSS
21
Удаление
Удаляем• Пробелы и комментарии (основной выигрыш)
• Правила с неверными селекторами
• Пустые правила
• Неверные декларации
• Неверно расположенные @import, @charset
• …
23
Но нужно учитывать особенности спецификаций
24
25
calc(4 * 2em - 10% / 3)Оригинальный CSS
Не правильно
calc(4*2em-10%/3)
Правильно
calc(4*2em - 10%/3)
Удаление пробелов
Еще примеры• Единицы измерения у нулей0px ! 0
• Кавычки[attr="name"] ! [attr=name] url('image.png') ! url(image.png)
• …
26
Но всегда есть нюансы…• 0px ! 0 можно
27
Но всегда есть нюансы…• 0px ! 0 можно
• 0deg ! 0 нельзя, так как не длина
27
Но всегда есть нюансы…• 0px ! 0 можно
• 0deg ! 0 нельзя, так как не длина
• flex: 1 0 0px ! flex: 1 0 0 нельзя, сломается в IE
27
Замена
Замена значений на более короткие эквиваленты
29
Наиболее интересное: цвет• 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
Что еще• Нормализация чисел: 0.00 ! 0 или 0.123 ! .123
• Специфика для свойств
• font-weight:bold ! font-weight:700
• background:none ! background:0 0
• from ! 0%, 100% ! to в @keyframes
• …
31
Не сильно эффективно
Структурная оптимизация
Слияние и перемещение деклараций и правил
34
Самая сложная и ресурсоемкая оптимизация
36
.foo { color: red; color: green;}
.foo { color: green;}
Удаление ненужных деклараций
color: red никогда не будет использовано браузером – можно удалить
Внимание! Викторина Насколько вы хороший минификатор ;)
37
38
.foo { color: red; color: rgba(…);}
.foo { color: rgba(…);}
Удаление ненужных деклараций
Правильно?
38
.foo { color: red; color: rgba(…);}
.foo { color: rgba(…);} НЕВ
ЕРНО
В старых браузерахне поддерживается rgba()
Удаление ненужных деклараций
Правильно?
39
.foo { color: red;}.bar { color: green;}.qux { color: red;}
.foo, .qux { color: red;}.bar { color: green;}
ПерегруппировкаПравильно?
39
.foo { color: red;}.bar { color: green;}.qux { color: red;}
.foo, .qux { color: red;}.bar { color: green;}
НЕВЕРН
О
Разный эффект, например:<div class="bar qux">
ПерегруппировкаПравильно?
40
span { color: red;}div { color: green;}ul { color: red;}
span, ul { color: red;}div { color: green;}
ПерегруппировкаПравильно?
40
span { color: red;}div { color: green;}ul { color: red;}
span, ul { color: red;}div { color: green;}
Правильно, у элементов одно имя
ПерегруппировкаПравильно?
41
.foo { color: red;}span { color: green;}.bar { color: red;}
.foo, .bar { color: red;}span { color: green;}
ПерегруппировкаПравильно?
41
.foo { color: red;}span { color: green;}.bar { color: red;}
.foo, .bar { color: red;}span { color: green;}
Правильно,разная специфичность –порядок не важен
ПерегруппировкаПравильно?
42
.foo { color: red;}.bar:not(.baz) { color: red;}
.foo,
.bar:not(.baz) { color: red;}
ПерегруппировкаПравильно?
42
.foo { color: red;}.bar:not(.baz) { color: red;}
.foo,
.bar:not(.baz) { color: red;}
ПерегруппировкаПравильно?
Старые браузеры не поддерживают :not()
НЕВЕРН
О
43
И т.д. и т.п.
44
.foo { color: red; width: 100px;}.bar { color: green; width: 100px;}
.foo, .bar { width: 100px;}.foo { color: red;}.bar { color: green;}
Вынос общих частей
Выносить можно в каждом случае по-разному
45
46
.foo { color: red;}.bar { color: red; color: rgba(..);}
.foo, .bar { color: red;}.bar { color: rgba(..);}
Вынос общих частей
В данном примере можно только в начало
47
.foo { color: rgba(..);}.bar { color: red; color: rgba(..);}
.bar { color: red;}.foo, .bar { color: rgba(..);}
Вынос общих частей
В данном примере можно только в конец
Очень много нюансов, нужно знать специфику свойств и селекторов
48
Базовая оптимизация• Похожие методы
• Основной выигрыш дает удаление пробелов
• Много хаков
• У всех есть ошибки
49
Продвинутые оптимизации
Usage data
Usage data
52
.foo { color: red;}.bar { color: green;}.qux { color: red;}
.foo, .qux { color: red;}.bar { color: green;}
Трансформация не безопасна, так как мы не знаем как используется CSS в разметке
Вспомним пример
Но что, если мы знаем как используется?
53
Фильтрация
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 }
Результат
Scopes
Пример
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
Пример
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; }
Минификатор не знает, что имена не смешиваются
и можно безопасно перемещать
Usage data
59
{ "scopes": [ ["module1-foo", "module1-bar"], ["module2-baz", "module2-qux"] ]}
Так мы гарантируем, что классы module1-* и module2-*
не встречаются на одном элементе
Результат с 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
61
Уже поддерживается в CSSO!
Что это дало нашему проекту
• 823 Kb Оригинальный CSS
• 596 Kb Базовая минификация
• 437 Kb Минификация с usage data
62
Улучшение результата на 159Kb (26%)
Как генерировать usage data?
63
Универсального решения нет – все зависит от используемого стека
Rename
Rename
65
.foo { color: red }
.foo.bar { color: green }
.a { color: red }
.a.b { color: green }
{ "foo": "a", "bar": "b"}
rename map
Результат
CSS+
66
• 823 Kb Оригинальный CSS
• 596 Kb Базовая минификация
• 385 Kb Rename (пока вне CSSO)
Улучшение результата на 211Kb (35%)
Что это дало нашему проекту
67
Улучшение результата на 364Kb (61%)
Все вместе
• 823 Kb Оригинальный CSS
• 596 Kb Базовая минификация
• 232 Kb Rename + Usage data
Должно ли это быть в минификаторе?
68
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
+
Кто будет писать такой CSS?
70
Usage data!
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}
В разработке – скоро в CSSO
73
• ~10 Kb дополнительного выигрыша (~3-4%)
• 1431 удаленный селектор из 6904
Селекторов стало на ~20% меньше
Что это дало нашему проектупредварительные оценки
74
Сжимать или не сжимать?
На что влияет минификация?
75
76
Network
Paint
Parse Stylesheet
Recalculate Style
Layout
Как CSS превращается в картинку
77
Network
Paint
Parse Stylesheet
Recalculate Style
Layout
Влияние характеристик CSS на скорость
Влияют количественные характеристики CSS (размер, кол-во селекторов и т.д.)
Влияют качественные характеристики CSS (сложность расчетов и отрисовки)
78
Network
Paint
Parse Stylesheet
Recalculate Style
Layout
Автоматизация улучшений
Компрессия может оказать положительный эффект
Пока нет предпосылок, что задача решается
79
Network
Paint
Parse Stylesheet
Recalculate Style
Layout
Network
Решение: gzip, SDCH …
Имеет эффект только для холодной загрузки
Неоптимизированный CSS сжимается лучше
80
Network
Paint
Parse Stylesheet
Recalculate Style
Layout
Parse Stylesheet
Решение: сжатие CSS
Тут gzip уже не играет роли, выполняется всегда на старте + мутация DOM
Меньше текста – меньше парсить
Без сжатия 823 Kb – 35ms Базовое сжатие 596 Kb – 29ms
Rename 385 Kb – 24ms Rename + usage data 232 Kb – 22ms
81
Наколеночные тестВлияние разного уровня сжатия на время парсинга
Размер уменьшился в ~4 раза, но время лишь на ~50%
(Chrome на MacBook Air)
Win10 Desktop 19ms → 11ms Nexus 5X 68ms → 44ms
Samsung Galaxy Note 2 158ms → 108ms 82
Наколеночные тесты
Ранее, на других устройствах, были получены более обнадеживающие цифры при улучшении сжатия
CSS 316Kb 215Kb (-39.5%)+ usage data
83
Network
Paint
Parse Stylesheet
Recalculate Style
Layout
Parse Stylesheet
Решение: rename и др.
Уменьшение кол-ва селекторов, их сложности
Пока гипотезы, цифр нет, но будут как только фича появится в CSSO ;)
Сжимать или не сжимать?
84
Сжимать или не сжимать?
84
Да! Хуже не будетХотя эффект – предмет для исследований
CSSO – новая жизнь
Что изменилось• В 10+ раз быстрее
• В 8+ раз меньше потребление памяти
• Исправлена большая часть проблем и багов
• Улучшена кодовая база и API
• Больше скачиваний и звезд на GitHub ;)86
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
postcss-csso
88
Плагин для PostCSS, aльтернатива cssnano
Работает почти также быстро как CSSO отдельно
Под капотом конвертация AST
github.com/lahmatiy/postcss-csso
89
1 300 000+ скачиваний в месяцx9 с октября 2015
Новое• Source Maps
• Usage data
• Лучше поддержка "новых" частей в CSS
• Лучше сообщения об ошибках
• Поддержка stdin
• Новый формат AST
90
Планы
Главная цель – лучший минификатор
Coming soon• Новые оптимизации и алгоритмы: быстрее и правильно
• Учет поддерживаемых браузеров
• Семейства свойств и сортировка деклараций
• Нормализация имен и переименование
• Понимание структуры shorthand-значений
• Применение статистики
93
В заключении
Любите CSS, читайте спеки
96Используйте CSSO :)
97
Все новое в твитере @cssoptimizer