csso – compress css (english version)

113
CSSO — compress CSS Roman Dvornov Avito Minsk 2016

Upload: roman-dvornov

Post on 07-Jan-2017

598 views

Category:

Technology


7 download

TRANSCRIPT

Page 1: CSSO – compress CSS (english version)

CSSO — compress CSS

Roman Dvornov Avito

Minsk 2016

Page 2: CSSO – compress CSS (english version)

Working at Avito

Building SPA

Author of basis.js

Maintainer of CSSO

Page 3: CSSO – compress CSS (english version)

3

Don't expect happy end

Page 4: CSSO – compress CSS (english version)

CSS-minifiers aren't needed!

Page 5: CSSO – compress CSS (english version)

It's a joke… or maybe notCSS-minifiers aren't needed!

Page 6: CSSO – compress CSS (english version)

5

Fast browsers

Heavy sites

Page 7: CSSO – compress CSS (english version)

5

Fast browsers

Heavy sites

a lot of CSS – compression needed

Page 8: CSSO – compress CSS (english version)

What tool to choose?

Page 9: CSSO – compress CSS (english version)

7

cssnanocsso clean-cssYUI Compressor fork

ycssmin

Heroes of the day

Page 10: CSSO – compress CSS (english version)

7

cssnanocsso clean-cssYUI Compressor fork

ycssmin

Heroes of the day

Page 11: CSSO – compress CSS (english version)

7

cssnanocsso clean-cssYUI Compressor fork

ycssmin

Heroes of the day

Page 12: CSSO – compress CSS (english version)

7

cssnanocsso clean-cssYUI Compressor fork

ycssmin

Heroes of the day

Page 13: CSSO – compress CSS (english version)

7

cssnanocsso clean-cssYUI Compressor fork

ycssmin

Heroes of the day

Page 14: CSSO – compress CSS (english version)

7

cssnanocsso clean-cssYUI Compressor fork

ycssmin

Heroes of the day

Page 15: CSSO – compress CSS (english version)

7

cssnanocsso clean-cssYUI Compressor fork

ycssmin

Heroes of the day

Page 16: CSSO – compress CSS (english version)

7

cssnanocsso clean-cssYUI Compressor fork

ycssmin

Heroes of the day

Page 17: CSSO – compress CSS (english version)

8

There are much more minifiers but not so famous or

not in active developing

Page 18: CSSO – compress CSS (english version)

Let's compare

Page 19: CSSO – compress CSS (english version)

10

clean-css 3.4.9 cssnano 3.5.2 csso 2.0.0

bootstrap.css147 427 bytes

118 186273 ms

117 4401 813 ms

117 756169 ms

foundation.css200 341 bytes

142 667389 ms

145 0301 983 ms

144 262222 ms

normalize.css7 707 bytes

17925 ms

182417 ms

1 8314 ms

reset.css1 092 bytes

758 3 ms

77313 ms

7473 ms

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

Page 20: CSSO – compress CSS (english version)

It looks like…

Page 21: CSSO – compress CSS (english version)

Libraries are written well, real CSS is not

12

Page 22: CSSO – compress CSS (english version)

13

clean-css 3.4.9 cssnano 3.5.2 csso 2.0.0

ActiAgent.ru602 233 bytes (5 month ago)

430 2401 077 ms

439 02423 270 ms

435 588531 ms

ActiAgent.ru822 021 bytes (now)

587 9061 705 ms

604 50348 550 ms

595 834616 ms

gzip compression factor is 8 (~72Kb) That means the result can be improved!

Our numbers

Page 23: CSSO – compress CSS (english version)

Minification

Page 24: CSSO – compress CSS (english version)

Every minifier works the same way

Page 25: CSSO – compress CSS (english version)

Basic minification

• Deletion

• Replacement

• Structural optimization

16

Page 26: CSSO – compress CSS (english version)

You may think that CSS minification is all about

W3C specifications

17

Page 27: CSSO – compress CSS (english version)

In fact sh*t happens all the time

Page 28: CSSO – compress CSS (english version)

That's why

