all you need to know about javascript loading and execution in the browser - jsconf br 2013
Post on 15-Jan-2015
3.475 Views
Preview:
DESCRIPTION
TRANSCRIPT
ALL YOU NEED TO KNOW ABOUTJAVASCRIPTLOADING AND EXECUTIONIN THE BROWSER
<SCRIPT language="JavaScript">//<![CDATA[alert('
');//]]></SCRIPT>
@sergio_caelumsergiolopes.org
<script src="/js/main.js"></script>
THE END
THE END?
HOW BROWSERS LOAD AND EXECUTE JS
disclaimer
HOW BROWSERS LOAD AND EXECUTE JS
<html><head> <script src="main.js"></script></head><body> ...</body></html>
JS BLOCKS RENDERING
JS BLOCKS RENDERING
JS BLOCKS RENDERINGNETWORK LATENCY
PARSING TIMEEXECUTION TIME
AVAILABILITY (SPOF)
PUT JS AT BOTTOM
<html><head> <script src="main.js"></script></head><body> ...
</body></html>
<html><head>
</head><body> ... <script src="main.js"></script></body></html>
DEFER
<html><head> <script src="main.js" defer></script></head><body> ...</body></html>
<html><head> <script src="main.js" defer></script> <script src="other.js" defer></script></head><body> ...</body></html>
PUT JS AT BOTTOMPLUS: NO NEED FOR $(document).ready(..) ANYMORE
MULTIPLE SCRIPTS
<script src="jquery.js"></script><script src="jquery.plugin.js"></script><script src="application.js"></script>...
LATENCY
SCRIPT CONCATENATION
SCRIPT CONCATENATION1 SCRIPT? 2 SCRIPTs?
SEQUENTIAL EXECUTION
ASYNC LOADING
var js = document.createElement('script');js.src = 'script.js';document.head.appendChild(js);
<script src="main.js" async></script><script src="other.js" async></script>
<html><head> <script src="main.js" async></script> <script src="other.js" async></script></head><body>
</body></html>
EXECUTION ORDER?
SEPARATE DOWNLOAD FROM EXECUTION
<script src="main.js" type="bla"></script>
<script src="main.js"></script>
<script src="main.js"></script>
/* alert('Everything commented out'); ... */
<script src="main.js"></script>
/* alert('Everything commented out'); ... */
eval(js_code_inside_comments);
new Image().src = 'script.js';
new Image().src = 'script.js';
<script src="script.js"></script>
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = function(js){ if (ajax.readyState == 4) // execute js in order};
ajax.open('script.js');ajax.send();
Ajax
var js = document.createElement('script');js.src = 'script.js';
IE
var js = document.createElement('script');
js.src = 'script.js';
IE
js.onreadystatechange = function(){ if (js.readyState == 'loaded') document.head.appendChild(js);};
var js = document.createElement('script');js.preload = true;js.onpreload = function(){ // ...};
js.src = 'script.js';
preload=true
var js = document.createElement('script');js.async = false;js.src = 'script.js';document.head.appendChild(js);
async=false
SCRIPT LOADERS
$LAB.script('jquery.js').wait() .script('plugin1.js') .script('plugin2.js') .script('plugin3.js').wait() .script('application.js');
LABjs
DISCOVERABILITY
<script src="labjs.js"></script>
<script>$LAB.script('jquery.js').wait() .script('plugin1.js') .script('plugin2.js') .script('plugin3.js').wait() .script('application.js');</script>
<script>/* inline ~2KB do LABjs */</script>
<script>$LAB.script('jquery.js').wait() .script('plugin1.js') .script('plugin2.js') .script('plugin3.js').wait() .script('application.js');</script>
LOOK AHEAD PRE-PARSER
<link rel="prefetch" href="script.js">
<link rel="subresource" href="script.js">
<link rel="subresource prefetch" href="script.js">
ASYNC EXECUTION
<script src="script1.js" async></script><script src="script2.js" async></script><script src="script3.js" async></script>
DEPENDENCIES?
order != dependency
<script src="script1.js"></script><script src="script2.js"></script><script src="script3.js"></script><script src="script4.js"></script><script src="script5.js"></script>
AMDASYNCHRONOUS MODULE DEFINITION
* OR SOMETHING SIMILAR
$('#panel').fadein();
define('app', ['jquery'], function($) {
}); $('#panel').fadein();
var jQuery = // ...
var jQuery = // ... function() {
return jQuery;}
define('jquery',[],
);
var jQuery = // ... function() {
return jQuery;}
BETTER CODE
ASYNC DEPENDENCY EXECUTION
Require.js
<script src="require.js" data-main= "myapp"></script>
<script src="require.js" data-main= "myapp"></script>
myapp.js
<script src="require.js" data-main= "myapp"></script>
myapp.js
mymodel.js mycontroller.js
<script src="require.js" data-main= "myapp"></script>
myapp.js
mymodel.js mycontroller.js
util.js plugin1.js plugin2.js
<script src="require.js" data-main= "myapp"></script>
myapp.js
mymodel.js mycontroller.js
jquery.js
util.js plugin1.js plugin2.js
BUILD
r.js + almond
r.js + almondr.js -o baseUrl=. name=almond include=main out=all.js wrap=true
<script src="all.js"></script>
myapp.js
mymodel.js mycontroller.js
jquery.js
util.js plugin1.js plugin2.js
all.js
almond.js
myapp.js
mymodel.js mycontroller.js
jquery.js
util.js plugin1.js plugin2.js
almond.jsbase.js
mypage.js
<script src="base.js"></script><script src="mypage.js"></script>
<script>/* 250b AMD define */</script>
<script src="base.js" async></script><script src="modules.js" async></script><script src="more.js" async></script>
FUTURE
TEST: 200 JS modules, ~13KB each
#1200 .js files + 1 HTML file<script async>HTTP
TEST: 200 JS modules, ~13KB each
#21 .js file + 1 HTML file<script async>HTTP
TEST: 200 JS modules, ~13KB each
#3200 .js files + 1 HTML file<script async>SPDY
200 files
1 file
0 12500 25000 37500 50000
HTTP:
200 files
1 file
200 files
1 file
0 12500 25000 37500 50000
HTTP:
SPDY:
SPDY & HTTP 2.0
FUTURE #2
module utils { var local = 0; export var exposed = "Public API";}
Modules
Modules
module main { import exposed from utils; console.log(exposed);}
ES-HARMONY
<script>deferasync
SCRIPT LOADERSprefetch / subresource
AMDrequire.js / r.js / almond
SPDY & HTTP 2ES-HARMONY MODULES *
ALL YOU NEED TO KNOW ABOUTJAVASCRIPTLOADING AND EXECUTIONIN THE BROWSER
<SCRIPT language="JavaScript">//<![CDATA[alert('
');//]]></SCRIPT>
THANK YOUsergiolopes.org
@sergio_caelum
<SCRIPT language="JavaScript">//<![CDATA[alert('
');//]]></SCRIPT>
top related