KEMBAR78
CSS and image optimization | PDF
CSS and Image
Optimization




Stoyan Stefanov, @stoyanstefanov
May 12, 2010
Web Optimization Summit
Agenda
1.  Reducing CSS file sizes
2.  Rendering
3.  Reducing HTTP requests
4.  Optimizing image file sizes
Reducing CSS file sizes
CSS recipe for disaster
#sidebar #menu ul li.blogroll	
{	
    color: green !important;	
    font-weight: bold;	
}
CSS recipe for disaster
#sidebar #menu ul li.blogroll	
{	
    color: green !important;	
    font-weight: bold;	
}	


     Long selectors
CSS recipe for disaster
#sidebar #menu ul li.blogroll	
{	
    color: green !important;	
    font-weight: bold;	
}	


       C-style indented
         declarations
CSS recipe for disaster
#sidebar #menu ul li.blogroll	
{	
    color: green !important;	
    font-weight: bold;	
}	


  What? Not
unique enough?
CSS recipe for disaster
#sidebar #menu ul li.blogroll	
{	
    color: green !important;	
    font-weight: bold;	
}	


           One is probably
              enough
CSS recipe for disaster
#sidebar #menu ul li.blogroll	
{	
    color: green !important;	
    font-weight: bold;	
}	



                   Lame
Crockford on CSS:



 “Long, fragile lists of
  self-contradictory
         rules”
So?
#sidebar #menu ul li.blogroll	
{	
    color: green !important;	
    font-weight: bold;	
}	

Legend:
• easy stuff • tough stuff
So?



 Make the tough stuff
        easy
Reusable CSS
.linklist {color: green; ...}	

/* widgets */	
.module {...}	
.gallery {...}	

/* utilities */ 	
.clearfix {...};	
.flip {...}
Mixin pattern
<ul class="module linklist">	
…
Reusable CSS

1.  Strong foundation:
    reset, grids
2.  Library styles:
    .class not #id
Object-Oriented CSS
•  Nicole Sullivan
•  oocss.org
Minifying CSS
•  Strip white space, comments
•  Some micro-optimizations
•  ~30% savings
•  can’t rename
•  YUICompressor, CSSTidy
•  Inline code too!
                http://tools.w3clubs.com/cssmin/
Browser-specific CSS
•  IE6,7 vs. others
•  -webkit-, -moz-, -o-
•  -ms-, _, *, zoom
•  automated
•  savings? 3-5%, mileage vary
       http://phpied.com/files/css-parse/css-strip.html
CSS and rendering
Filters
•  AlphaImageLoader is bad
•  Verdict is out on the others
Expressions
•  Executed too often
•  Avoid
•  JavaScript or self-rewrite
Behaviors
•  Be careful with the shims
•  ie-css3.htc, pngfix.htc,…
Scrollbars trick
•  Prevent a reflow when you
expect a long page

body {overflow-y: scroll;}
Reducing HTTP requests
CSS blocks rendering
•  The worst component type
•  Place way at the top
•  Inline all @media print, etc



http://www.phpied.com/delay-loading-your-print-css/
http://www.phpied.com/rendering-styles/
Same domain
•  If you split across domains,
keep CSS on the same
domain as HTML
Inline CSS
•  Google search
•  Bing.com: inline + postload
Inline + postload
•  First visit:


1. Inline
2. Lazy-load the external file
3. Write a cookie
Inline + postload
•  Later visits:


1. Read cookie
2. Refer to the external file
Web Fonts
•  Don’t go overboard!
•  Subset
•  Gzip!


      http://snook.ca/archives/html_and_css/
                screencast-converting-ttf2eot
Fewer HTTP requests
•  Inline images:
   in CSS sprites
   with data: URI scheme


                http://csssprites.com
                                    	
                http://spriteme.org
Fewer HTTP requests
•  data: URI scheme

$ php ‐r "echo base64_encode(file_get_contents('my.png'));” 
iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAAGElEQVQIW2P
4DwcMDAxAfBvMAhEQMYgcACEHG8ELxtbPAAAAAElFTkSuQmCC 
Fewer HTTP requests
•  data: URI scheme

