

Javascript and CSS best practices for better performance - subbu
http://www.webuiarchitect.com/30-best-practices-to-boost-your-web-applicati

======
kls
_Always fall back to core JavaScript whenever possible. Limit framework
usage._

Why, frameworks exist for a reason and keeps us from reinventing the wheel.
Many times a contributor to a framework has labored to make his routine as
efficient as possible on the broadest array of platforms. Many times we can
forgo a lot of optimization work by using the framework rather than rolling
our own.

~~~
mrduncan
In other words: Do you really think that you can write this piece of
javascript better than John Resig? (substitute authors as necessary)

In some cases, yes, but I'd argue that in most cases probably not.

~~~
kls
Thanks, you made my point better than I did.

------
FlemishBeeCycle
I hate articles that just make a bunch of assertions without any explanation
as to _why_ or performance tests.

If I'm earning a savings of < 1ms by making one choice over the other, it is
probably more time efficient for me to simply not worry about it.

> 8 But if you have multiple string concatenation, prefer pushing to an Array
> and then calling the join() method on it. This is particularly helpful while
> building HTML snippets.

Depends on too many factors (browser, number of segments, segment length etc)
to a be rule. Most of the time, the performance between this and += is going
to be more or less the same.

> 26 With AJAX, GET works faster than POST. So prefer GET unless request
> length is more than 2K; yes, you guessed it right - IE.

Use GET or POST when you're supposed to not based on how much information you
think you'll be sending.

> 27\. Go easy on scripted animations.

What's easy? What's hard?

> 30\. Always fall back to core JavaScript whenever possible. Limit framework
> usage.

It would be more prudent to _know_ your framework, and know when to not use
it. IE (even in 9!) still doesn't implement indexOf - I can roll my own
solution or use jQuery's inArray.

Here's a better article <http://www.slideshare.net/nzakas/speed-up-your-
javascript>

