So you've built an application using Dojo and it "feels slow", now what?
Dojo's performance tuning centers around four areas:
If you are a widget developer, you might also be interested in Profiling Javascript.
The plan of attack for reducing page loading latency is to configure the web server sending the JavaScript files to cache them agressively and to not request even status information about them. Servers that don't send adequate cache information may find that UIs are very slow even though the content of the scripts are never sent. Instead, browsers may be checking to see if the file has changed since it was last seen. This "has it changed?" check is synchronous and serial and so we want to eliminate it if possible.
There are several things you can do to improve the performance of your application relating to the web server that are outside the scope of Dojo. Some things to look at are server side caching, data compression and even application program structure. See the following article Improving performance of Dojo-based web applications which contains useful information on these topics.
If you find IE is repeatedly downloading the same image, read this article for advice. This also helps get rid of ugly image flickering in IE.
Dojo builds or distributions contain all the files that are part of Dojo and that may seem some what large. Luckily Dojo includes a mechanism which downloads only files that you use. Creating a custom build of Dojo means identifying the files that you use which will improve the download of the page since a separate network request is not made for each module.
See Creating a Custom Distribution for more information on how to customize your Dojo build.
Page load time is proportional to the number of nodes on the page because Dojo searches all the nodes to see if they are widgets. You can avoid this in the following ways:
Add the following line in the
<script> djConfig = { parseWidgets: false, searchIds: [] }; </script> This turns off parsing so if you do include widgets in your page you will have to make the widgets known to Dojo yourself. Use searchIds.push on the global object djConfig. In the :
<div dojoType="Button" id="button1">...</div>
<script>djConfig.searchIds.push("button1");</script>
...
<div dojoType="Button" id="button2">...</div>
<script>djConfig.searchIds.push("button2");</script>
...
You can also make the parser not search underneath a given node by doing this
<div parseWidgets="false">
... no widgets in here, don't waste your time looking! ...
</div>
One little known feature about searchIds usage is that if you add at least one searchIds, then the "body" (and so the whole) of the document will not be parsed at all, even when the djConfig.parseWidget=true. (See hostenv_browser.js 's makeWidget() function) I think this is a buggy behaviour, and the whole document should still be parsed if djConfig.parseWidget=true. A use case when this is simply necessary: you have a section where you turn off the parsing using the new parseWidget="false" flag. But if you happen to have some widgets inside, those must be parsed using searchIds. But because you've added one such, the whole page will not be parsed, but those parts may contain other widgets!
It sounds obvious, but many web pages have a lot of unnecessary markup. For example, instead of
<table ...>
<tr>
<td>Hello World</td>
</tr>
</table>
just do
<div class="foo">Hello World</div>
Time is proportional to the number of widgets on the page. No advice here.
Instead of downloading your whole page at once, defer portions until the user needs them. For example:
<div dojoType="Tooltip" href="tooltip.jsp"></div>
<div dojoType="TabContainer">
<a dojoType="LinkPane" href="tab1.jsp">Tab #1</a>
<a dojoType="LinkPane" href="tab2.jsp">Tab #2</a>
</div>
FIXME: content below this break is legacy and in need of serious rework
>> On Nov 20, 2005, at 3:54 AM, Christian Boulanger wrote:
>
>>> > I am using dojo.io.bind and need a reference to the calling object
>>> > in the handler code. Not being a javascript geek, I am still
>>> > confused about the closures stuff and how much it impacts
>>> > performance. Is the following way an ok way of doing things or is
>>> > there a better way? Would it make sense to add a parameter to
>>> > dojo.io.bind which transfers the callingObject to the handler
>>> > without need to create the closure?
>
>>
>> Closures are fine to use all over the place. The only time it can
>> matter is the specific instances when they cause circular references
>> to certain kinds of objects that don't fully participate in the
>> interpreter's garbage collection scheme (most commonly DOM objects in
>> IE).
and if you use dojo.event.connect() to set up your event handlers, you
don't have to worry about it even then. In short, go nuts with the
closures, just don't manually set properties on DOM nodes that include
functions or objects.
Regards
Alex Russell
Visit this link for more information about closures and memory leaks in IE.