Opened 7 years ago

Closed 7 years ago

#15780 closed feature (wontfix)

remove unused methods

Reported by: Paul Christopher Owned by: Rawld Gill
Priority: undecided Milestone: 1.9
Component: BuildSystem Version: 1.7.3
Keywords: Cc:
Blocked By: Blocking:

Description

Description

Dead code removal, i.e. removal of code that is never used or called, seems not to work properly for module exports. Say I have a helper module such as dojo.string or dojox.validate that consist of several helper functions like so:

define(function(){
	
	return {
		addStuff1: function(s){
			return s + " + my stuff1";
			
		},
		
		addStuff2: function(s){
			return s + " + my stuff2";
			
		},
		
		addStuff3: function(s){
			return s + "+ my stuff3";
			
		}
		
	};
	
});

This module could be quite big in size since it offers various helpers (such as checking for valid e-mails, credit cards, phone numbers etc). But in most cases, only a few functions are really used by the code/app, which loads/uses the module (e.g. only mail validation). When creating a build, all unused functions are not removed from the build layer although this might offer a huge potential for optimization of layer size and application performance.

Steps to reproduce the issue

See attached testCase. The page-level controller loads the string helper module shown above but only uses string.addStuff2. Make a build using Google's closure compiler. After that, search the layer file "dojo.js" for "my stuff". You will notice: All 3 functions are baked into the layer and not only addStuff2 although:

  • all 3 functions are independent and do not call each other, i.e. addStuff1 and addStuff3 are not used within the string module itself.

Therefore, since only addStuff2 is used by the page-level controller, addStuff1 and addStuff3 are truely dead code which could bloat the layer size dramatically (not in this case since it's a dumb example).

Discussion

I came across this when writting my own string helper module with lots of different convenient functions (such as string.constains, string.startsWith, string.endsWith, string.isNullOrEmpty etc.). I wanted to use this module in my latest project. But then I realized that unused functions are not removed by the built. I would have therefore bloated my layer with a lot of dead code. And since I need to optimize for size, I could not include the module.

Attachments (1)

testCase.zip (93.0 KB) - added by Paul Christopher 7 years ago.

Download all attachments as: .zip

Change History (6)

Changed 7 years ago by Paul Christopher

Attachment: testCase.zip added

comment:1 Changed 7 years ago by bill

I think you're getting confused between how the feature is designed to work vs. how you want it to work. It's actually dead branch removal, and is designed to collapse one of the sections of if/else statements, ternary's, etc., stuff like that.

comment:2 Changed 7 years ago by Paul Christopher

Since December 2011 Closure Compiler offers an experimental AMD support, see http://code.google.com/p/closure-compiler/source/detail?r=1684.

The author says that it has already been tested with Dojo.

An in-depth explanation on how to compile AMD modules with CC is given by the author on this homepage: http://www.nonblocking.io/2011/12/experimental-support-for-common-js-and.html

comment:3 Changed 7 years ago by Paul Christopher

But it seems that closure compiler's new AMD support does not strip unused module functions. Therefore I have placed a ticket on the issue tracker, see http://code.google.com/p/closure-compiler/issues/detail?id=788.

Don't know what is really needed that this new feature works nicely together with Dojo. At the moment they try to transform AMD modules to CommonJS modules and CommonJS modules to a format closure compiler understands (i.e. they remove the function wrapper and place all functions in the same scope). But I doubt that this will work with Dojo since Dojo embeds its own loader in the build/layer and still expects "define" and "require" statements? I would like to give the Google guy's more feedback on that, but can't since for me the build system is a riddle wrapped up in an enigma...

comment:4 Changed 7 years ago by bill

Summary: Dead code removal for AMD modules not working properlyremove unused methods
Type: defectfeature

comment:5 Changed 7 years ago by Rawld Gill

Milestone: tbd1.9
Resolution: wontfix
Status: newclosed

The dojo build program does not cause any code optimizations directly. Instead, it submits resources to external processes that have one or another capability. These processes are called transforms. As of 1.8, we have the ability to optimize resources with Dojo's shrinksafe minimizer and Google's Closure compiler; there is some effort to get Uglify to work as well, but that is not guaranteed at this point. Therefore, the build program is exactly as powerful/powerless as these external processes.

It may be possible to get the kind of optimizations you are looking for by aggregating all modules in a single resource and submitting that resource to the Closure compiler (I'm not sure of Closure's current capabilities). If this were the case, then you could write a transform to build the aggregate file and use the build program to optimize a program as such.

In any event, these kind of transforms (speaking now of compiler transforms, not build transforms) require control-flow analysis, data-flow analysis, and dependency analysis which are highly-advanced and extremely-complex compiler operations. They will not be included as part of dojo 1.x...and likely not even 2.0.

Note: See TracTickets for help on using tickets.