• Specs are changing

• Various browser support of CSS

• Browser's bugs

• CSS hacks

19

Page 29: CSSO – compress CSS (english version)

Most important

Minification shouldn't break or repair the CSS

20

Page 30: CSSO – compress CSS (english version)

Deletion

Page 31: CSSO – compress CSS (english version)

What to delete• Whitespaces and comments (most part of saving)

• Rules with wrong selectors

• Empty rules

• Wrong declarations

• Malposed @import, @charset

• …

22

Page 32: CSSO – compress CSS (english version)

Always respect specifications

23

Page 33: CSSO – compress CSS (english version)

24

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

Wrong

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

Correct

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

Whitespace deletion

Page 34: CSSO – compress CSS (english version)

More examples• Units for zero dimensions0px ! 0

• Quotes[attr="name"] ! [attr=name] url('image.png') ! url(image.png)

• …

25

Page 35: CSSO – compress CSS (english version)

But it's not so simple• 0px ! 0

correct

26

Page 36: CSSO – compress CSS (english version)

But it's not so simple• 0px ! 0

correct• 0deg ! 0

wrong, not a length unit

26

Page 37: CSSO – compress CSS (english version)

But it's not so simple• 0px ! 0

correct• 0deg ! 0

wrong, not a length unit• flex: 1 0 0px ! flex: 1 0 0

wrong, doesn't work as expected in IE

26

Page 38: CSSO – compress CSS (english version)

Replacement

Page 39: CSSO – compress CSS (english version)

Replace with shorter forms

28

Page 40: CSSO – compress CSS (english version)

Most interesting: colour• hsl ! rgb, hsla ! rgba

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

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

• normalize: rgb(500, -100, 0) ! rgb(255, 0, 0)

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

• #aabbcc ! #abc

• #ff0000 ! red, darkslateblue ! #483d8b29

Page 41: CSSO – compress CSS (english version)

More examples• Number normalization: 0.00 ! 0 or 0.123 ! .123

• Special values for some properties

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

• background:none ! background:0 0

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

• …

30

Page 42: CSSO – compress CSS (english version)

Isn't effective actually

Page 43: CSSO – compress CSS (english version)

Structural optimization

Page 44: CSSO – compress CSS (english version)

Merging and moving declarations and rules

33

Page 45: CSSO – compress CSS (english version)

The most complicated and expensive optimization

Page 46: CSSO – compress CSS (english version)

35

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

.foo { color: green;}

Declaration deletion

color: red has never to be used by browser – can be deleted

Page 47: CSSO – compress CSS (english version)

Let's check Are you a proper minifier or not? ;)

36

Page 48: CSSO – compress CSS (english version)

37

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

.foo { color: rgba(…);}

Deletion of declarationsCorrect?

Page 49: CSSO – compress CSS (english version)

37

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

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

Old browsers don't support rgba()

Deletion of declarationsCorrect?

Page 50: CSSO – compress CSS (english version)

38

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

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

RegroupingCorrect?

Page 51: CSSO – compress CSS (english version)

38

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

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

Wrong

Different results, e.g.<div class="bar qux">

RegroupingCorrect?

Page 52: CSSO – compress CSS (english version)

39

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

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

RegroupingCorrect?

Page 53: CSSO – compress CSS (english version)

39

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

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

Correct, elements have a single name

RegroupingCorrect?

Page 54: CSSO – compress CSS (english version)

40

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

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

RegroupingCorrect?

Page 55: CSSO – compress CSS (english version)

40

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

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

Correct,different specificity –order doesn't matter

RegroupingCorrect?

Page 56: CSSO – compress CSS (english version)

41

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

.foo,

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

RegroupingCorrect?

Page 57: CSSO – compress CSS (english version)

41

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

.foo,

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

RegroupingCorrect?

Old browsers don't support :not()

Wrong

Page 58: CSSO – compress CSS (english version)

42

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

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

Moving common parts aside

Page 59: CSSO – compress CSS (english version)

Moving direction matters

43

Page 60: CSSO – compress CSS (english version)

44

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

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

