Progressive downloads
and rendering
Stoyan Stefanov, Yahoo!
HighLoad++, Moscow, 2010
http://slideshare.net/stoyan/
About me
YSlow 2.0
Why progressive?
Importance of performance
•  Psychology, physiology
•  Effects of waiting
•  “Time is money”
•  Make people happy
Perception
Perception
Perception
Perception
Time is relative
•  Sometimes crawls
•  Sometimes flies
•  “it depends”
Durations
actual
expected
perceived
rem’d
time
It feels slower when…
•  Unpleasant
•  Unknown
•  Boring
•  Too much to keep track
First time experience
•  Unfamiliar = slow
•  Optimize empty cache or
there will be no full cache
So… go progressive!
But before we begin…
The basics
•  Reducing the # HTTP
•  Gzip
•  Minification
•  Image smushing
•  Expires
•  CDN
The basics
•  Yahoo!’s best practices +
YSlow
http://developer.yahoo.com/performance/ 	
•  Google’s too +
Page Speed
http:...
Progressive
Progressive enhancement
Progressive downloads
Progressive rendering
Agenda
1.  Prevent download blocks:
scripts, styles, CC, favicon
2.  Ways to render sooner:
flush, data URIs, lazy loading...
Blocking JavaScript
JavaScript blocks
html
js
png
png
JavaScript blocks
•  A no-no!
<script src="jquery.js"></script> 
<script src="jquery.twitter.js"></script> 
<script src="j...
This waterfall looks ridiculous
html
js
png
png
js
js
js
JavaScript at the bottom
html
js
png
png
Non-blocking JavaScript
•  defer and async	
•  Defer: IE innovation, ok to
delay, but keep order
•  Async: HTML5, whatever...
defer and async timeline
DOMContentLoaded	 load	
async	
defer
Non-blocking JavaScript
•  Asynchronous loading
var h, js = document.createElement('script'); 
js.src = 'myscript.js'; 
h ...
Non-blocking JavaScript
•  Others:
- iframe
- XHR
- <object>	
- …
CSS and rendering
Worst enemy?
CSS
CSS blocks rendering
•  The worst component type
•  Place way at the top
•  @media print, etc in the
same external CSS
htt...
CSS
CSS
CSS block
downloads?
But they do block:
•  When followed
by an inline script
•  When in conditional
comments
Inline CSS
•  Google search
•  Bing.com: inline + postload
Same domain
•  If you split across domains
•  and if you don’t use CDN
•  Saves a DNS lookup
•  e.g. Google and Bing’s CDN
CC block
Normal page
With conditionally commented
CSS file
http://www.phpied.com/

conditional-comments-block-downloads/
What…?! Case #1
  <link type="text/css" rel="stylesheet" 
        href="1.css"> 
  <!‐‐[if IE 6]> 
    <link type="text/cs...
What…?! Case #2
<!‐‐[if IE 6]> 
    <body class="ie6">  
<![endif]‐‐> 
<!‐‐[if !IE]><!‐‐> 
    <body> 
<!‐‐<![endif]‐‐> 
Solution for case #1
<!DOCTYPE html> 
<!‐‐[if IE 6]><![endif]‐‐> 
<html> 
    ... 
Solution for case #2
<!‐‐[if IE 6]> 
    <html class="ie6">  
<![endif]‐‐> 
<!‐‐[if !IE]><!‐‐> 
    <html> 
<!‐‐<![endif]‐...
Blocking favicon
Flush
flush() early
html
png
js
css
html
png
js
css
✔

flush()
<html>	
<head>	
<script src="my.js" 	
	type="text/javascript"></script>	
<link href="my.css" 	
	type="text/css" re...
