JavaScript Library Showdown
description
Transcript of JavaScript Library Showdown
JavaScript Library Showdown
Rob Larsen4.30.2009
drunkenfist.com | @rob_reacthttp://media.drunkenfist.com/downloads/libraries.ppt
Who is this Guy Anyway?• 10+ years HTML/CSS/JavaScript all
day • Principal Presentation Engineer at
Cramer• PAST: AdvisorTech, Compete, Demandware, Boston's Weekly Dig,
Gillette, Museum of Science, Boston, PC Connection, State Street, Webex
History• I remember when dHTML was “cool”
document.all(“ftw”)
document.layers[0]
History• And then it wasn’t
(http://www.amazon.com/Macromedia-Flash-5-Upgrade-Windows/dp/B00004WG0L)
History• And then it was actually cool, but
we stopped mentioning dHTML
Photo by Martin Kliehm ( http://www.flickr.com/photos/martin-kliehm/536545606/ )
Perspective• Front end performance
• Library agnostic
What Libraries?• “By the book” JavaScript• “What I Would Normally Do” (small library
with basic x-browser features and nothing else)
• Dojo• jQuery• Prototype/Scriptaculous• YUI
How Will They Be Compared?
• Simple Tasks• Performance (Page render &
execution)• Code Base • Documentation/Overall Presentation• Anecdotes
What Tasks?• Fire a function when the DOM is loaded• That function attaches a click event to an
HTML element• When clicked, a function fires that:• Grabs an RSS feed from Reddit and writes it
into a UL• Grabs a JSON feed from search.twitter.com
and writes it into a UL• Creates an IMG, inserts it into the document
and Fades it up from 0 opacity.
*• “Not Science” the numbers are for
discussion, not for library turf wars• Get it done• Shallow, not deep• Obvious answers- didn’t phone a
friend
Exciting?•Heck Yeah.
Photo by laverrue (http://www.flickr.com/photos/23912576@N05/2940137084/)Photo by ortizmj12 (http://www.flickr.com/photos/23912576@N05/2940137084/)
Let’s Look at Some Code
HTML<html>
<head> <title>JavaScript</title> <script type="text/javascript" src="scripts/base.js"></script> <style type="text/css" media="screen">
@import url("../_assets/styles/screen.css"); </style>
</head> <body>
<div id="container"> <h1>Tell me about <a
href="http://www.google.com/search?q=javascript" id="make-it-so">JavaScript</a></h1>
<div id="twitter"> <!—tweets go here--> </div> <div id="feed"> <!—reddit goes here--> </div> <div id="image"> <!--image goes here--> </div>
</div> </body> </html>
Add Load Event/ Add EventJavaScriptfunction init() {
document.getElementById("make-it-so").addEventListener("click" , results, false);}window.addEventListener("DOMContentLoaded", init, false);Dojodojo.addOnLoad(
function() { dojo.connect(dojo.byId("make-it-so"), 'onclick',
results) }
);jQuery$(document).ready( function() {
$("#make-it-so").click(results);}
);
Add Load Event/ Add EventJavaScriptfunction init() {
document.getElementById("make-it-so").addEventListener("click" , results, false);}window.addEventListener("DOMContentLoaded", init, false);Dojodojo.addOnLoad(
function() { dojo.connect(dojo.byId("make-it-so"), 'onclick',
results) }
);jQuery$(document).ready( function() {
$("#make-it-so").click(results);}
);
Add Load Event/ Add EventPrototypedocument.observe("dom:loaded", function() {
$("make-it-so").observe("click" , results, false);});YUIfunction init() {
YAHOO.util.Event.addListener(YAHOO.util.Dom.get("make-it-so"), "click", results, this); };YAHOO.util.Event.onDOMReady(init);
Add Load Event/ Add EventWIWND//Dean Edwards (http://dean.edwards.name/weblog/2006/06/again/function init() { if (arguments.callee.done) return; arguments.callee.done = true; if (_timer) clearInterval(_timer);
//demoaddEvent(document.getElementById("make-it-so"), "click" , results );
//end demo};if (document.addEventListener) { document.addEventListener("DOMContentLoaded", init, false);};//http://javascript.nwbox.com/IEContentLoaded//*@cc_on @*//*@if (@_win32)(function () {
try {document.documentElement.doScroll('left');
} catch (e) {setTimeout(arguments.callee, 50);return;
}init();
})();/*@end @*/if (/WebKit/i.test(navigator.userAgent)) { // sniff var _timer = setInterval(function() { if (/loaded|complete/.test(document.readyState)) { init(); // call the onload handler } }, 10);};window.onload = init;
Get JSONJavaScript/WIWNDvar twitterJSON = document.createElement("script");twitterJSON.type="text/javascript";twitterJSON.src="http://search.twitter.com/search.json?callback=writeTwitterSearchResults&q=%23javascript&count=10";document.body.appendChild(twitterJSON);Dojodojo.xhrGet( { url: '../json.php?url=http://search.twitter.com/search.json?q=javascript&count=10', handleAs: "json", load: function(responseObject, ioArgs) { writeTwitterSearchResults(responseObject) }
});jQuery$.getJSON("../json.php?url=http://search.twitter.com/search.json?q=javascript&count=10", writeTwitterSearchResults );
Get JSONPrototypeNew Ajax.Request('../json.php?url=http://search.twitter.com/search.json?q=javascript&count=10', {
method:'get',requestHeaders: {Accept: 'application/json'},onSuccess: function(transport){
var json = transport.responseText.evalJSON(true);
writeTwitterSearchResults(json); }
});YUIYAHOO.util.Get.script("http://search.twitter.com/search.json?callback=writeTwitterSearchResults&q=%23javascript&count=10");
XHRJavaScriptgetData : function() {
var data = new XMLHttpRequest();data.onreadystatechange = function(){
if ( data.readyState == 4 && data.responseXML != null) { reddit.parseIt(data.responseXML); }
};data.open("GET",
"../feed.php?url=http://www.reddit.com/r/javascript/.rss", true);data.send(null);
}Dojodojo.xhrGet( {
url: '../feed.php?url=http://www.reddit.com/r/javascript/.rss', handleAs: "xml", load: function(responseObject, ioArgs) { reddit(responseObject)
}});
XHRjQuery$.get("../feed.php?url=http://www.reddit.com/r/javascript/.rss", reddit );Prototype
new Ajax.Request("../feed.php?url=http://www.reddit.com/r/javascript/.rss", {
method: 'get',onSuccess: function(transport) {
reddit(transport.responseXML)}
});YUIvar callback = {
success:reddit }; var request = YAHOO.util.Connect.asyncRequest('GET', "../feed.php?url=http://www.reddit.com/r/javascript/.rss", callback);
Remove ElementJavaScripttwitterDIV.removeChild(document.getElementById("twitter-list"));WIWNDtwitterDIV.innerHTML="";Dojodojo.destroy("twitter-list");jQuery$("#twitter-list").remove();Prototype$("twitter-list").remove();YUItwitterDIV.removeChild(YAHOO.util.Dom.get("twitter-list"));
Add Element, Fade UpJavaScriptvar image = {
insert : function(){if (document.getElementById("fadeMe")) {
document.getElementById("image").removeChild(document.getElementById("fadeMe"));}var newImage = document.createElement("img");newImage.src=
"/web/samples/presentation/_assets/images/javascript.jpg";newImage.setAttribute("id","fadeMe");newImage.style.opacity=0;document.getElementById("image").appendChild(newImage);image.fadeUp();
},fadeUp : function() {
var fadeImage = document.getElementById("fadeMe")if (fadeImage.style.opacity < 1 ) {fadeImage.style.opacity=parseFloat(fadeImage.style.opacity) + .05;var callback = function() {
image.fadeUp();}setTimeout(callback,50);}
}}
Add Element, Fade UpDojovar newImage = document.createElement("img");newImage.src= "/web/samples/presentation/_assets/images/javascript.jpg";newImage.setAttribute("id","fadeMe");newImage.style.opacity=0;dojo.byId("image").appendChild(newImage);dojo.fadeIn({ node : "fadeMe" , duration : 3000 }).play(); jQuery$("#image").append("<img id='fadeMe' src='/web/samples/presentation/_assets/images/javascript.jpg' style='display:none' />");$("#fadeMe").fadeIn("slow"); Prototype$("image").insert(new Element("img", {"src" : "/web/samples/presentation/_assets/images/javascript.jpg", "id" :"fadeMe", "style" : "display:none"}));$("fadeMe").appear({ duration: 3.0 });
Add Element, Fade UpWIWNDvar image = {
insert : function(){if ($("fadeMe")) {
$("image").innerHTML="";};/*@cc_on
/*@if (@_win32)var style= "filter:alpha(opacity=0)";
@else @*/ var style="opacity:0"; /*@end
@*/$("image").innerHTML="<img src='/web/samples/presentation/_assets/images/javascript.jpg'
style='"+style+"' id='fadeMe' />";image.fadeUp(0);
},fadeUp : function(count) {
var fadeImage = $("fadeMe");count = count + 5;if (count < 100 ) {/*@cc_on
/*@if (@_win32)fadeImage.style.filter ="alpha(opacity="+ count +")";
@else @*/fadeImage.style.opacity= (count/100);
/*@end@*/var callback = function() {
image.fadeUp(count);}setTimeout(callback,50);}
}};
Add Element, Fade UpYUIvar image = {
insert : function(){if (YAHOO.util.Dom.get("fadeMe")) {
YAHOO.util.Dom.get("image").removeChild(YAHOO.util.Dom.get("fadeMe"));}var newImage = document.createElement("img");newImage.src= "/web/samples/presentation/_assets/images/javascript.jpg";newImage.setAttribute("id","fadeMe");newImage.style.opacity=0;YAHOO.util.Dom.get("image").appendChild(newImage);image.fadeUp(0);
},fadeUp : function(count) {
var fadeImage = YAHOO.util.Dom.get("fadeMe")count = count + 5;if (count < 100 ) {/*@cc_on
/*@if (@_win32)fadeImage.style.filter ="alpha(opacity="+ count +")";
@else @*/fadeImage.style.opacity= (count/100);
/*@end@*/var callback = function() {
image.fadeUp(count);}setTimeout(callback,50);}
}
}
Let’s Look at Some Numbers
Pure JavaScript (the numbers)
Load Time in ms (Internet Explorer 7 webPageTest) 0.644Load Time in ms (Internet Explorer 7 webPageTest) CACHED 0.59Average Execution Time (Firefox) in ms 104.678Approximate # of Calls 56YSlow Score 88Lines of Code Written 107minified size (KB) 3.23Works (out of the box) in Internet Explorer 7? No
Pure JavaScript (anecdotal)• The Good: • Light. Fast. Standards based
• The Bad:• More verbose. API awkward?
• The Ugly:• Doesn’t work in 65% of the browsers
worldwide
WIWND (the numbers)Load Time in ms (Internet Explorer 7 webPageTest) 0.759Load Time in ms (Internet Explorer 7 webPageTest) CACHED 0.586Average Execution Time (Firefox) in ms 106.666Approximate # of Calls 84YSlow Score 88Lines of Code Written 94minified size (KB) 8.44Works (out of the box) in Internet Explorer 7? N/A
WIWND(anecdotal)• The Good: • Light. Fast. Handles “big” x-browser
stuff. Fun (for me)• The Bad:• Not clever / less convenient.
• The Ugly:• Lots of heavy lifting. Lots.
Dojo (the numbers)Load Time in ms (Internet Explorer 7 webPageTest) 1.75Load Time in ms (Internet Explorer 7 webPageTest) CACHED 0.748Average Execution Time (Firefox) in ms 307.07Approximate # of Calls 5200YSlow Score 85Lines of Code Written 77minified size (KB) 96
Works (out of the box) in Internet Explorer 7? No (fade up
fails)
Dojo (anecdotal)• The Good: • Easy to pick up. HTML to include
GZipped/CDN version right on download page
• The Bad:• Slower. No JSON+Callback functionality.
Need to learn to think in “Dojo”• The Ugly:• Documentation
jQuery (the numbers)Load Time in ms (Internet Explorer 7 webPageTest) 1.34Load Time in ms (Internet Explorer 7 webPageTest) CACHED 0.717Average Execution Time (Firefox) in ms 190.521Approximate # of Calls 1500YSlow Score 84Lines of Code Written 53minified size (KB) 57.5
Works (out of the box) in Internet Explorer 7?
No, middle block is
unformatted
jQuery (anecdotal)• The Good: • Easy to pick up. Fast, succinct code.
Chaining is fun. Solid documentation.• The Bad:• No JSON+Callback functionality. Need to
learn to think in “jQuery.” CDN link not promoted.
• The Ugly:
Prototype/Scriptaculous (the numbers)
Load Time in ms (Internet Explorer 7 webPageTest) 3.349Load Time in ms (Internet Explorer 7 webPageTest) CACHED 1.423Average Execution Time (Firefox) in ms 394.045Approximate # of Calls 7000YSlow Score 49Lines of Code Written 74minified size (KB) 88.6Works (out of the box) in Internet Explorer 7? yes
Prototype/Scriptaculous (anecdotal)
• The Good: • Feels more like JavaScript. Deep.
• The Bad:• No JSON+Callback functionality.
Promoted code is not minified. Slowest of the libraries.
• The Ugly:• “Blototype.” Reading documentation was
like being punched in the face.
YUI (the numbers)Load Time in ms (Internet Explorer 7 webPageTest) 1.145Load Time in ms (Internet Explorer 7 webPageTest) CACHED 0.621Average Execution Time (Firefox) in ms 116.956Approximate # of Calls 120YSlow Score 88Lines of Code Written 105minified size (KB) 69Works (out of the box) in Internet Explorer 7? No
YUI (anecdotal)• The Good: • Fast. Incredible documentation. CDN +
single file functionality. Deep bench of advanced functionality. JSON+Callback functionality.
• The Bad:• Limited, generic effects. Leaves more
basic work than other libraries. • The Ugly:• Code.is.Awkward.To.Me()
All the Numbersjavascript wiwnd dojo jquery prototype yui
Load Time (Internet Explorer 7 webPageTest) 0.644 0.759 1.75 1.34 3.349 1.145Load Time (Internet Explorer 7 webPageTest) cached 0.59 0.586 0.748 0.717 1.423 0.621Execution time (firefox) 104.678 106.666 307.07 190.521 394.045 116.956approximate # of calls 56 84 5200 1500 7000 120YSlow Score 88 88 85 84 49 88Lines of Code Written 107 94 77 53 74 105minified size (KB) 3.23 8.44 96 57.5 88.6 69Works (out of the box) in Internet Explorer 7? No N/A
No (fade up fails) no yes no
The Results• If forced (for public consumption)• jQuery
• If forced (the app division)• YUI
• If forced (the Palm Pre/webOS edition)• Prototype