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

PDF
"Пиринговый веб на JavaScript"
PPTX
JavaScript: прошлое, настоящее и будущее.
PDF
Wordpress Cron
PDF
Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"
PDF
Batch processing on RoR
PPTX
CodeFest 2014. Пугачев С. — Язык TypeScript или JavaScript на стероидах
PPTX
Jinba - frontendconf.ru/2015
PDF
Reform: путь к лучшему ORM
"Пиринговый веб на JavaScript"
JavaScript: прошлое, настоящее и будущее.
Wordpress Cron
Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"
Batch processing on RoR
CodeFest 2014. Пугачев С. — Язык TypeScript или JavaScript на стероидах
Jinba - frontendconf.ru/2015
Reform: путь к лучшему ORM

What's hot (20)

PDF
React со скоростью света: не совсем обычный серверный рендеринг
PDF
«Как перестать отлаживать асинхронные вызовы и начать жить»​
KEY
Batch processing in rails
PPTX
Парсер: что? зачем? как?
PDF
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
PDF
Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»
PDF
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...
PDF
Практика применения Pinba в Badoo / Денис Карасик (Badoo)
PDF
MxxRu::externals: Repositoryless Dependency Manager
PDF
Расширения для PostgreSQL
PDF
How to build solid CI-CD pipeline / Илья Беда (beda.software)
PDF
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
PDF
Hacking PostgreSQL. Разделяемая память и блокировки.
ODP
Практический опыт создания уменьшенной копии боевой инфраструктуры сайта для ...
PPTX
Денормализованное хранение данных в PostgreSQL 9.2 (Александр Коротков)
PDF
Суперсилы Chrome DevTools — Роман Сальников, 2ГИС
PDF
Суперсилы Chrome developer tools
ODP
Hacking PostgreSQL. Физическое представление данных
PDF
Отладка и устранение проблем в PostgreSQL Streaming Replication.
PPT
Perl in practice
React со скоростью света: не совсем обычный серверный рендеринг
«Как перестать отлаживать асинхронные вызовы и начать жить»​
Batch processing in rails
Парсер: что? зачем? как?
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...
Практика применения Pinba в Badoo / Денис Карасик (Badoo)
MxxRu::externals: Repositoryless Dependency Manager
Расширения для PostgreSQL
How to build solid CI-CD pipeline / Илья Беда (beda.software)
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
Hacking PostgreSQL. Разделяемая память и блокировки.
Практический опыт создания уменьшенной копии боевой инфраструктуры сайта для ...
Денормализованное хранение данных в PostgreSQL 9.2 (Александр Коротков)
Суперсилы Chrome DevTools — Роман Сальников, 2ГИС
Суперсилы Chrome developer tools
Hacking PostgreSQL. Физическое представление данных
Отладка и устранение проблем в PostgreSQL Streaming Replication.
Perl in practice
Ad

Viewers also liked (9)

PPTX
Migrate your React.js application from (m)Observable to Redux
PPTX
Dart: питание и сила для вашего проекта
PPTX
Если у вас нету тестов...
PDF
Будь первым
PDF
Redux. From twitter hype to production
PDF
"Service Worker: Let Your Web App Feel Like a Native "
PDF
Scalable Angular 2 Application Architecture
PDF
В погоне за производительностью
PDF
Digital pipeline — инновации в продажах / Михаил Токовинин
Migrate your React.js application from (m)Observable to Redux
Dart: питание и сила для вашего проекта
Если у вас нету тестов...
Будь первым
Redux. From twitter hype to production
"Service Worker: Let Your Web App Feel Like a Native "
Scalable Angular 2 Application Architecture
В погоне за производительностью
Digital pipeline — инновации в продажах / Михаил Токовинин
Ad

Similar to CSSO — сжимаем CSS (20)

