Progressive downloads and rendering
Download
1 / 126

Progressive downloads and rendering - PowerPoint PPT Presentation


  • 76 Views
  • Uploaded on

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.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about ' Progressive downloads and rendering' - luana


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
Progressive downloads and rendering

Progressive downloads and rendering

Stoyan Stefanov, Yahoo!

HighLoad++, Moscow, 2010

http://slideshare.net/stoyan/


About me

About me

YSlow 2.0



Importance of performance

Importance of performance

Psychology, physiology

Effects of waiting

“Time is money”

Make people happy






Time is relative

Time is relative

Sometimes crawls

Sometimes flies

“it depends”


Durations

Durations

actual

expected

perceived

rem’d

time


It feels slower when

It feels slower when…

Unpleasant

Unknown

Boring

Too much to keep track


First time experience

First time experience

Unfamiliar = slow

Optimize empty cache or there will be no full cache


So go progressive

So… go progressive!



The basics

The basics

Reducing the # HTTP

Gzip

Minification

Image smushing

Expires

CDN


The basics1

The basics

Yahoo!’s best practices + YSlow

http://developer.yahoo.com/performance/

Google’s too + Page Speed

http://code.google.com/speed/






Agenda

Agenda

Prevent download blocks: scripts, styles, CC, favicon

Ways to render sooner: flush, data URIs, lazy loading, lazy evaluation, preloading, animations



Javascript blocks

JavaScript blocks

html

js

png

png


Javascript blocks1

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>


This waterfall looks ridiculous

This waterfall looks ridiculous

html

js

js

js

js

png

png


Javascript at the bottom

JavaScript at the bottom

html

png

png

js


Non blocking javascript

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>


Defer and async timeline

defer and async timeline

async

defer

DOMContentLoaded

load


Non blocking javascript1

Non-blocking JavaScript

html

js

png

Asynchronous loading

varh, js= document.createElement('script');

js.src = 'myscript.js';

h= document.getElementsByTagName('head')[0];

h.appendChild(js);

png


Non blocking javascript2

Non-blocking JavaScript

Others:

- iframe

- XHR

- <object>

- …




Css blocks rendering

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/




Css block downloads

CSS blockdownloads?

But they do block:

When followed by an inline script

When in conditional comments


Inline css

Inline CSS

Google search

Bing.com: inline + postload


Same domain

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




With conditionally commented css file

With conditionally commented CSS file

http://www.phpied.com/conditional-comments-block-downloads/


What case 1

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]-->


What case 2

What…?! Case #2

<!--[if IE 6]>

<body class="ie6">

<![endif]-->

<!--[if !IE]><!-->

<body>

<!--<![endif]-->


Solution for case 1

Solution for case #1

<!DOCTYPE html>

<!--[if IE 6]><![endif]-->

<html>

...


Solution for case 2

Solution for case #2

<!--[if IE 6]>

<html class="ie6">

<![endif]-->

<!--[if !IE]><!-->

<html>

<!--<![endif]-->


Blocking favicon

Blocking favicon



Flush early

flush() early

html

png

js

css

html

png

js

css


Flush1

flush()

<html>

<head>

<script src="my.js"

type="text/javascript"></script>

<link href="my.css"

type="text/css" rel="stylesheet" />

</head>

<body>

....

<?php flush() ?>


Chunked encoding

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


Chunked encoding1

Chunked encoding

Progressive rendering

- Semantic app chunks

vs.

- Server-level chunks


Progressive rendering1

Progressive rendering

Chunk #1

Chunk #2

Chunk #3


<!doctype html>

<html>

<head><title>My App</title></head>

<body>

<div id="header">

<imgsrc="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 -->




Http chunking not only html1

HTTP chunking: not only HTML

Google Instant

/*""*/ - delimited JSON pieces

Chunk #1 suggestions

Chunk #2 results

http://tinyurl.com/chunkview



Fewer http requests

Fewer HTTP requests

Inline images:

in CSS sprites

with data: URI scheme

http://csssprites.com

http://spriteme.org


