[dojo-contributors] Thoughts on dead-code removal and the DojoToolkit

Stephen Chung Stephen.Chung at intexact.com
Wed Mar 16 06:19:40 EDT 2011

A few more words on large functions...

Large functions that take on many different configurations (and use
conditional logic to branch them off for different processing) are more
difficult to optimize than a number of smaller functions, each handling one
configuration.  The optimizer has to do detailed code flow analysis in order
to determine whether a parameter never takes on certain values so it can
remove certain parts of the code of a large function -- a highly non-trivial
task in a flexible language like JavaScript.  On the other hand, when split
into a number of smaller functions, some of them are simply not called at
all, and an optimizer will have no trouble eliminating it.

However, having one large function with a lot of flexibility makes the API
smaller and easier to use than a number of similarly-named small functions.

Therefore, to facilitate unused code removal and optimization, we should
investigate a construct (perhaps through comments) that can allow a build
transform filter to split a large function into different smaller parts, and
convert calls to the relevant functions.  The split can be based on
different values of a particular argument, or a particular number of
arguments passed, or a particular type of argument.  For example:

    function doSomething(x) {
        /*SplitCase 1*/ if (x == 1) { ... }
        /*SplitCase 2*/ if (x == 2) { ... }
        /*SplitCase 3*/ if (x == 3) { ... }

can be transformed into:

    function doSomething(x) {
        if (x == 1) doSplitCase1(x);
        if (x == 2) doSplitCase2(x);
        if (x == 3) doSplitCase3(x);
    function doSplitCase1(x) { ... }
    function doSplitCase2(x) { ... }
    function doSplitCase3(x) { ... }

Such a construct may not be difficult to design, but it needs to be 
throughout the code base to be really useful.  As far as I know, no Library
currently does that and can be optimized like this (not even Google's 
Library), and Dojo can lead the way.

- Stephen

-----Original Message----- 
From: Eugene Lazutkin
Sent: Wednesday, 16 March, 2011 1:10 PM
To: dojo dev.
Subject: Re: [dojo-contributors] Thoughts on dead-code removal and the

Hash: SHA1

Sounds like we need to go to "one dojo.declare'd object per file", and
even probably "one processing unit (e.g., a significant function) per
file" splitting. Is it a valid assumption?


Eugene Lazutkin

On 03/15/2011 11:40 PM, Stephen Chung wrote:
> I’ve recently done more experiments on dead-code removal, since I have
> succeeded in virtualizing the “dojo” namespace.  My application also now
> pulls in dojox.charting (which pulls in dojox.lang, dojox.color and
> dojox.gfx) and I am now fine-tuning my techniques in dealing with Closure.
> My observation is that dead-code removal is not significant for Dojo.
> There are a few reasons:
> - Dojo is written in a very compact way, with many cross-callings among
> functions to save space.
> - Dijit is very modular, and code within a module are usually all needed.
> - Classes declared via dojo.declare cannot be removed (as they are
> probably needed declaratively).  So, although some modules define many
> optional classes (e.g. the plot styles in dojox.charting), they all
> stayed and cannot be removed even though I used only one class out of
> many.
> - Code removed are usually small functions.  Large blocks of code are
> seldom unused (although typically only small sections of these large
> functions are touched).  Currently it looks like 10-20% of code can
> typically be removed, but no more.
> - Feature detection code must be replaced by constants in order to
> remove unneeded code branches when building for a specific platform.
> For example: if (“localStorage” in window) ... is not
> dead-code-removable, but: if (has(“localStorage”)) can be removed if
> this has() call is re-mapped to a constant false for a special build.
> Therefore, in order to facilitate dead code removal (by any means, not
> just Closure), the following has to be considered:
> 1) Heavy modularization – the smaller the modules the better; this can
> eliminate code at the merge stage of the build
> 2) Favor a lot of smaller functions vs. large functions that do a lot of
> things – optimizers can in-line then and remove unused functions – but
> this conflicts with the drive for higher performance when the js is not
> processed by an optimizer.
> 3) Find a way to specify (for the build process) which dojo.declare’d
> classes will be needed by the parser and which will not.
> 4) Replace detection code with something like has.js (which I see
> discussed actively) that enables an optimizer to remove entire branches
> of code based on hard-coded feature sets specified during a build for a
> particular platform.
> - Stephen
> _______________________________________________
> dojo-contributors mailing list
> dojo-contributors at mail.dojotoolkit.org
> http://mail.dojotoolkit.org/mailman/listinfo/dojo-contributors
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

dojo-contributors mailing list
dojo-contributors at mail.dojotoolkit.org

No virus found in this incoming message.
Checked by AVG - www.avg.com
Version: 9.0.894 / Virus Database: 271.1.1/3509 - Release Date: 03/16/11

More information about the dojo-contributors mailing list