PDF
CSSO — сжимаем CSS Роман Дворнов, Avito
PDF
CSSO — минимизируем CSS
PDF
SASS & LESS
PDF
Ваш CSS нас не устраивает, мы придумаем свой / Роман Прудников (2ГИС)
PDF
Олег Мохов "Куда идём мы с Пятачком, или О том, куда движется вёрстка и верст...
PDF
Жизнь в изоляции
PDF
Сергей Сыркин - CSS
PDF
Роман Комаров — «Механизм работы браузера»
PDF
Михаил Трошев — CSS: Систематизация базовых знаний
PDF
Робота з CSS. Методології, інструменти, оптимізація
PPT
Trening modul2-conf1-tema5
PDF
Роман Комаров "CSS-препроцессоры: из каменного века — в будущее"
PDF
Жизнь в изоляции / Роман Дворнов (Avito)
PDF
LESS and even more. Anton Shubkin.
PDF
D2D Pizza JS Тимофей Чаптыков "CSS-менеджмент в 2016"
PDF
CSS-менеджмент в 2016
PDF
Современная верстка с адекватными трудозатратами Максим Тимохин, технолог, И...
PDF
Олег Мохов "Куда движется вёрстка и верстальщики Яндекса"
PPTX
A вы верите в систематизацию
CSSO — сжимаем CSS Роман Дворнов, Avito
CSSO — минимизируем CSS
SASS & LESS
Ваш CSS нас не устраивает, мы придумаем свой / Роман Прудников (2ГИС)
Олег Мохов "Куда идём мы с Пятачком, или О том, куда движется вёрстка и верст...
Жизнь в изоляции
Сергей Сыркин - CSS
Роман Комаров — «Механизм работы браузера»
Михаил Трошев — CSS: Систематизация базовых знаний
Робота з CSS. Методології, інструменти, оптимізація
Trening modul2-conf1-tema5
Роман Комаров "CSS-препроцессоры: из каменного века — в будущее"
Жизнь в изоляции / Роман Дворнов (Avito)
LESS and even more. Anton Shubkin.
D2D Pizza JS Тимофей Чаптыков "CSS-менеджмент в 2016"
CSS-менеджмент в 2016
Современная верстка с адекватными трудозатратами Максим Тимохин, технолог, И...
Олег Мохов "Куда движется вёрстка и верстальщики Яндекса"
A вы верите в систематизацию

More from FDConf (20)

PPT
Антон Киршанов - «Квант изменения. Реактивные реакции на React.
PDF
Игорь Еростенко - Создаем виртуальный тур
PDF
Илья Климов - Reason: маргиналы против хайпа
PDF
Максим Щепелин - Доставляя веб-контент в игру
PDF
Александр Черноокий - Как правило "победитель получает все" работает и не раб...
PDF
Михаил Волчек - Что такое Цифровая мастерская?
PDF
Radoslav Stankov - Handling GraphQL with React and Apollo
PDF
Виктор Русакович - Выборы, выборы, все фреймворки… приторны
PDF
Slobodan Stojanovic - 8 1/2 things about serverless
PPTX
Тимофей Лавренюк - Почему мне зашел PWA?
PDF
В погоне за производительностью
PDF
«I knew there had to be a better way to build mobile app»​
PDF
«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»
PPTX
«Идеи и алгоритмы создания масштабируемой архитектуры в играх»​
PDF
«От экспериментов с инфраструктурой до внедрения в продакшен»​
PDF
«The Grail: React based Isomorph apps framework»​
PDF
«The Illusion of Time. When 60 sec is not 1 minute»​
PDF
«Книги в браузере»
PDF
«Как работают современные интерактивные карты на WebGL»​
PDF
«# Self Modifying Code»​
Антон Киршанов - «Квант изменения. Реактивные реакции на React.
Игорь Еростенко - Создаем виртуальный тур
Илья Климов - Reason: маргиналы против хайпа
Максим Щепелин - Доставляя веб-контент в игру
Александр Черноокий - Как правило "победитель получает все" работает и не раб...
Михаил Волчек - Что такое Цифровая мастерская?
Radoslav Stankov - Handling GraphQL with React and Apollo
Виктор Русакович - Выборы, выборы, все фреймворки… приторны
Slobodan Stojanovic - 8 1/2 things about serverless
Тимофей Лавренюк - Почему мне зашел PWA?
В погоне за производительностью
«I knew there had to be a better way to build mobile app»​
«Continuous Integration — A to Z или Непрерывная интеграция — кто всё сломал?»
«Идеи и алгоритмы создания масштабируемой архитектуры в играх»​
«От экспериментов с инфраструктурой до внедрения в продакшен»​
«The Grail: React based Isomorph apps framework»​
«The Illusion of Time. When 60 sec is not 1 minute»​
«Книги в браузере»
«Как работают современные интерактивные карты на WebGL»​
«# Self Modifying Code»​

CSSO — сжимаем CSS