Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
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

9,250 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
  • Be the first to comment

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/

×