Chunked encoding
HTTP/1.1 200 OK 
Content‐Type: text/plain 
Transfer‐Encoding: chunked 
25 
This is the data in the first ...
Chunked encoding
•  Progressive rendering
- Semantic app chunks
vs.
- Server-level chunks
Progressive rendering
Chunk
#1
Chunk
#2
Chunk
#3
<!doctype html>	
<html>	
<head><title>My App</title></head>	
<body>	
<div id="header">	
<img src="logo.png" />	
...	
</div...
Progressive + source order
1
2
3
4
HTTP chunking: not only HTML
HTTP chunking: not only HTML
•  Google Instant
•  /*""*/ - delimited JSON
pieces
•  Chunk #1 suggestions
•  Chunk #2 resul...
Data URIs
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'));” 
iVBORw0KGgoAAAANSUhEU...
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..." /> 
Both
•  flushes
•  data: URIs
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
http://phpied.com

/the-...
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]	
--MYSEP...
MHTML.css – all together
/*	
Content-Type: multipart/related; boundary="MYSEPARATOR"	
--MYSEPARATOR	
Content-Location: myi...
MHTML: inline too<!doctype html>
<html>
<head>
<title>Look Ma' No HTTP requests</title>
<style type="text/css">
/*
Content...
<!doctype html>	
<html>	
<head>	
<title>Look Ma' No HTTP requests</title>	
<style type="text/css">	
...
/*	
Content-Type: multipart/related; boundary="_"	
--_	
Content-Location:locoloco	
Content-Transfer-Encoding:base64	
iVBOR...
.image1 {	
background-image: url("data:image/png;base64,iVBOR...CC"); /* normal */	
*background-image: url(mhtml:http://.....
...	
</style>	
</head>	
<body>	
<h1>MHTML + Data:URIs inline in <code>style</code></h1>	
<p class="image1">hello<br>hello<...
MHTML + data URI
•  X-browser
single request
web apps
Single request
•  WT☠?
•  Separation of concerns
•  Content-presentation-
behavior
•  yes, it’s a tradeoff
MHTML + data URI
•  drawback: repeats the same
encoded image
•  solutions:
- browser-specific CSS
- keep close = better gz...
Single stream MHTML/data URI
•  image header + css + data
/9j/4AA0;background-image:url(data:image/jpeg;base64;00,/9j/4AA0...
/*	
Content-Type: multipart/related; boundary="granitza"	
--granitza	
Content-Type: text/css;	
*/	
#myid {	
/*	
--granitza...
/*	
Content-Type: multipart/related; boundary="granitza"	
--granitza	
Content-Type: text/css;	
*/	
#myid {	
/*	
--granitza...
/*	
Content-Type: multipart/related; boundary="granitza"	
--granitza	
Content-Type: text/css;	
*/	
#myid {	
/*	
--granitza...
/*	
Content-Type: multipart/related; boundary="granitza"	
--granitza	
Content-Type: text/css;	
*/	
#myid {	
/*	
--granitza...
Single stream MHTML/data URI
•  And for <img> too!
Single stream <img>
<h2>Hello Kitty</h2>	
<!	
--granitza	
Content-Location: myimage	
Content-Transfer-Encoding: base64	
Co...
Single stream <img>
<h2>Hello Kitty</h2>	
<!	
--granitza	
Content-Location: myimage	
Content-Transfer-Encoding: base64	
Co...
Lazy loading
Lazy loading aka post-loading
•  After-onload
•  Some images
•  Below the fold (on scroll)
•  Hidden content e.g. tabs
Amazon’s lazy bestsellers
•  Page’s purpose is ranking
•  Details can come later
•  via onload XHR
•  JS off = no details
...
Lazy evaluation
GMail mobile’s lazy JS
<!doctype html>	
<html><body>	
...	
<script id="lazy">/*	
console.log("I can wait");	
*/</script>	
...
Lazy HTML
<!doctype html>	
<html><body>	
...	
<div id="lazy"><!--	
<p>lots of html goes here...</p>	
--></div>	
...	
<scri...
Lazy HTML test
•  500K (200K gzipped) HTML doc
•  “Sherlock Holmes”
•  comment out 95%
•  still one whole chapter left
htt...
Lazy HTML test results
Lazy HTML - misc
•  Who loads a book?
•  Use case: blog comments
•  SEO? Content is hidden
•  What about display: none?
• ...
Preloads
Preloads
•  Anticipate next page
•  Problems:
- does next page anticipate you?
- parsing and execution time
•  <link prefe...
Preload sans execute
var preload; 	
if (/*@cc_on!@*/false) { // IE 	
preload = function (file) {	
new Image().src = file;	...
Preload, then execute
var loader = function (file, callback) {	
var obj = document.createElement('object'),	
body = docume...
Browser search preload
Chrome search
•  In-browser search box
•  Gives suggestions as you type
•  Visual suggestions in IE8+
IE8 Visual
Search Suggestions
...	
<Item>	
<Text>Currently: Partly Cloudy, 67F</Text>	
<Description>High: 71F Low: 63F</De...
IE8 Visual Search Preload
...	
<Item>	
<Text>any search suggestion</Text>	
<Image 	
source="http://path/to/sprite.png" 	
w...
IE8 Visual Search Preload
IE8 Visual Search Preload
•  didn’t work for CSS and JS
IE8 Visual Search
•  preload images, e.g. sprite
•  DNS lookups via beacons
Animations as distractions…
Distractimations
Parting words
What not to say…
•  “Everyone is on high-speed
these days”
•  “It’s all in the cache”
Do care about
•  Progressive,
non-blocking,
asynchronous downloads
•  Progressive rendering
Thank you!
Stoyan Stefanov
@stoyanstefanov
http://www.phpied.com
Slides: http://slideshare.net/stoyan/
Progressive Downloads and Rendering - take #2
Progressive Downloads and Rendering - take #2
Progressive Downloads and Rendering - take #2
Progressive Downloads and Rendering - take #2
Progressive Downloads and Rendering - take #2
Progressive Downloads and Rendering - take #2
Progressive Downloads and Rendering - take #2
Progressive Downloads and Rendering - take #2
Progressive Downloads and Rendering - take #2
Progressive Downloads and Rendering - take #2
Progressive Downloads and Rendering - take #2
Progressive Downloads and Rendering - take #2
Progressive Downloads and Rendering - take #2
Progressive Downloads and Rendering - take #2
Progressive Downloads and Rendering - take #2
Progressive Downloads and Rendering - take #2
Progressive Downloads and Rendering - take #2
Progressive Downloads and Rendering - take #2
Upcoming SlideShare
Loading in …5
×

Progressive Downloads and Rendering - take #2

8,791 views

Published on

HighLoad++ presentation including:
- single stream data URIs and MHTML
- in CSS and <img> tags
- lazy evaluation, lazy JS and lazy HTML experiment
- browser chrome search preload
- Amazon's post-loaded content
- Google instant's chunks

Published in: Design, Technology
0 Comments
21 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
8,791
On SlideShare
0
From Embeds
0
Number of Embeds
42
Actions
Shares
0
Downloads
105
Comments
0
Likes
21
Embeds 0
No embeds

No notes for slide

Progressive Downloads and Rendering - take #2

  1. 1. Progressive downloads and rendering Stoyan Stefanov, Yahoo! HighLoad++, Moscow, 2010 http://slideshare.net/stoyan/
  2. 2. About me YSlow 2.0
  3. 3. Why progressive?
  4. 4. Importance of performance •  Psychology, physiology •  Effects of waiting •  “Time is money” •  Make people happy
  5. 5. Perception
  6. 6. Perception
  7. 7. Perception
  8. 8. Perception
  9. 9. Time is relative •  Sometimes crawls •  Sometimes flies •  “it depends”
  10. 10. Durations actual expected perceived rem’d time
  11. 11. It feels slower when… •  Unpleasant •  Unknown •  Boring •  Too much to keep track
  12. 12. First time experience •  Unfamiliar = slow •  Optimize empty cache or there will be no full cache
  13. 13. So… go progressive!
  14. 14. But before we begin…
  15. 15. The basics •  Reducing the # HTTP •  Gzip •  Minification •  Image smushing •  Expires •  CDN
  16. 16. The basics •  Yahoo!’s best practices + YSlow http://developer.yahoo.com/performance/ •  Google’s too + Page Speed http://code.google.com/speed/
  17. 17. Progressive
  18. 18. Progressive enhancement
  19. 19. Progressive downloads
  20. 20. Progressive rendering
  21. 21. Agenda 1.  Prevent download blocks: scripts, styles, CC, favicon 2.  Ways to render sooner: flush, data URIs, lazy loading, lazy evaluation, preloading, animations
  22. 22. Blocking JavaScript
  23. 23. JavaScript blocks html js png png
  24. 24. JavaScript blocks •  A no-no! <script src="jquery.js"></script>  <script src="jquery.twitter.js"></script>  <script src="jquery.cookie.js"></script>  <script src="myapp.js"></script> 
  25. 25. This waterfall looks ridiculous html js png png js js js
  26. 26. JavaScript at the bottom html js png png
  27. 27. Non-blocking JavaScript •  defer and async •  Defer: IE innovation, ok to delay, but keep order •  Async: HTML5, whatever <script async src="my.js" onload="doIt()"></script>  <script defer src="my.js" onload="doIt()"></script> 
  28. 28. defer and async timeline DOMContentLoaded load async defer
  29. 29. Non-blocking JavaScript •  Asynchronous loading var h, js = document.createElement('script');  js.src = 'myscript.js';  h = document.getElementsByTagName('head')[0];  h.appendChild(js);  html js png png
  30. 30. Non-blocking JavaScript •  Others: - iframe - XHR - <object> - …
  31. 31. CSS and rendering
  32. 32. Worst enemy? CSS
  33. 33. CSS blocks rendering •  The worst component type •  Place way at the top •  @media print, etc in the same external CSS http://www.phpied.com/delay-loading-your-print-css/ http://www.phpied.com/rendering-styles/
  34. 34. CSS
  35. 35. CSS
  36. 36. CSS block downloads? But they do block: •  When followed by an inline script •  When in conditional comments
  37. 37. Inline CSS •  Google search •  Bing.com: inline + postload
  38. 38. Same domain •  If you split across domains •  and if you don’t use CDN •  Saves a DNS lookup •  e.g. Google and Bing’s CDN
  39. 39. CC block
  40. 40. Normal page
  41. 41. With conditionally commented CSS file http://www.phpied.com/
 conditional-comments-block-downloads/
  42. 42. What…?! Case #1   <link type="text/css" rel="stylesheet"          href="1.css">    <!‐‐[if IE 6]>      <link type="text/css" rel="stylesheet"            href="ie.css">    <![endif]‐‐> 
  43. 43. What…?! Case #2 <!‐‐[if IE 6]>      <body class="ie6">   <![endif]‐‐>  <!‐‐[if !IE]><!‐‐>      <body>  <!‐‐<![endif]‐‐> 
  44. 44. Solution for case #1 <!DOCTYPE html>  <!‐‐[if IE 6]><![endif]‐‐>  <html>      ... 
  45. 45. Solution for case #2 <!‐‐[if IE 6]>      <html class="ie6">   <![endif]‐‐>  <!‐‐[if !IE]><!‐‐>      <html>  <!‐‐<![endif]‐‐> 
  46. 46. Blocking favicon
  47. 47. Flush
  48. 48. flush() early html png js css html png js css ✔ 
  49. 49. flush() <html> <head> <script src="my.js" type="text/javascript"></script> <link href="my.css" type="text/css" rel="stylesheet" /> </head> <body> .... <?php flush() ?>
  50. 50. Chunked encoding HTTP/1.1 200 OK  Content‐Type: text/plain  Transfer‐Encoding: chunked  25  This is the data in the first chunk  1C  and this is the second one  0 
  51. 51. Chunked encoding •  Progressive rendering - Semantic app chunks vs. - Server-level chunks
  52. 52. Progressive rendering Chunk #1 Chunk #2 Chunk #3
  53. 53. <!doctype html> <html> <head><title>My App</title></head> <body> <div id="header"> <img src="logo.png" /> ... </div> <!-- end of chunk #1 --> ... The full body of the page ... <!-- end of chunk #2 --> <script src="all_20100925.js"></script> </body> </html> <!-- end of chunk #3 -->
  54. 54. Progressive + source order 1 2 3 4
  55. 55. HTTP chunking: not only HTML
  56. 56. HTTP chunking: not only HTML •  Google Instant •  /*""*/ - delimited JSON pieces •  Chunk #1 suggestions •  Chunk #2 results http://tinyurl.com/chunkview
  57. 57. Data URIs
  58. 58. Fewer HTTP requests •  Inline images: in CSS sprites with data: URI scheme http://csssprites.com http://spriteme.org
  59. 59. Fewer HTTP requests •  data: URI scheme $ php ‐r "echo base64_encode(file_get_contents('my.png'));”  iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAAGElEQVQIW2P4 DwcMDAxAfBvMAhEQMYgcACEHG8ELxtbPAAAAAElFTkSuQmCC 
  60. 60. Fewer HTTP requests •  data: URI scheme background‐image: url("data:image/png;base64,iVBORw0KG..."); 
  61. 61. Fewer HTTP requests •  data: URI scheme <img src="data:image/png;base64,iVBOR..." /> 
  62. 62. Both •  flushes •  data: URIs
  63. 63. Fewer HTTP requests •  data: URI scheme •  works in IE!...
  64. 64. Fewer HTTP requests •  data: URI scheme •  works in IE8!
  65. 65. Fewer HTTP requests •  data: URI scheme •  MHTML for IE < 8
  66. 66. MHTML •  MIME HTML •  Works in IE 6,7 •  Indeed it actually absolutely does work in IE7/Vista too http://phpied.com
 /the-proper-mhtml-syntax/
  67. 67. MHTML - one part Content-Location: myimage Content-Transfer-Encoding: base64 iVBORw0KGgoAAAANSU....U5ErkJggg==
  68. 68. MHTML - multi parts Content-Type: multipart/related; boundary="MYSEPARATOR" --MYSEPARATOR [here comes part one] --MYSEPARATOR [here's part two] --MYSEPARATOR-- The double- dash of doom
  69. 69. MHTML.css – 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); }
  70. 70. MHTML: inline too<!doctype html> <html> <head> <title>Look Ma' No HTTP requests</title> <style type="text/css"> /* Content-Type: multipart/related; boundary="_" --_ Content-Location:locoloco Content-Transfer-Encoding:base64 iVBOR...CC --_ Content-Location:polloloco Content-Transfer-Encoding:base64 iVBOR....gg== --_-- */ .image1 { background-image: url("data:image/png;base64,iVBOR...CC"); /* normal */ *background-image: url(mhtml:http://...html!locoloco); /* IE < 8 */ } .image2 { background-image: url("data:image/png;base64,iVBOR...gg=="); /* normal */ *background-image: url(mhtml:http://...html!polloloco); /* IE < 8 */ } body { font: bold 24px Arial; } </style> </head> <body> <h1>MHTML + Data:URIs inline in <code>style</code></h1> <p class="image1">hello<br>hello</p> <p class="image2">bonjour<br>bonjour</p> </body> </html> http://phpied.com
 /inline-mhtml-data-uris/
  71. 71. <!doctype html> <html> <head> <title>Look Ma' No HTTP requests</title> <style type="text/css"> ...
  72. 72. /* Content-Type: multipart/related; boundary="_" --_ Content-Location:locoloco Content-Transfer-Encoding:base64 iVBOR...CC --_ Content-Location:polloloco Content-Transfer-Encoding:base64 iVBOR....gg== --_-- */
  73. 73. .image1 { background-image: url("data:image/png;base64,iVBOR...CC"); /* normal */ *background-image: url(mhtml:http://...html!locoloco); /* IE < 8 */ } .image2 { background-image: url("data:image/png;base64,iVBOR...gg=="); /* normal */ *background-image: url(mhtml:http://...html!polloloco); /* IE < 8 */ } body { font: bold 24px Arial; }
  74. 74. ... </style> </head> <body> <h1>MHTML + Data:URIs inline in <code>style</code></h1> <p class="image1">hello<br>hello</p> <p class="image2">bonjour<br>bonjour</p> </body> </html>
  75. 75. MHTML + data URI •  X-browser single request web apps
  76. 76. Single request •  WT☠? •  Separation of concerns •  Content-presentation- behavior •  yes, it’s a tradeoff
  77. 77. MHTML + data URI •  drawback: repeats the same encoded image •  solutions: - browser-specific CSS - keep close = better gzip - or… an ingenious hack
  78. 78. Single stream 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/
  79. 79. /* Content-Type: multipart/related; boundary="granitza" --granitza Content-Type: text/css; */ #myid { /* --granitza Content-Location: myimage Content-Transfer-Encoding: base64 Content-Type: image/jpeg;*/ /9j/4AA0;background-image:url(data:image/jpeg;base64;00,/9j/4AAQSkZJRgA...); /* --granitza Content-Type: text/css; */ background-image: url(mhtml:http://localhost/my.css!myimage) !ie; } /* --granitza-- */
  80. 80. /* Content-Type: multipart/related; boundary="granitza" --granitza Content-Type: text/css; */ #myid { /* --granitza Content-Location: myimage Content-Transfer-Encoding: base64 Content-Type: image/jpeg;*/ /9j/4AA0;background-image:url(data:image/jpeg;base64;00,/9j/4AAQSkZJRgA...); /* --granitza Content-Type: text/css; */ background-image: url(mhtml:http://localhost/my.css!myimage) !ie; } /* --granitza-- */ ???
  81. 81. /* Content-Type: multipart/related; boundary="granitza" --granitza Content-Type: text/css; */ #myid { /* --granitza Content-Location: myimage Content-Transfer-Encoding: base64 Content-Type: image/jpeg;*/ /9j/4AA0;background-image:url(data:image/jpeg;base64;00,/9j/4AAQSkZJRgA...); /* --granitza Content-Type: text/css; */ background-image: url(mhtml:http://localhost/my.css!myimage) !ie; } /* --granitza-- */
  82. 82. /* Content-Type: multipart/related; boundary="granitza" --granitza Content-Type: text/css; */ #myid { /* --granitza Content-Location: myimage Content-Transfer-Encoding: base64 Content-Type: image/jpeg;*/ /9j/4AA0;background-image:url(data:image/jpeg;base64;00,/9j/4AAQSkZJRgA...); /* --granitza Content-Type: text/css; */ background-image: url(mhtml:http://localhost/my.css!myimage) !ie; } /* --granitza-- */ ???1 2 3
  83. 83. Single stream MHTML/data URI •  And for <img> too!
  84. 84. Single stream <img> <h2>Hello Kitty</h2> <! --granitza Content-Location: myimage Content-Transfer-Encoding: base64 Content-Type: image/gif 2 invalid MHTML headers lines followed by data--><![if gt IE 7]> <img width="16" height="16" src="data:image/gif;base64, R0lGODl ... FxMKVvDijNQaodOl+N5Pk+pmIX7brGweCg4SCEhEAOw=="><![endif]> <!--[if lt IE 8]> <img src="mhtml:http://.../bolknote.html!myimage" width="16" height="16"> <![endif]--> <p> more page... </p>
  85. 85. Single stream <img> <h2>Hello Kitty</h2> <! --granitza Content-Location: myimage Content-Transfer-Encoding: base64 Content-Type: image/gif 2 invalid MHTML headers lines followed by data--><![if gt IE 7]> <img width="16" height="16" src="data:image/gif;base64, R0lGODl ... FxMKVvDijNQaodOl+N5Pk+pmIX7brGweCg4SCEhEAOw=="><![endif]> <!--[if lt IE 8]> <img src="mhtml:http://.../bolknote.html!myimage" width="16" height="16"> <![endif]--> <p> more page... </p>
  86. 86. Lazy loading
  87. 87. Lazy loading aka post-loading •  After-onload •  Some images •  Below the fold (on scroll) •  Hidden content e.g. tabs
  88. 88. Amazon’s lazy bestsellers •  Page’s purpose is ranking •  Details can come later •  via onload XHR •  JS off = no details •  but that’s fine (see bullet #1)
  89. 89. Lazy evaluation
  90. 90. GMail mobile’s lazy JS <!doctype html> <html><body> ... <script id="lazy">/* console.log("I can wait"); */</script> ... <script> console.log("I'm needed"); window.onload = function () { var comment = document.getElementById('lazy') .innerHTML, code = comment.substring(3, comment.length - 3); eval(code); }; </script> </body></html> http://googlecode.blogspot.com/2009/09
 /gmail-for-mobile-html5-series-reducing.html
  91. 91. Lazy HTML <!doctype html> <html><body> ... <div id="lazy"><!-- <p>lots of html goes here...</p> --></div> ... <script> window.onload = function () { var el = document.getElementById('lazy'), inner = el.innerHTML, code = inner.substring(4, inner.length - 3); el.innerHTML = code; }; </script> </body></html> http://phpied.com... (coming-soon)
  92. 92. Lazy HTML test •  500K (200K gzipped) HTML doc •  “Sherlock Holmes” •  comment out 95% •  still one whole chapter left http://www.phpied.com/files/lazyhtml/start.html
  93. 93. Lazy HTML test results
  94. 94. Lazy HTML - misc •  Who loads a book? •  Use case: blog comments •  SEO? Content is hidden •  What about display: none? •  The test page was simple-to- render, no complex layout
  95. 95. Preloads
  96. 96. Preloads •  Anticipate next page •  Problems: - does next page anticipate you? - parsing and execution time •  <link prefetch="http://..">
  97. 97. Preload sans execute var preload; if (/*@cc_on!@*/false) { // IE preload = function (file) { new Image().src = file; }; } else { preload = function (file) { var obj = document.createElement('object'), body = document.body; obj.width = 0; obj.height = 0; obj.data = file; body.appendChild(obj); }; }
  98. 98. Preload, then execute var loader = function (file, callback) { var obj = document.createElement('object'), body = document.body; obj.width = 0; obj.height = 0; obj.data = file; obj.onload = function () { var h, js = document.createElement('script'); js.src = file; js.onload = callback; h = document.getElementsByTagName('head')[0]; h.appendChild(js); }; body.appendChild(obj); };
  99. 99. Browser search preload
  100. 100. Chrome search •  In-browser search box •  Gives suggestions as you type •  Visual suggestions in IE8+
  101. 101. IE8 Visual Search Suggestions ... <Item> <Text>Currently: Partly Cloudy, 67F</Text> <Description>High: 71F Low: 63F</Description> <Url>http://weather.yahoo.com/forecast/ USCA1024_f.html</Url> <Image source="http://l.yimg.com/a/i/us/we/31/30.gif" alt="Partly Cloudy" width="31" height="31"/> </Item> ...
  102. 102. IE8 Visual Search Preload ... <Item> <Text>any search suggestion</Text> <Image source="http://path/to/sprite.png" width="0" height="0"/> </Item> ...
  103. 103. IE8 Visual Search Preload
  104. 104. IE8 Visual Search Preload •  didn’t work for CSS and JS
  105. 105. IE8 Visual Search •  preload images, e.g. sprite •  DNS lookups via beacons
  106. 106. Animations as distractions…
  107. 107. Distractimations
  108. 108. Parting words
  109. 109. What not to say… •  “Everyone is on high-speed these days” •  “It’s all in the cache”
  110. 110. Do care about •  Progressive, non-blocking, asynchronous downloads •  Progressive rendering
  111. 111. Thank you! Stoyan Stefanov @stoyanstefanov http://www.phpied.com Slides: http://slideshare.net/stoyan/

×