Moving common parts aside

In this case only moving up is correct

Page 61: CSSO – compress CSS (english version)

45

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

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

Moving common parts aside

In this case only moving down is correct

Page 62: CSSO – compress CSS (english version)

Too many things minifier should respect…

46

Page 63: CSSO – compress CSS (english version)

Basic optimization summary• Common approaches

• Usually whitespace deletion is most effective

• Many hacks and edge cases

• Every minifier has bugs

47

Page 64: CSSO – compress CSS (english version)

Advanced optimizations

Page 65: CSSO – compress CSS (english version)

Usage data

Usage data

Page 66: CSSO – compress CSS (english version)

50

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

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

This transformation isn't safe, since we don't know how CSS is used in markup

Example

Page 67: CSSO – compress CSS (english version)

But what if we knew?

51

Page 68: CSSO – compress CSS (english version)

Filtering

Page 69: CSSO – compress CSS (english version)

53

{ "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 }

Result

Page 70: CSSO – compress CSS (english version)

Scopes

Page 71: CSSO – compress CSS (english version)

55

.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; }

Rules with .module1-foo and .module2-baz can't be merged,

since .module1-bar is between them

Page 72: CSSO – compress CSS (english version)

56

.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; }

Rules merge is safe only if we sure that class names are never applied to a single element

Page 73: CSSO – compress CSS (english version)

Usage data

57

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

With this JSON we explain to optimizer thatmodule1-* and module2-* class names are never applied to a single element

Page 74: CSSO – compress CSS (english version)

The basic minification result (157 bytes)

58

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

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

.module2-qux{width:50px}

34 bytes extra saving

.module1-foo{background:red}.module1-bar{font-size:1.5em;background:#ff0}.module2-baz{background:red}.module2-qux{font-size:1.5em;background:#ff0;width:50px}

The result with usage data (123 bytes)

Page 75: CSSO – compress CSS (english version)

59

Feature is already available in CSSO!

Page 76: CSSO – compress CSS (english version)

Profit for our project

• 823 Kb Original CSS

• 596 Kb Basic optimization

• 437 Kb Optimization with usage data

60

159 Kb extra saving (26%)

Page 77: CSSO – compress CSS (english version)

How to generate usage data?

61

There is no universal solution – it depends on the technology stack

It is expected such tools will be created soon

Page 78: CSSO – compress CSS (english version)

Rename

Rename

Page 79: CSSO – compress CSS (english version)

63

.foo { color: red }

.foo.bar { color: green }

.a { color: red }

.a.b { color: green }

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

Rename map

Result

CSS+

Page 80: CSSO – compress CSS (english version)

64

• 823 Kb Orignal CSS

• 596 Kb Basic optimization

• 385 Kb Rename (currently outside CSSO)

211 Kb of extra saving (35%)

Profit for our project

Page 81: CSSO – compress CSS (english version)

65

364Kb of extra saving (61%)

All together

• 823 Kb Original CSS

• 596 Kb Basic optimization

• 232 Kb Rename + Usage data

Page 82: CSSO – compress CSS (english version)

Should it be a part of minifier?

66

Yep, because it leads to a new optimization

Page 83: CSSO – compress CSS (english version)

67

.foo,

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

.a { color: red }

.a:hover { color: green }

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

Rename map

ResultCSS

+

The single new name for old two names – reduce selector count

Page 84: CSSO – compress CSS (english version)

Nobody writes this sort of CSS…

68

Page 85: CSSO – compress CSS (english version)

69

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

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

ResultCSS + usage data.foo,.bar { color: red;}.foo:hover,.bar:hover { color: green}

Page 86: CSSO – compress CSS (english version)

In development – coming soon in CSSO

Page 87: CSSO – compress CSS (english version)

71

• ~10 Kb of extra saving (~3-4%)

• 1431 of 6904 selectors were deleted

Selector count decreased by ~20%

Profit for our projectquick and dirty numbers

Page 88: CSSO – compress CSS (english version)

72

To compress or not to compress?

Page 89: CSSO – compress CSS (english version)

What is the effect of minification?

73

Page 90: CSSO – compress CSS (english version)

74

Network

Paint

Parse Stylesheet

Recalculate Style

Layout

How CSS to became an image

Page 91: CSSO – compress CSS (english version)

75

Network

Paint

Parse Stylesheet

Recalculate Style

Layout

Characteristics of CSS that affect performance

Quantitative characteristics matters (size, number of selectors etc.)

Qualitative characteristics matters (complexity of layout and effects)

Page 92: CSSO – compress CSS (english version)

76

Network

Paint

Parse Stylesheet

Recalculate Style

Layout

Automation of enhancement

Compression can give a positive effect

Currently, have no ideas how to automate optimizations

Page 93: CSSO – compress CSS (english version)

77

Network

Paint

Parse Stylesheet

Recalculate Style

Layout

Network

Solution: gzip, SDCH …

It matters for cold page load only

Page 94: CSSO – compress CSS (english version)

78

Network

Paint

Parse Stylesheet

Recalculate Style

Layout

Parse Stylesheet

Solution: use a minifier

Performs every time on page load

Less text – less to parse

Page 95: CSSO – compress CSS (english version)

Original CSS 823 Kb – 35ms Basic optimisations 596 Kb – 29ms

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

79

Quick and dirty testsVarious level of compression and its influence on Parse Stylesheet

Size is reduced by ~4 times, time by ~40%

(Chrome on MacBook Air)

Page 96: CSSO – compress CSS (english version)

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

Samsung Galaxy Note 2 158ms → 108ms 80

Quick and dirty tests

On other devices there were more encouraging numbers

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

Page 97: CSSO – compress CSS (english version)

81

Network

Paint

Parse Stylesheet

Recalculate Style

Layout

Recalculate Style

Solution: rename etc.

Performs every time on page load and on any DOM mutation

We've hypotheses only, more details when feature will be shipped in CSSO ;)

Page 98: CSSO – compress CSS (english version)

To compress or not to compress?

82

Page 99: CSSO – compress CSS (english version)

To compress or not to compress?

82

Yes!But it's still a subject for research

Page 100: CSSO – compress CSS (english version)

CSSO reborn

Page 101: CSSO – compress CSS (english version)

What was changed• 10+ times faster

• 8+ times less memory consumption

• Fixed most of bugs

• Better code base and API

• More downloads and stars on GitHub ;)84

