I did an experiment to slim down the dojo base. I summarised the results, findings, and proposals into an attached PDF file.
Any comments or suggestions will be greatly appreciated.
http://dojotoolkit.org/files/DojoLite-20071109.pdf
| Attachment | Size |
|---|---|
| DojoLite-20071109.pdf | 126.61 KB |

very interesting read.
very interesting read. not sure i agree with even considering taking dojo.connect and event out of base, nor NodeList for that matter, but some of the size decreases you are showing are astounding. I'm curious how badly taking stuff out of bootstrap breaks legacy things, and how horrible a transition it would be to track down individual dependancies.
Very nice and detailed
1.0 is great, but still killing startup time,
ultralight version you composed sounds great.
I agree on doing something with the css files too.
I'm still trying out 1.0, since I'm stuck with 0.3 on the largest project :(
It seems to me that you do
It seems to me that you do not need the widget system for the simple widget you are trying to create. If you do not use the dijit system, and a dojo.js layer build that defines customBase, then I think you can achieve what you want today with a small download size.
Otherwise, I'm not sure this specific dojo lite is worth putting in the toolkit. For instance, dojo.query() is referenced in _Widget.js for getDecendants(). It would be interesting to see if any of the dijits would work with this custom dojo lite. I'm thinking we will be hard pressed to find some. I believe most if not all will pull in most of the code you tried to remove. I do not think it is a good idea to force the user to resolve the extra dependencies for the dijit widgets either.
And the target widget is so simple that you do not need the dijit system to create it: just have a dojo.addOnLoad() that grabs the elements you need and convert that markup to the things you want. Although, in that case, I've found dojo.connect() to be important for any non-trivial "widget" that is created in this way.
I think some of the recommendations are good though:
- Have a build option to exclude GoogleGears code (maybe via the //>> directives)
- Have a build option to exclude dojo.i18n from the xd dojo.js (which would also remove the i18n calls in loader_xd.js)
- The //>> directives should be run before dojo.require dependency mapping.
- Addressing the sizes of the theme CSS files would be nice.
BTW, you can run shrinksafe on the non-layer js files by specifying optimize=shrinksafe on the build command line. Maybe we should consider that making the default option, but it is possible to get some minification in those files.
Let me clarify a little
Thanks for the comments. Let me clarify a little.
To run the simple hello widget is not my purpose.
What I think would be useful is fully configurable dojo base, especially that allows us to minimize "initial" download size. (Other code would be downloaded after the startup only when necessary.) What I imagine is Apache module configuration or unix kernel reconfiguration or something like that.
To remove essential modules such as connect or event is not my purpose, either. The experiment I did was just a means to figure out what sort of issues we may have when we create a minimum custom base that include only necessary code for a various type of target applications.
For this purpose, I took the extreme scenario. I know this extreme ultra light base is almost useless. But I still think it should be up to the users to decide what configuration to use.
I agree with you in that we should not force the user to resolve the extra dependencies. I don't intend to change the current default configuration, which I believe is appropriate for most users. The user who has to resolve the extra dependencies is only the one who wants to do so to improve performance.
For optimize=shrinksafe option, I thought it was the default option. I didn't think specifying optimize=shrinksafe made any difference. Anyway, it's good news to me. Thank you!
dojo.require("dijit.form.Button")
Just to add to Kamiyama-san's reply, let me address some of James' comments:
That last sentence is the golden question. We have to do more research to see. But also note that this work may be more for custom widgets than for the dijit widgets. (With custom widgets maybe you want to make size related tradeoffs, like getting rid of animations.)
Well, but that usage can be converted to just a few lines of native javascript code. There's a tradeoff here in that dojo.query() has a huge up-front cost (it's 30K of code uncompressed), but then every time you use it you save a few lines of code, and also it's faster on the minority browsers (but not on IE, which is the most important).
I think the idea is just to include dojolite.js, and then do a dojo.require("dijit.form.Button") (or whatever your widget). dijit.form.Button pulls in whatever it needs to, so the user doesn't have to chase down secret dependencies.
I filed the following trac
I filed the following trac tickets, targeted for 1.1:
#5180: Build option to exclude Google Gears detection
#5181: Build option to exclude dojo.i18n from dojo.xd.js
#5182: The build system //>> directives should be run before dojo.require dependency mapping.
On the CSS files, it would be nice (and it has been mentioned before), if they were commented to indicate what widgets used what parts of the file, so it could be easier to manually trim out the stuff you will not be using. It looks like some of the info is in there, but just needs to be fleshed out some more.
wrt to css
well its getting philosophical about the size of css:
we have tickets leaning towards the [slightly] smaller soria-approach by grouping a lot of classes with a single foundation rule (which would break most chances of easily stripping individual widget styles), and tickets leaing towards a requireCss() approach or a templateCssPath (without magic in the sense we shouldn't start doing ${var} substitutions or anything else).
or, we could do some magic without telling anyone like we do with _base, eg:
dijit/themes/tundra/
./TitlePane.css
./form/InlineEditBox.css
./tundra.css
tundra.css:
@import "TitlePane.css";
@import "form/InlineEditBox.css"
...
and have the build roll a tundra.css from the .css files that match [insert awesome magical convention for naming .css files here] and it's done. a single images/ dir would only load images that are needed anyway.
or just some nice way to utilize the build system to roll all the css into a single cache-able, comment stripped css file.
css is such murky water though.
I like the idea of doing
I like the idea of doing @imports for individual widgets and having the build system optimize it. That seems to match how we treat the JS code too. The build system could have capabilities like it does for a "customBase" dojo.js: if you know you what widgets you use, you could specify specifically what imports you want the build system to pull together.
I like it too, but
I like the idea of having the build system optimize CSS, too. That would help improve the performance of many types of applications. But in some cases, templateCssPath is still useful. Think about applications like iGoogle, where the user can put any widgets after the application starts up. Obviously we want to dynamically load only the CSS for the used widgets.
Very good investigation.
Very good investigation. Some stuff is debatable, but in general it is nice to see what can be done in some "what if" scenarios.