background‐image: url("data:image/
png;base64,iVBORw0KG..."); 
Fewer HTTP requests
•  data: URI scheme

<img src="data:image/png;base64,iVBOR..." /> 
Fewer HTTP requests
•  data: URI scheme
•  works in IE!...
Fewer HTTP requests
•  data: URI scheme
•  works in IE8!
Fewer HTTP requests
•  data: URI scheme
•  MHTML for IE < 8
MHTML
•  MIME HTML
•  Works in IE 6,7
•  Indeed it actually absolutely
does work in IE7/Vista too
MHTML - one part
Content-Location: myimage	
Content-Transfer-Encoding: base64	

iVBORw0KGgoAAAANSU....U5ErkJggg==
MHTML - multi parts
Content-Type: multipart/related; boundary="MYSEPARATOR"	

--MYSEPARATOR	

[here comes part one]	                   The
                                         double-
--MYSEPARATOR	                           dash of
                                         doom
[here's part two]	

--MYSEPARATOR--
MHTML – all together
/*	
Content-Type: multipart/related; boundary="MYSEPARATOR"	

--MYSEPARATOR	
Content-Location: myimage	
Content-Transfer-Encoding: base64	

iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAD....U5ErkJggg==	
--MYSEPARATOR	
Content-Location: another	
Content-Transfer-Encoding: base64	

iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAA....U5ErkJggg==	
--MYSEPARATOR--	
*/	
.myclass {	
    background-image:url(mhtml:http://example.org/styles.css!myimage);	
}	
.myotherclass {	
    background-image:url(mhtml:http://example.org/styles.css!another);	
}
MHTML + data URI
•  drawback: repeats the
same encoded image
•  solution: browser-specific
CSS
•  or… an ingenious hack
MHTML + data URI
•  image header + css + data
/9j/4AA0;background-image:url(data:image/jpeg;base64;00,/9j/4AA0


Reality:

IE:

Others:



http://habrahabr.ru/blogs/webdev/90761/
No-image UI
•  a.k.a. CSS3
Rounded corners
.module {	
  -moz-border-radius: 9px;	
  -webkit-border-radius: 9px;	
  border-radius: 9px;	
}
Rounded corners
            All

            vs. 	
             IE
Gradients
.hd {	
  background-image: -moz-linear-gradient(top, #641d1c, #f00);	
  background-image: -webkit-gradient(linear, left top, left bottom, 	
                                     from(#641d1c), to(#f00));	
  filter: [...].gradient(startColorstr=#ff641d1c,endColorstr=#ffff0000);	
  -ms-filter: "[...].gradient(startColorstr=#ff641d1c,endColorstr=#ffff0000)"; 	
}
No-image UI
•  rounded corners
•  gradients
•  glows, shadows
•  rgba
                  http://www.phpied.com/
     css-performance-ui-with-fewer-images/
                     http://css3please.com
Multi-purpose “mask” images
•  one image on top of
different solid colors
•  for themes, social profiles…
1px wide “mask”
•  Top:
somewhat
transparent
•  Bottom:
Fully
transparent
Multi-purpose mask
Gradient mask
•  the data URI smaller that all
the CSS –moz, -webkit, filter...
A glossy mask
Optimizing image file sizes
Rule #1: No GIFs




$ optipng *.gif
PNG-8
•  Palette image (like GIF)
•  256 colors (like GIF)
•  Smaller than GIF (GIF++)
•  Alpha transparency (GIF++)
Rarely PNG-24
•  Truecolor
PNGSlim
                  	
OptiPNG	        DeflOpt	

           PNGOut	
      PNGOptimizer	

PNGCrush	
                 AdvPNG	
   PNGRewrite
JPEG
•  The format for photos
•  Run through JPEGTran
Study of the images on the top
1000 sites
Q: How many GIFs are out
there?
Q: What if we make them PNG?
Q: Are PNGs optimized?
Q: Are JPEGs optimized?
Top 1000 – how?
•  URLs from Alexa top sites
•  open Fiddler
•  php script that opens/closes
Explorer with each URL
•  enjoy!
•  Export images from Fiddler
Top 1000 – GIF vs. PNG?

                 Animated
                    GIF
                    3%

                            PNG
                            24%

    GIF
    73%
Top 1000 – GIF vs. PNG vs.
JPG?

                            GIF
                            40%
       JPEG
        46%



                PNG   Animated GIF
                13%       1%
Top 1000 – GIF to PNG
$ optipng *.gif	
$ pngoptimizercl –
file:"*.png”	
(1 min/1000 files)	

                 23.79%
                 savings
Top 1000 – Optimizing PNG
$ pngoptimizercl –
file:"*.png"	




                 16.90%
                 savings
Top 1000 – Optimizing JPG
$ jpegtran –copy none -optimize	




                   13.08%
                   savings
Take-home
1.  Think reusable CSS
2.  Reduce HTTP requests:
     - sprites, data URIs
     - CSS3, reusable images
3.  Smush all images
Thank you!


Stoyan Stefanov
@stoyanstefanov
http://www.phpied.com

CSS and image optimization