Page 102: CSSO – compress CSS (english version)

85

1 300 000+ downloads per month9x since October 2015

Page 103: CSSO – compress CSS (english version)

Com

pres

sion

tim

e (6

00Kb

CSS

file

)

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 version

1.4.0 1.5.0 1.6.0 1.7.0 1.8.0 2.0

1 050 msclean-css

Performance changes

csso500 ms

cssnano23 250 ms

Page 104: CSSO – compress CSS (english version)

postcss-csso

87

Plugin for PostCSS

As fast as CSSO alone

Under the hood the plugin converts PostCSS AST into CSSO format, optimises it and converts back

github.com/lahmatiy/postcss-csso

Page 105: CSSO – compress CSS (english version)

New features• Source Maps

• Usage data

• Support for new parts of CSS

• User friendly error messages

• Support for stdin

• New AST format

88

Page 106: CSSO – compress CSS (english version)

Plans

Page 107: CSSO – compress CSS (english version)

Main goal is to build the best CSS optimizer

Page 108: CSSO – compress CSS (english version)

Coming soon• New algorithms and optimizations

• Browser support modes

• Property families and declaration sorting

• Name normalization and renaming

• Shorthand properties structure recognition

• And more…91

Page 109: CSSO – compress CSS (english version)

Conclusion

Page 110: CSSO – compress CSS (english version)

Like CSS, read specs

Page 111: CSSO – compress CSS (english version)

94 Try CSSO :)

Page 112: CSSO – compress CSS (english version)

95

All new around CSSO – @cssoptimizer

Page 113: CSSO – compress CSS (english version)

Roman Dvornov @rdvornov

[email protected]

Any questions?

github.com/css/csso