JavaScript Performance (at SFJS)

Post on 10-May-2015

16,075 views 2 download

description

A deep dive into async script loading.

transcript

JavaScript Performance

stevesouders.com/docs/sfjs-20120112.pptxDisclaimer: This content does not necessarily reflect the opinions of my employer.

Cuzillion SpriteMeYSlow Hammerhead

drives traffic

improves UX

increases revenue

reduces costs

Web

Performance

OptimizationWPO

What’s the #1 cause

of slow web pages?

JAVASCRIPT!

{31%

all requests containing “.js” are skipped

http://httparchive.org/trends.php?s=intersection

1995: scripts in HEAD

<head><script src=‘a.js’></script></head>

blocks other downloads (IE 6-7, images in IE, iframes)

downloaded sequentially (IE 6-7)

blocks rendering during download & parse-execute

2007: move scripts to bottom

...<script src=‘a.js’></script></body>

doesn’t block other downloads

downloaded sequentially in IE 6-7

blocks rendering during download & parse-execute

2009: load scripts async

var se = document.createElement(‘script’);

se.src = ‘a.js’;document.getElementsByTagName(‘head’)[0].appendChild(se);

doesn’t block other downloads

downloaded in parallel (all browsers)

blocks rendering during parse-execute

2010: async + on-demand exec

var se = new Image(); // Objectse.onload = registerScript;se.src = ‘a.js’;

separate download from parse-execute

doesn’t block other downloads

downloaded in parallel (all browsers)

doesn’t block rendering until demanded

20??: markup

script async & deferparsing doesn’t wait for script:• async – executed when available• defer – executed when parsing finished

when is it downloaded?

missing:• defer download AND execution• async/defer download, execute on demand

20??: markup

<script src=‘a.js’ [async|defer|noexecute] [deferdownload]>

doesn’t block downloads

downloaded in parallel

doesn’t block rendering until demanded

doesn’t contend for a connection

easier

ControlJSa JavaScript module for making scripts load faster

just change HTML

inline & external scripts

<script type=‘text/cjs’ data-cjssrc=‘main.js’></script>

<script type=‘text/cjs’>var name = getName();</script>

http://controljs.org/

ControlJSa JavaScript module for making scripts load faster

download without executing<script type=‘text/cjs’ data-cjssrc=‘main.js’ data-cjsexec=false><script>

Later if/when needed:CJS.execScript(src);

GMail Mobile<script type=‘text/javascript’>

/*

var ...

*/

</script>

get script DOM element's text

remove comments

eval() when invoked

awesome for prefetching JS that might (not) be needed

http://goo.gl/l5ZLQ

localStorage

yuiblog.com/blog/2007/01/04/performance-research-part-2/

blaze.io/mobile/understanding-mobile-cache-sizes/

Home screen apps on iPhone are slower because resources

are re-requested even though they should be read from

cache.

localStoragewindow.localStorage:

setItem()getItem()removeItem()clear()

also sessionStorage

all popular browsers, 5MB maxhttp://dev.w3.org/html5/webstorage/http://diveintohtml5.org/storage.html

localStorage as cache

1st doc: write JS & CSS blocks to localStoragemres.-0yDUQJ03U8Hjija: <script>(function(){...

set cookie with entries & versionMRES=-0yDUQJ03U8Hjija:-4EaJoFuDoX0iloI:...

later docs: read JS & CSS from localStoragedocument.write( localStorage.getItem(mres.-0yDUQJ03U8Hjija) );

http://stevesouders.com/blog/2011/03/28/storager-case-study-bing-google/

Google Analytics Async Snippet

var ga = document.createElement(‘script’);ga.type = ‘text/javascript’;ga.async = true;ga.src = (‘https:’ == document.location.protocol ? ‘https://ssl’ : ‘http://www’)+‘.google-analytics.com/ga.js’;

var s = document.getElementsByTagName(‘script’)[0];

s.parentNode.insertBefore(ga, s);

code.google.com/apis/analytics/docs/tracking/asyncTracking.html

var ga = document.createElement(‘script’);ga.type = ‘text/javascript’;ga.async = true;ga.src = (‘https:’ == document.location.protocol ? ‘https://ssl’ : ‘http://www’)+‘.google-analytics.com/ga.js’;

var s = document.getElementsByTagName(‘script’)[0];

s.parentNode.insertBefore(ga, s);

stevesouders.com/blog/2010/02/10/5a-missing-schema-double-download/

avoid mixed content warning

protocol relative URLs have problems

set src last

var ga = document.createElement(‘script’);ga.type = ‘text/javascript’;ga.async = true;ga.src = (‘https:’ == document.location.protocol ? ‘https://ssl’ : ‘http://www’)+‘.google-analytics.com/ga.js’;

var s = document.getElementsByTagName(‘script’)[0];

s.parentNode.insertBefore(ga, s);

stevesouders.com/blog/2010/05/11/appendchild-vs-insertbefore/

stevesouders.com/blog/2010/05/12/autohead-my-first-browserscope-user-test/

previously: getElementsByTagName(‘head’)[0].appendChild(ga)

HEAD might not exist

Android 1.5, iPhone 3.0, Opera 8.50, Safari 3.2

var ga = document.createElement(‘script’);ga.type = ‘text/javascript’;ga.async = true;ga.src = (‘https:’ == document.location.protocol ? ‘https://ssl’ : ‘http://www’)+‘.google-analytics.com/ga.js’;

var s = document.getElementsByTagName(‘script’)[0];

s.parentNode.insertBefore(ga, s);

stevesouders.com/tests/jsorder.php

some browsers preserve execution order

Firefox 3.6, Opera, OmniWeb

stevesouders.com/tests/jsorder.php

var ga = document.createElement(‘script’);ga.type = ‘text/javascript’;ga.async = true;ga.src = (‘https:’ == document.location.protocol ? ‘https://ssl’ : ‘http://www’)+‘.google-analytics.com/ga.js’;

var s = document.getElementsByTagName(‘script’)[0];

s.parentNode.insertBefore(ga, s);

stevesouders.com/tests/jsorder.php

some browsers preserve execution order

Firefox 3.6, Opera, OmniWeb

async=true fixes this (except Opera)

<html><head>

<link rel=stylesheet ...><style>...</style><script [...]></script>

</head>

<body><div><p><ul>

</body></html>

onload:

C

B

A

D

<html><head>

<link rel=stylesheet ...><style>...</style><script [...]></script>

</head>

<body><div><p><ul>

</body></html>

onload:

A

script loads sooner

beacon fires sooner

blocks other async (Opera)

may block rendering

<html><head>

<link rel=stylesheet ...><style>...</style><script [...]></script>

</head>

<body><div><p><ul>

</body></html>

onload:

B

script loads later

beacon fires later

blocks fewer async (Opera)

may block rendering

<html><head>

<link rel=stylesheet ...><style>...</style><script [...]></script>

</head>

<body><div><p><ul>

</body></html>

onload:

C

script loads last

beacon fires late

doesn’t block async

doesn’t block rendering

<html><head>

<link rel=stylesheet ...><style>...</style><script [...]></script>

</head>

<body><div><p><ul>

</body></html>

onload:

script loads after page

beacon fires very late

doesn’t block async

doesn’t block rendering

onload fires sooner

D

more

stevesouders.com/blog/2011/12/01/silk-ipad-galaxy-comparison/

stevesouders.com/mobileperf/mobileperfbkm.php

Top 100

Top 1000

WPO

WebPagetest.org

Cuzillion.com

Browserscope.org

ControlJS.org

localStorage

takeawaysGA snippet is

good

Loadtimer.org

MobilePerf.org

HTTPArchive.org

Velocity

stevesouders.com

@souders

http://stevesouders.com/docs/sfjs-20120112.pptx