JavaScript Library Showdown Rob Larsen htmlcssjavascript.com htmlcssjavascript.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 (
History And then it was actually cool, but we stopped mentioning dHTML Photo by Martin KliehmPhoto by Martin Kliehm ( )
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
Concept “I’ve got how long to finish this?” Let’s see what’s out there…
How Will They Be Compared? Simple Tasks Performance (Page render & execution) Code Base Documentation/Overall Presentation Anecdotes
What Tasks? Unobtrusive JavaScript 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.
Unobtrusive JavaScript? What is it? Unobtrusive JavaScript is a method used to separate behavior from content and style, into its own discrete component. Helps create usable, maintainable web sites
Unobtrusive JavaScript? Why? Once coded, it should be easy to implement It's accessible The HTML markup is kept lean Easier maintenance
Unobtrusive JavaScript? How does it work? Separate structure, style and behavior – Specifcally No inline event handlers No, REALLY. No inline event handlers. – Seriously. is bad Based on structure, attach events
* “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 by ortizmj12
Let’s Look at Some Code
HTML url("../_assets/styles/screen.css"); Tell me about JavaScript
Add Load Event/ Add Event JavaScript function init() { document.getElementById("make-it-so").addEventListener("click", results, false); } window.addEventListener("DOMContentLoaded", init, false); Dojo dojo.addOnLoad( function() { dojo.connect(dojo.byId("make-it-so"), 'onclick', results) } ); jQuery $(document).ready( function() { $("#make-it-so").click(results); } );
Add Load Event/ Add Event Prototype document.observe("dom:loaded", function() { $("make-it-so").observe("click", results, false); }); YUI function init() { YAHOO.util.Event.addListener(YAHOO.util.Dom.get("make-it-so"), "click", results, this); }; YAHOO.util.Event.onDOMReady(init);
Add Load Event/ Add Event WIWND //Dean Edwards ( function init() { if (arguments.callee.done) return; arguments.callee.done = true; if (_timer) clearInterval(_timer); //demo addEvent(document.getElementById("make-it-so"), "click", results ); //end demo }; if (document.addEventListener) { document.addEventListener("DOMContentLoaded", init, false); }; (function () { try { document.documentElement.doScroll('left'); } catch (e) { setTimeout(arguments.callee, 50); return; } init(); 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 JSON JavaScript/WIWND var twitterJSON = document.createElement("script"); twitterJSON.type="text/javascript"; twitterJSON.src=" earchResults&q=%23javascript&count=10"; document.body.appendChild(twitterJSON); Dojo dojo.xhrGet( { url: '../json.php?url= =10', handleAs: "json", load: function(responseObject, ioArgs) { writeTwitterSearchResults(responseObject) } }); jQuery $.getJSON("../json.php?url= &count=10", writeTwitterSearchResults );
Get JSON Prototype New Ajax.Request('../json.php?url= ipt&count=10', { method:'get', requestHeaders: {Accept: 'application/json'}, onSuccess: function(transport){ var json = transport.responseText.evalJSON(true); writeTwitterSearchResults(json); } ); YUI YAHOO.util.Get.script(" itterSearchResults&q=%23javascript&count=10");
XHR JavaScript getData : 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= true); data.send(null); } Dojo dojo.xhrGet( { url: '../feed.php?url= handleAs: "xml", load: function(responseObject, ioArgs) { reddit(responseObject) } });
XHR jQuery $.get("../feed.php?url= reddit ); Prototype new Ajax.Request("../feed.php?url= { method: 'get', onSuccess: function(transport) { reddit(transport.responseXML) } }); YUI var callback = { success:reddit }; var request = YAHOO.util.Connect.asyncRequest('GET', "../feed.php?url= callback);
Remove Element JavaScript twitterDIV.removeChild(document.getElementById("twitter-list")); WIWND twitterDIV.innerHTML=""; Dojo dojo.destroy("twitter-list"); jQuery $("#twitter-list").remove(); Prototype $("twitter-list").remove(); YUI twitterDIV.removeChild(YAHOO.util.Dom.get("twitter-list"));
Add Element, Fade Up JavaScript var 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 Up Dojo var 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(" "); $("#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 Up WIWND var image = { insert : function(){ if ($("fadeMe")) { $("image").innerHTML=""; }; var var $("image").innerHTML=" "; image.fadeUp(0); }, fadeUp : function(count) { var fadeImage = $("fadeMe"); count = count + 5; if (count < 100 ) { fadeImage.style.filter ="alpha(opacity="+ fadeImage.style.opacity= var callback = function() { image.fadeUp(count); } setTimeout(callback,50); } };
Add Element, Fade Up YUI var 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 ) { fadeImage.style.filter ="alpha(opacity="+ fadeImage.style.opacity= 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) Load Time in ms (Internet Explorer 7 webPageTest) CACHED 0.59 Average Execution Time (Firefox) in ms Approximate # of Calls 56 YSlow Score 88 Lines of Code Written 107 minified size (KB) 3.23 Works (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.759 Load Time in ms (Internet Explorer 7 webPageTest) CACHED0.586 Average Execution Time (Firefox) in ms Approximate # of Calls84 YSlow Score88 Lines of Code Written94 minified size (KB)8.44 Works (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.75 Load Time in ms (Internet Explorer 7 webPageTest) CACHED0.748 Average Execution Time (Firefox) in ms Approximate # of Calls5200 YSlow Score85 Lines of Code Written77 minified 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.34 Load Time in ms (Internet Explorer 7 webPageTest) CACHED0.717 Average Execution Time (Firefox) in ms Approximate # of Calls1500 YSlow Score84 Lines of Code Written53 minified 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.349 Load Time in ms (Internet Explorer 7 webPageTest) CACHED1.423 Average Execution Time (Firefox) in ms Approximate # of Calls7000 YSlow Score49 Lines of Code Written74 minified size (KB)88.6 Works (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.145 Load Time in ms (Internet Explorer 7 webPageTest) CACHED0.621 Average Execution Time (Firefox) in ms Approximate # of Calls120 YSlow Score88 Lines of Code Written105 minified size (KB)69 Works (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 Numbers javascriptwiwnddojojqueryprototypeyui Load Time (Internet Explorer 7 webPageTest) Load Time (Internet Explorer 7 webPageTest) cached Execution time (firefox) approximate # of calls YSlow Score Lines of Code Written minified size (KB) Works (out of the box) in Internet Explorer 7?No N/A No (fade up fails)noyesno
Final Thoughts
Thanks!
Questions?