Love it or hate it, JavaScript is playing an increasingly important role in the next generation of web and mobile apps. As code continues to move from the server to the client, JavaScript is being used to do more than simple HTML manipulation. Be prepared for this transition and make sure the JavaScript you write is optimized and ready to perform on desktops and devices! In this session, you will learn ten practical tips that you can use today to write faster, more maintainable, memory friendly JavaScript.
12. “JS had to 'look like Java'
only less so, be Java‟s
dumb kid brother or boy-
hostage sidekick. Plus, I
had to be done in ten
days or something worse
than JS would have
happened”
14. Aug 1996
Microsoft
Mar 1999 Firefox
XHR Safari
Chrome
Mobile
//
Sept 1995
Netscape
Aug 2001
IE6
June 1997
ECMAScript
Feb 2005
Ajax
15. JavaScript won by
default.
If you're the last man left on
earth, it doesn't matter how ugly
you are when the women come to
re-populate the planet.
Scott Koon
25. TIP #1
jQuery is a friend…
…that will stab you in the back.
Prove It
26. CACHE OBJECTS
BAD
$("#myDiv").css("color","red");
$("#myDiv").css("opacity",1);
BETTER
$("#myDiv").css("color","red")
.css("opacity",1);
BEST*
var $myDiv = $("#myDiv");
$myDiv.css("color","red");
$myDiv.css("opacity",1); Prove It
27. NATIVE LOOPS
BAD
$.each(arr, function (i) {i / 2;});
BETTER
arr.forEach(function (i) {i / 2;});
BEST*
var i = 0, len = arr.length;
for (i = 0; i < len; i += 1) {
i / 2;
} Prove It
32. BEST(ISH)
var app = (function(){
var _name = "Todd";
return{
sayHello: function(){
alert(_name);
}
}
}());
app.sayHello();
16:39
33. SUPER PATTERN
Self-Executing Anonymous Functions + Global Imports
+ Prototype
(function(window,$,c){
var _private = "Todd";
function privateClass(){}
function myWidget(){}
myWidget.prototype.doSomething =
function(){}
window.myWidget = myWidget;
}(window,jQuery,console);
Prove It
40. ALSO BETTER
function doSomething(){
var dfd = new $.Deferred();
//Do something async, then...
//dfd.resolve();
return dfd.promise();
}
function doSomethingElse(){
$.when(doSomething()).then(//The next
thing);
}
16:39
42. My Awesome Page
Lorem ipsumy samplish
jibber jabbish text only
meant to serve as a
placeholder, and much like
Pi, should never repeat or
be read much beyond the
first few characters.
Copyright Fo'eva
43. BAD
function doSomething{
...
var $list = $("body").append("<ul>");
for(var i = 0; i < 10; i++){
$list.append("<li>"+ i +"</li>")
}
}
16:39
44. BETTER
function doSomething{
...
var $domChunk = $("<ul>");
for(var i = 0; i < 10; i += 1){
$domChunk.append("<li>"+ i +"</li>");
}
$("body").append($domChunk);
}
16:39
45. DOM SPEED WITH
STRINGS & INNERHTML
function doSomething{
...
var domString = "<ul>";
for(var i = 0; i < 10; i += 1){
domString += "<li>"+ i +"</li>";
}
domString += "</ul>"
$("body")[0].innerHTML = domString;
}
Prove It
46. BEST
<script type="text/x-kendo-template" id="tmp">
<ul>
#for(var i = 0; i < data.length; i += 1){#
<li>#= data[i] #</li>
#}#
</ul>
</script>
function doSomething(){
var myData = [1,..,10];
var template = kendo.template($("#tmp").html());
$("body").append(template(myData));
}
16:39
Prove It
53. Fix IE
<script type="text/javascript">
<!--Console global variable fix for IE-->
if (!this.console) {
window.console = {
log: function() {}
};
}
</script>
16:39
54. Resources for Study
• Books
– JavaScript: The Good Parts (Crockford)
– JavaScript: The Definitive Guide (Flanagan)
– JavaScript Patterns (Stefanov)
– High Performance JavaScript (Zakas)
16:39
5 Tips for Better JavaScript Love it or hate it, JavaScript is playing an increasingly important role in the next generation of web and mobile apps. As code continues to move from the server to the client, JavaScript is being used to do more than simple HTML manipulation. Be prepared for this transition and make sure the JavaScript you write is optimized and ready to perform on desktops and devices! In this session, you will learn ten practical tips that you can use today to write faster, more maintainable, memory friendly JavaScript. You will also learn techniques for testing, debugging, and profiling JavaScript apps.
anglin@telerik.comKendo UI: Everything you need to build sites & mobile apps with HTML and JavaScript (http://www.kendoui.com)
AGENDA:- Why JavaScript? Why?!- Most Common JS Problems- TIPS- Future of JavaScript
JavaScript uses syntax influenced by that of C. JavaScript copies many names and naming conventions from Java, but the two languages are otherwise unrelated and have very different semantics. The key design principles within JavaScript are taken from the Self and Scheme programming languages.http://en.wikipedia.org/wiki/JavaScript
NOTES:HistoryEvolutionThe IE Connection (IE6 memory)Modern JS EnginesBOTTOM LINE: Only Cross Platform Language Solution
Netscape also wanted a lightweight interpreted language that would complement Java by appealing to nonprofessional programmers, like Microsoft's VB
Credit: Brendan Eich via WikipediaSource: http://www.jwz.org/blog/2010/10/every-day-i-learn-something-new-and-stupid/#comment-1021Brendan further said that JavaScript saved the world from VBScripthttp://www.jwz.org/blog/2010/10/every-day-i-learn-something-new-and-stupid/#comment-1049
Java is to JavaScriptASCar is to CarpetNetscape was going to release JavaScript as “LiveScript.” Last minute change produced JavaScript.
HOW DID JAVASCRIPT BECOME UBIQUITOUS?Netscape shipped first in Netscape 2Microsoft support added in IE3 (“JScript”)Other environments adopted JavaScript-like script languages: ActionScript (Flash), PDFs, Qt
Contributing factors:New JS engines (V8)CPU speed (more local processing power)Better debugging toolsBetter understanding of language (closures, patterns, functional programming, JSLint)
Chrome is 10x faster than IE7 (IE6 too old to test)Used crude relative test: http://jsbenchmark.celtickane.com
http://geekmontage.com/firefox-vs-chrome-vs-ie/
http://www.codinghorror.com/blog/2007/07/the-principle-of-least-power.htmlThe Principle of Least Power
Jordan Ilchev, Icenium Team LeadIvan Ivanov, Sr DeveloperBurke Holland, Evangelist, Kendo UIJohn Bristowe, Evangelist, Kendo UITsvetomirTsonev, Sr Developer, Kendo UI
jQuery built for convenience, not for performance.PERF PROOF: http://jsperf.com/id-vs-class-vs-tag-selectors/46Note: This in general is applicable to native JavaScript methods too, like document.getElementById() not limited to jQuery only objects DOM lookups are slow especially if DOM is huge.Instead of this:$('#test').bind('click', function() { /**/ });$('#test').css('border', '1px solid #999');Better use jQuery Method chaining:$('#test').bind('click', function() {/**/ }) .css('border', '1px solid #999');Or cache jQuery object:var $test = $('#test');$test.bind('click', function() {/**/ });$test.css('border', '1px solid #999');(Performance comparison here: http://jsperf.com/jquery-chaining/12) (~+30% here, but it stacks on each additional method call)
PRO TIP CONVENTION: Name jQuery variables with $ (ie $myObject)PERF TEST: http://jsperf.com/caching-jquery-objects-perfhttp://jsbin.com/udizam/2
PERF TEST: http://jsperf.com/for-vs-foreach-vs-each/3- Caching the array length improves perf by about 15% (http://jsperf.com/for-vs-foreach-vs-each/24)- Technically a reverse (count down) for loop is faster (15%) than count-up loop, but much harder to read/use
Global variables pollute the JS app and are slower to use in code. Harder to be a good JS "neighbor" with global variables (collide with other JS code).Better to use local variables, cached variable, or closures
Pattern sometimes referred to as: MODULE EXPORThttp://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-DepthBE CAREFUL WITH CLOSURES: Most common source of memory leaks in modern appshttps://developers.google.com/speed/articles/optimizing-javascriptCircular Reference Memory Leaks: http://blogs.msdn.com/b/ericlippert/archive/2003/09/17/53028.aspx
PERF TEST: http://jsperf.com/prototype-vs-closures/20Suppose you develop a widget. The widget has a number of axillary classes. If you just define them globally they will pollute the global window class, meaning they will be available from everywhere. Instead consider the following definition: (function (window) { function classA () {} function classB () {} function myWidget () {} myWidget.prototype.method1 = function () { } window.myWidget = myWidget; }) (window, undefined); This is the pattern which jQuery follows. Now the only available global definition will be of myWidget. classA and classB remain hidden in the anonymous function. If you look closely in the definition, you will see the that window and undefined are passed to the anonymous function. Passing anonymous guaranties that undefined will be available in the scope of this function and will prevent you from someone who accidentally did something like: undefined = true; before your function. Also, if you use some minifier, it will replace all occurrences of window with some shorter name. Of course you can pass as much params as you wish, thus assuring that these objects exist in the scope of your anonymous function.
- Binding to delegates is less brittle, easier to avoid memory leaks- Pub/Sub is super flexible, less coupling
The scope of an inline event bind is GLOBAL!Inline event handlers can also cause memory leaks in IE: https://developers.google.com/speed/articles/optimizing-javascript
Old jQuery syntax: .delegate
Every time you need to dispose a DOM element, make sure you unbind all of its events, unless you want to come up with a memory leak.Whenever you bind an event handler to an event, you tell the processor to allocate memory for it. The more event handlers you have running at the same time, the more memory you are using. This is why it's important to unbind or detach your event handlers soon as you no longer need them.http://www.learnjquery.org/newsletter/Tutorial-3-jquery-events.html
Event listening PUB/SUB
Reducing the time spent changing the DOM improvesperf. Using templates improves readability/maintainability.Instead of this:var $list = $('#mylist').append('<ul>');for (var i = 0, l = itemlist.length; i < l; i++) { $list.append('<li>' + itemlist[i] + '</li>');}better this:var $list = $('<ul>');for (var i = 0, l = itemlist.length; i < l; i++) { $list.append('<li>' + itemlist[i] + '</li>');}$('#mylist').append($list);(Performance comparison here: http://jsperf.com/jquery-dom-manipulation/3) (up to x5 in this case)
PERF TEST: http://jsperf.com/jquery-dom-manipulation/4When you want to dynamically build html, prefer string concatenation like: var html = ’<p>some paragraph</p>’;html += ‘<p>another paragraph</p>’;$(“#placeHolder”).html(html); over DOM object creation and appending/prepending like: var p1 = document.createElement('p'); p1.innerHTML = "some paragraph"; document.body.appendChild(p1); var p2 = document.createElement('p’); p2.innerHTML = "another paragraph"; document.body.appendChild(p2); assigning directly to the innerHTML proves to be the fastest method for html creation.
Common Examples:RequireJS, CommonJSApplications of any size are painful to manage without a module pattern.
We want to reduce JavaScript files for performance (fewer network requests), BUT…One large JS file is hard to maintain. We'd really prefer more modular files.
JSLint – by Douglas CrockfordCode quality tool for JavaScripthttp://www.jslint.com/
More complete fix by Paul Irish: http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/