~~~
webuiarchitect
Nickolas Zakas' Slideshare presentation mainly covers the four areas of
performance and goes deep into it, while my aim was to cover as many aspects
as possible (not restricting it only to JavaScript) and add brief description
wherever I could. Also, when we talk about performance, we usually talk about
milliseconds - so if doing something shows even slightest improvement on at
least one of the browser (e.g. accessing object properties by dot notation
works faster on Safari and doesn't make difference on other browsers), it
helps in keeping a watch on that practice. Even JSLint does the same.

------
juliusdavies
#29 No Tables. How does that help performance? Sure on very large pages that
might help, since the table usually won't render until the </table> has been
sent, but maybe the better tip would be "avoid very large pages" (i.e. 100KB
or more of HTML). DIV based layout also degrade if text in a single cell is
very large, whereas Table based layout is robust against that. Also, I don't
understand why <TABLE> is bad, but this is okay!?!?!

    
    
      <div class='table'>
      <div class='tr'>
        <div class='td'>1</div><div class='td'>2</div><div class='td'>3</div>
      </div>
      <div class='tr'>
        <div class='td'>a</div><div class='td'>b</div><div class='td'>c</div>
      </div>
      </div>
    

Which is what DIV/FLOAT layout usually ends up becoming. If your DIV/FLOAT
layout doesn't map to a structure like that, you're probably doing something
wrong!

Finally, has IE fixed the "we double the padding on floats" issue? Because
float-driven layout with that bug is pretty hard, since IE will double your
paddings while the other browsers don't.

I do know that proudly espousing TABLE in a job interview can cost you the
job. But aside from that TABLE is very effective for most layouts. I do avoid
TABLE inside TABLE of course, that's a code smell, but top level TABLE is the
right tool most of the time. Do anti-TABLE people also avoid Excel?

~~~
webuiarchitect
Updated the blog with some explanation on why TABLEs for layout is not a good
idea. Please recheck.

------
ck2
The problem with this list is some are micro-optimizations while others are
rather important and dramatic, but they are all listed together in no
particular order or weight.

~~~
webuiarchitect
Yes, it is a random list.

------
lhorie
This author doesn't inspire much confidence when he says "A fellow reader just
forwarded this link to me" when referring to Google Closure. Did he even try
it out?

Also, some things are pretty pointless (e.g. "#6 - no globals" doesn't do
anything to improve performance), and other are poorly explained (e.g. "#13 -
store local refs to out-of-scope vars" - what does that even mean?)

He even has syntax errors (e.g. "#7 - var fullName +=", really?) and other
oddities ("#28 - element.bind" What in the world is that?)

The good points are largely regurgitation of stuff that is much better covered
by Steve Souders, the Opera blog and other resources.

------
mayoff
Some of the advice is just plain wrong depending on your target platform. For
example, on my iPad, iPhone 3G (not 3GS), and Safari 5.0 (6533.16)/Mac, using
createElement/appendChild is consistently faster than using innerHTML. In
Chrome 5.0.375.70/Mac, they are the same speed. In Firefox 3.6.3/Mac, naive
createElement is slower, but using a DocumentFragment makes it as fast as
innerHTML.

My test case: <http://dqd.com/~mayoff/timeDom.html>

------
webuiarchitect
Thanks for all the valuable feedback. I have updated the post by adding little
explanation to most of the points there to justify each concern. And have
revised a couple of points. Please feel free to comment further. Please
revisit [http://www.webuiarchitect.com/30-best-practices-to-boost-
you...](http://www.webuiarchitect.com/30-best-practices-to-boost-your-web-
applicati) to see the changes.

------
jaysoo
> #13 In any code block, store local references to out-of-scope variables.

That doesn't even make sense. The for-loop block doesn't create a new scope,
so it's perfectly valid to refer to the variable `a`. Plus, even if you create
a new scope, you can still refer to `a` due to closure.

~~~
webuiarchitect
We are talking about performance optimization here; which means 'what will
work faster' over conventional approaches. Every time the scripting engine
doesn't find a variable in the local scope, it starts searching for it upwards
until it reaches global namespace. And this, my friend, costs CPU cycles. Now
consider this out-of-scope variable being used in a loop. Closure is a power
JavaScript has given us to use it wisely; and not to misuse.

~~~
jaysoo
In the case of closure, yes you will take a small performance hit. But the
example given is still invalid because the only scope present is the function-
scope (for-loop doesn't create new scope).

For example, if you ran the code below in FireBug you'll get the same results
(minor variance aside).

function foo() { var a = 0; for (var i=0, j=a; i<10000000; i++) { var x = j+i;
} }

function bar() { var a = 0; for (var i=0; i<10000000; i++) { var x = a+i; } }

(function() { var start = new Date().getTime(), end; foo(); end = new
Date().getTime(); console.log(end-start); })();

(function() { var start = new Date().getTime(), end; bar(); end = new
Date().getTime(); console.log(end-start); })();

~~~
webuiarchitect
for-loop does create a scope. In fact, every statement block is a scope in
itself.

In your examples, just change the value of variable 'a' to 100 or 1000 and you
will see the difference.

~~~
jaysoo
Blocks in JavaScript do not create scopes. This is different from many other
languages (like Java or C).

In fact, Crockford has mentioned this as well:
<http://javascript.crockford.com/code.html>

"JavaScript does not have block scope, so defining variables in blocks can
confuse programmers who are experienced with other C family languages."

Which is why this code works:

(function() {

    
    
        for (var i=0; i<100; i++);
    
        alert(i);
    

})();

Notice the variable `i` is accessible from outside the for-loop.

~~~
webuiarchitect
That's correct. Thanks a lot. Updated the blog with the correct example (using
function). I was testing on Chrome and even your examples showed better
results with value of variable 'a' to 1000, although slightly. Firefox shows
no difference.

Another thing, JavaScript 1.7 has introduced block level scopes.. you can
achieve that by using the 'let' keyword instead of 'var' to declare a
variable. Although most browsers don't support it yet.

~~~
jaysoo
No problem. It's one of those things developers don't realize when coming from
C-style languages. :)

------
subbu
I think he is referring to asset hosts in #20. Rails does it pretty easily.
ActionController::Base.asset_host = "assets.example.com"

~~~
webuiarchitect
You are right, Subbu. Rails is nothing but common sense; it leaves developers
only to do development and nothing else.

------
interesse
Poor freshmen taking all of this for real. Ever heard of premature
optimization?

------
geuis
#1 is completely wrong. Use of document fragments is much faster than
innerHTML. This way your dom operations occur in memory and the results are
pushed to the dom in one operation. Most of the rest of the tips are valid.

~~~
webuiarchitect
No Geuis. Setting innerHTML works faster than DOM methods. Please test.

------
hackermom
To state the obvious: the JS performance advices this person gives won't
necessarily apply the same to ALL JS engines. I wonder which specific browser
and version he/she bases the advice on.

(Why the heck do the kindergarten people of HN downvote this? It's a perfectly
sensible question.)

~~~
nixy
You are correct. I work with JS engine implementations most people have never
heard of. Performance is different between engine implementations, and so is
availability of different ways of solving a task. Using the common browsers'
best practice for performance doesn't always work for me.

My favorite JS engine is the one implemented in the Evo browser. Among other
things, it lacks support for arrays and for loops which makes development a
tad interesting. And then we have the iPanel browser built for the Sunniwell
set-top-box, in which you have no try/catch. Also, if you use more than five
chained if/else, the browser will crash. However, this could be viewed as
enforcing general programming best practices :)

~~~
cema
Quote:

    
    
      it lacks support for arrays and for loops
    

Wow. They still call it Javascript?

Could you please point at the docs, to see what kind of language they offer?
Thanks!