Fewer http requests1

Fewer HTTP requests

data: URI scheme

$ php -r "echo base64_encode(file_get_contents('my.png'));”

iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAAGElEQVQIW2P4DwcMDAxAfBvMAhEQMYgcACEHG8ELxtbPAAAAAElFTkSuQmCC


Fewer http requests2

Fewer HTTP requests

data: URI scheme

background-image: url("data:image/png;base64,iVBORw0KG...");


Fewer http requests3

Fewer HTTP requests

data: URI scheme

<imgsrc="data:image/png;base64,iVBOR..." />


Both

flushes

data: URIs


Fewer http requests4

Fewer HTTP requests

data: URI scheme

works in IE!...


Fewer http requests5

Fewer HTTP requests

data: URI scheme

works in IE8!


Fewer http requests6

Fewer HTTP requests

data: URI scheme

MHTML for IE < 8


Mhtml

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/


Mhtml one part

MHTML - one part

Content-Location: myimage

Content-Transfer-Encoding: base64

iVBORw0KGgoAAAANSU....U5ErkJggg==


Mhtml multi parts

MHTML - multi parts

The double-dash of doom

Content-Type: multipart/related; boundary="MYSEPARATOR"

--MYSEPARATOR

[here comes part one]

--MYSEPARATOR

[here's part two]

--MYSEPARATOR--


Mhtml css all together

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);

}


Mhtml inline too

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/


Doctype html html head title look ma no http requests title style type text css

<!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>


Mhtml data uri

MHTML + data URI

X-browser

single request

web apps


Single request

Single request

WT☠?

Separation of concerns

Content-presentation-behavior

yes, it’s a tradeoff


Mhtml data uri1

MHTML + data URI

drawback: repeats the same encoded image

solutions:

- browser-specific CSS

- keep close = better gzip

- or… an ingenious hack


Single stream mhtml data uri

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/


/*

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--

*/


???

/*

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--

*/


/*

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

/*

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--

*/

3


Single stream mhtml data uri1

Single stream MHTML/data URI

And for <img> too!


Single stream img

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]>

<imgsrc="mhtml:http://.../bolknote.html!myimage" width="16" height="16">

<![endif]-->

<p> more page... </p>


Single stream img1

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]>

<imgsrc="mhtml:http://.../bolknote.html!myimage" width="16" height="16">

<![endif]-->

<p> more page... </p>



Lazy loading aka post loading

Lazy loading aka post-loading

After-onload

Some images

Below the fold (on scroll)

Hidden content e.g. tabs


Amazon s lazy bestsellers

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)



Gmail mobile s lazy js

GMail mobile’s lazy JS

<!doctype html>

<html><body>

...

<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>

</body></html>

http://googlecode.blogspot.com/2009/09/gmail-for-mobile-html5-series-reducing.html


Lazy html

Lazy HTML

<!doctype html>

<html><body>

...

<divid="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)


Lazy html test

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



Lazy html misc

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



Preloads1

Preloads

Anticipate next page

Problems:

- does next page anticipate you?

- parsing and execution time

<link prefetch="http://..">


Preload sans execute

Preload sans execute

varpreload;

if (/*@[email protected]*/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);

};

}


Preload then execute

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);

};



Chrome search

Chrome search

In-browser search box

Gives suggestions as you type

Visual suggestions in IE8+


Ie8 visual search suggestions

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>

...


Ie8 visual search preload

IE8 Visual Search Preload

...

<Item>

<Text>any search suggestion</Text>

<Image

source="http://path/to/sprite.png"

width="0"

height="0"/>

</Item>

...



Ie8 visual search preload2

IE8 Visual Search Preload

didn’t work for CSS and JS


Ie8 visual search

IE8 Visual Search

preload images, e.g. sprite

DNS lookups via beacons



Do care about

Do care about

Progressive,

non-blocking,

asynchronous downloads

Progressive rendering


Thank you

Thank you!

Stoyan Stefanov

@stoyanstefanov

http://www.phpied.com

Slides: http://slideshare.net/stoyan/


ad