Mais conteúdo relacionado Semelhante a Progressive downloads and rendering (Stoyan Stefanov) (20) Progressive downloads and rendering (Stoyan Stefanov)12. Durations
actual
expected
perceived
rem’d
time
13. It feels slower when…
• Unpleasant
• Unknown
• Boring
• Too much to keep track
17. The basics
• Reducing the # HTTP
• Gzip
• Minification
• Image smushing
• Expires
• CDN
18. The basics
• Yahoo!’s best practices +
YSlow
http://developer.yahoo.com/performance/
• Google’s too +
Page Speed
http://code.google.com/speed/
24. Agenda
1. Prevent download blocks:
scripts, styles, CC, favicon
2. Ways to render sooner:
flush, data URIs, lazy loading,
lazy evaluation, preloading,
animations
27. 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>
30. Non-blocking JavaScript
• deferand async
• Defer: IE innovation, ok to
delay, but keep order
• Async: HTML5, whatever
<script asyncsrc="my.js" onload="doIt()"></script>
<script defer src="my.js" onload="doIt()"></script>
32. Non-blocking JavaScript
• Asynchronous loading
html
js
png
png
varh, js= document.createElement('script');
js.src = 'myscript.js';
h= document.getElementsByTagName('head')[0];
h.appendChild(js);
36. 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/
41. 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
45. 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]-->
48. Solution for case #2
<!--[if IE 6]>
<html class="ie6">
<![endif]-->
<!--[if !IE]><!-->
<html>
<!--<![endif]-->
54. 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
60. HTTP chunking: not only HTML
• Google Instant
• /**/ - delimited JSON
pieces
• Chunk #1 suggestions
• Chunk #2 results
http://tinyurl.com/chunkview
62. Fewer HTTP requests
• Inline images:
in CSS sprites
with data: URI scheme
http://csssprites.com
http://spriteme.org
63. Fewer HTTP requests
• data: URI scheme
$ php -r echo base64_encode(file_get_contents('my.png'));”
iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAAGElEQVQIW2P4
DwcMDAxAfBvMAhEQMYgcACEHG8ELxtbPAAAAAElFTkSuQmCC
81. 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/
82. MHTML - one part
Content-Location: myimage
Content-Transfer-Encoding: base64
iVBORw0KGgoAAAANSU....U5ErkJggg==
83. 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--
84. 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);
}
85. MHTML: inline too
!doctype html
html
head
titleLook 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
h1MHTML + Data:URIs inline in codestyle/code/h1
p class=image1hellobrhello/p http://phpied.com
p class=image2bonjourbrbonjour/p
/body
/html
/inline-mhtml-data-uris/
88. .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;
}
92. MHTML + data URI
• drawback: repeats the same
encoded image
• solutions:
- browser-specific CSS
- keep close = better gzip
- or… an ingenious hack
93. 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/
94. /*
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--
*/
95. /*
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--
*/
96. /*
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--
*/
97. /*
Content-Type: multipart/related; boundary=granitza
--granitza
Content-Type: text/css;
*/ 1 ???
#myid {
/*
--granitza
Content-Location: myimage
2
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;
3
}
/*
--granitza--
*/
99. Single stream img
h2Hello 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]
imgsrc=mhtml:http://.../bolknote.html!myimage width=16 height=16
![endif]--
p more page... /p
100. Single stream img
h2Hello 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]
imgsrc=mhtml:http://.../bolknote.html!myimage width=16 height=16
![endif]--
p more page... /p
102. Lazy loading aka post-loading
• After-onload
• Some images
• Below the fold (on scroll)
• Hidden content e.g. tabs
105. 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)
107. GMail mobile’s lazy JS
!doctype html
htmlbody
...
scriptid=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 http://googlecode.blogspot.com/2009/09
/body/html /gmail-for-mobile-html5-series-reducing.html
109. Lazy HTML
!doctype html
htmlbody
...
divid=lazy!--
plots 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)
110. 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
112. 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
114. Preloads
• Anticipate next page
• Problems:
- does next page anticipate you?
- parsing and execution time
•link prefetch=http://..
115. Preload sans execute
varpreload;
if (/*@cc_on!@*/false) { // IE
preload = function (file) {
new Image().src = file;
};
} else {
preload = function (file) {
varobj = document.createElement('object'),
body = document.body;
obj.width = 0;
obj.height = 0;
obj.data = file;
body.appendChild(obj);
};
}
116. Preload, then execute
varloader = function (file, callback) {
varobj = document.createElement('object'),
body = document.body;
obj.width = 0;
obj.height = 0;
obj.data = file;
obj.onload = function () {
varh,js= document.createElement('script');
js.src =file;
js.onload=callback;
h = document.getElementsByTagName('head')[0];
h.appendChild(js);
};
body.appendChild(obj);
};
119. IE8 Visual
Search Suggestions
...
Item
TextCurrently: Partly Cloudy, 67F/Text
DescriptionHigh: 71F Low: 63F/Description
Urlhttp://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
...
120. IE8 Visual Search Preload
...
Item
Textany search suggestion/Text
Image
source=http://path/to/sprite.png
width=0
height=0/
/Item
...
125. Do care about
• Progressive,
non-blocking,
asynchronous downloads
• Progressive rendering
Notas do Editor c Dev process, philosophy Non-blockingasynchronousFree-falling waterfalls Rendering something quickly ~200ms - instanteneous redesign c c c c - 3 times faster on 3G, 4 and 1/2 times faster on WiFi - still faster after evaluation - DOMContentLoaded happens sooner S S S S S Showing something in 200 ms is incredible, users will love it