Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
CSSO — сжимаем CSS
Роман Дворнов
Avito
Минск 2016
Работаю в Avito
Делаю SPA
Автор basis.js
Мейтенер CSSO
За любую движуху, 

кроме голодовки ;)
3
3
4
«Хэппи-энда» не будет
5
CSS-минификаторы не нужны!
5
Шутка… почти
CSS-минификаторы не нужны!
6
Быстрые 

браузеры
«Тяжелые» 

сайты
6
Быстрые 

браузеры
«Тяжелые» 

сайты
много CSS – нужно сжимать
Чем сжимать?
8
cssnanocsso clean-css
YUI Compressor fork
ycssmin
Герои сегодняшнего дня
8
cssnanocsso clean-css
YUI Compressor fork
ycssmin
Герои сегодняшнего дня
8
cssnanocsso clean-css
YUI Compressor fork
ycssmin
Герои сегодняшнего дня
8
cssnanocsso clean-css
YUI Compressor fork
ycssmin
Герои сегодняшнего дня
8
cssnanocsso clean-css
YUI Compressor fork
ycssmin
Герои сегодняшнего дня
8
cssnanocsso clean-css
YUI Compressor fork
ycssmin
Герои сегодняшнего дня
8
cssnanocsso clean-css
YUI Compressor fork
ycssmin
Герои сегодняшнего дня
8
cssnanocsso clean-css
YUI Compressor fork
ycssmin
Герои сегодняшнего дня
9
Минификаторов гораздо больше,
но либо не популярны 

либо слабо развиваются
Сравниваем
11
clean-css 3.4.9 cssnano 3.5.2 csso 2.0.0
bootstrap.css
147 427 байт
118 186
273 ms
117 440
1 813 ms
117 756
169 ms
foundation.css
200 341 байт
142 667
389 ms
145 030
1 983 ms
144 262
222 ms
normalize.css
7 707 байт
1792
5 ms
1824
17 ms
1 831
4 ms
reset.css
1 092 байт
758
3 ms
773
13 ms
747
3 ms
goalsmashers.github.io/css-minification-benchmark/
Выглядит как-то так…
Библиотеки пишутся
оптимально,
реальный CSS – нет
13
14
clean-css 3.4.9 cssnano 3.5.2 csso 2.0.0
ActiAgent.ru
602 233 байт (5 мес назад)
430 240
1 077 ms
439 024
23 270 ms
435 588
531 ms
ActiAgent.ru
822 021 байт (сейчас)
587 906
1 705 ms
604 503
48 550 ms
595 834
616 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 ! #483d8b
30
Что еще
• Нормализация чисел: 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(600Kb)
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 ms
clean-css
Изменение по скорости
csso
500 ms
cssnano
23 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
Роман Дворнов
@rdvornov
rdvornov@gmail.com
Вопросы?
github.com/css/csso

More Related Content

CSSO — сжимаем CSS (часть 2)