Monthly Archives: November 2007

JavaScript Performance – Incremental Asynchronous Processing

I have an application where the hierarchical data is displayed as a table and I need to provide the ability to expand and collapse the nodes (I explained how this can be done in my Nested TBODYs post). With large data sets this had a lot of problem and Netscape displays the standard dialog about stop/continue the script. After a bit of research, it turned out that using the setTimeout method, the long running code can be made asynchronous.

So, I thought that’s not a big deal. Just call the function in setTimeout. After doing that, I still had the same problem. Then, it appears that even with setTimeout, the code shouldn’t be running for too long or otherwise I would end up with the same stop/continue dialog.

Then it turns out, the solution is to keep calling the setTimeout multiple times and each time doing only a small part of the computation. Now, how the heck can this be done when you have a big loop? Below are the steps to do that.

Say you had code like


for(var i=0;i<rows.length;i++) {
... // some logic
}

Change this to


var i=0;
function dosomething() {
var count = 0;
for(;i<rows.length;i++) {
... // original logic
count++;
if(count == 10) // change this to an appropriate number
break;
}
if(i<rows.length)
setTimeout(dosomething,0);
}

This is pretty much it!

Now, say you want to do something at the end of such long logic in loop. How can this be done? You can do this by using a callback function. So, the above code would be changed to


var i=0;

function dosomething(callbackf) {
var count = 0;
for(;i<rows.length;i++) {
... // original logic
count++;
if(count == 10) // change this to an appropriate number
break;
}
if(i<rows.length)
setTimeout(dosomething,0);
else if(callbackf) callbackf();
}

That’s it, now at the end of this incremental asynchronous processing, you get a hook to do some additional logic. Infact, you can keep nesting these incremental-asynchronous computations each of which calling at the end of the other.

Couple of things to note:

1. The dosomething should be a function defined within the context of another function and the loop variable. This essentially creates a closure for the loop variable. Defining the function as a top level function will not work.
2. In my specific case, I had defined the dosomething function twice, once in each part of the if-else statement. For some reason, this didn’t work in IE. Giving a different name for each case worked though.
3. In the above code, where the count is incremented, if you have logic that skips doing anything for certain increments of the loop variable, i, then don’t increment the count variable. For example, in my hierarchical data expansion/collapse functionality, there are times where the rows are already hidden and I don’t have to hide them again. This improves the speed a bit more as the number of chunks of incremental processing are optimized.

Advertisements

2 Comments

Filed under DHTML, javascript

Firefox 3

I just downloaded Firefox 3 Beta 1 and installed it (recently I have been a bit unhappy with Firefox due to performance issues, especially visiting/using web site/applications that are DHTML/JavaScript/AJAX intensive). I will use this post to keep updating the features I have been noticing as a end user and a developer.

* The file upload field automatically opens up the File Open dialog as soon as the cursor is placed on the field. The textfield also appears as disabled and tabbing to the field automatically places the cursor to the “Browse” button next to the field. While this is good, it’s unclear how I can clear the file I selected to upload!
* Recently I wrote about Nested TBODYs and the example I had was a bit slow for large data set. Now the nodes are expanding and collapsing much faster.

Leave a comment

Filed under Firefox

Kindle vs iPod

Amazon released a new product called Kindle, a portable wireless ebook reader. There have been many ebook readers in the past, but none have become popular. Amazon says it spent about 3yrs in designing the Kindle product. I briefly looked at it and my first reaction is that the gadget is not sexy. I mean, when you look at an iPod or iPhone, you feel the desire to own it, partly because of it’s looks (don’t deny!). The things I didn’t like are the plastic look and the odd shape with sharp corners.

I think the odd look is perhaps due to ergonomics. If you own a iPod Video or an iPone, you know how cool the round corners with a steel casing (not to mention the etching of an apple with a bite out of it).

Keeping the looks aside, the gadget has some good features. First and foremost, it’s weight of 10.3 ounces (292 grams or less than 1/3 of a kg) should make it easy to carry it like a book. They have something called “electronic-paper display” which supposedly makes the viewing experience close to the real paper. It’s wireless capabilities allows connecting it directly to the Kindle store, so there is no need for the middle-man, I mean the computer, to do all kinds of syncing and juggling. What’s best is, the wireless is based on a technology similar to the cell-phones (Whispernetâ„¢). What that means is, no need to search for a hotspot while traveling and better yet, no wireless access fee to purchase from the Kindle store. They even allow you to surf the wikipedia.org for free!

Overall, for book lovers or gadget lovers, this can be one of the best gift idea for the coming holidays!

Also, I think, with Kindle, Amazon is trying to do with books, what Apple did with iPod/iTunes combination for music.

1 Comment

Filed under Gadgets, Kindle

Nested TBODYs

The quick answer is, this is not possible. But continue to read on a possible workaround.

As per the HTML 4.01 tables specification, a tbody consists of only TRs. So, that essentially means, it’s not possible to have nested TBODYs. Ofcourse, a cell in a row can contain a table that can contain a TBODY, but we are not talking about that type of nesting, are we?

Taking a step back, what’s the need for nested TBODYs? I have a hierarchical data that is displayed as a table and to provide the ability to expand and collapse, a quick temptation is to make the child nodes of each parent node to be put into a tbody and just hide/show that tbody element alone. Now, due to the hierarchical nature, a child node itself will need to be created as a tbody to capture it’s own children. So, this is where the need for a nested tbody arises.

So, after checking the above mentioned specification that it’s not possible to nest tbodys, I achieved the above required expand/collapse functionality using TRs itself. The trick here is to make use of the ID attribute and specify a unique ID for each TR such that the TR elements of the child nodes contain the IDs which contain the ID of the parent element in them as a prefix. For example, if the parent has an id of ‘0’, then the child 1 can contain ‘0/0’, child 2 can contain ‘0/1’ and child of child 1 can contain ‘0/0/0’ and so on. With this approach, when the user is trying to expand/collapse a node, I can loop through all the TRs of the table and identify those that have a prefix same as the id of the node being expanded/collapsed and then hide/show those rows accordingly. I tried this idea and it worked without any problems.

6 Comments

Filed under DHTML, javascript

Domain Spam – Domains That Aren’t

These days I am quite upset about a problem. Every other domain that I think of to register for my business idea, yes real business idea that I am interested in, I see that an appropriate domain is already taken. But when you access the website of that domain, what you see is a stupid page filled with all sorts of keywords related to the domain name. Clicking them will show sponsored ads. Now, obviously when the cost of registering a domain keeps falling down, the idea of being able to make money out of random-once-in-a-few days visitors if they able to click the money is quite compelling.

Say, the cost of a domain to register is $6.00, with a PPC rate of $0.50, more than 12 clicks a year is more than enough to make profit. The profit can range from a few bucks to several depending on how often the site is being visited. But registering many such sites some of which also for the purpose of selling at a higher price for those desperately interested in a specific domain, there is definitely some business idea in this (infact, recently I saw a guy trying to borrow $25K, yes that’s $25K to buy a highly sought after domain name with the idea of making more money in the future from it, seems he can even rent it out for other companies interested in advertising on the site due to it’s popularity in the search).

However, this whole process of registering so many domain names is causing a domain spam and the only way to prevent this is by not clicking on any link when landed on such a domain. The less lucrative this becomes, the less incentive one would have to do this. Similar to maintaining a scam/phishing domain list, if one maintains a list of domains created for the purpose of displaying ads and alert the user in the browser as soon as such a site is visited, then a naive user can easily avoid clicking the links.

Leave a comment

Filed under Domain Registration

Open Source And SAAS

Based on the recent move by an open source company to offer it’s product only as a SAAS, it got me thinking about that move. What does it mean to the people who are interested in contributing to the software?

Open Source has several benefits to the people using the software, some of which are

a) if the company goes bust, the code is accessible to continue further
b) if there is a bug, access to the code makes it easy to fix it before it’s available through the vendor
c) review of the code from multiple developers reduces the security issues
d) and also, new features are likely to get added faster through contributions

Now, if the vendor chooses to make the code available to customers only as a SAAS application, then what incentive does the ecosystem supporting that software have any longer? For example, some one interested in consulting can’t do that any longer as the customers are not installing but using the SAAS offering. System Integrators have limited opportunity, if any, to develop and make money out of integrations.

So, it makes me think that an open source company choosing to provide only the SAAS model is at the risk of losing the developer community. Interestingly, right now both Open Source and SAAS are two interesting buzz words that the VCs are interested in. Lack of stellar revenue opportunity from Open Source model perhaps made some of the companies to mold themselves into SAAS providers (SAAS is perhaps inevitable even for their closed source cousins as well).

Leave a comment

Filed under open source, SAAS

HTML Table Sorting Using JavaScript

One of the most common actions when viewing data in a tabular format is to be able to sort. With DHTML and JavaScript, it’s possible to sort the data on the clientside. This avoid unnecessary roundtrip to the server and improves the usability. There are a few javascript libraries that provide the sorting capability with minimal edits to the html. However, if you want to have a total control over the sorting, for features such as, sorting a column sorts against data that is different than what’s visible (for example, data is displayed as percentages while the sorting is done without the % symbol, data is displayed as yyyy/mm/dd but internally there is a date object corresponding to what is displayed), then more control is required on sorting the data. Below is a snippet of code for doing this.


function DataRow(data) {
this.data = data; // data is itself an array or other object that contains data
this.row = null;
}

var data = new Array();
// here generate/write javascript to store the rows and their data, for example,
// data[data.length] = new DataRow(new Array(1,2,3));

var table = document.getElementById('data'); // assuming there is no THEADER
if(table.firstChild.nodeName == 'TBODY') table = table.firstChild;
var rows = table.getElementsByTagName('TR');
for(var i=1;i<rows.length;i++) // assuming header is also stored as a row
data[i].row = row[i];

function sortTable(event,col) {
var header = table.firstChild; // storing both heading and data in tbody.
while(table.firstChild) table.removeChild(table.lastChild);
table.appendChild(header);
data.sort(function(a,b) { return a.data[col] - b.data[col]; });
// you can have more complex logic based on the data and requirements
for(var i=0;i<data.length;i++)
table.appendChild(data[i]);
}

Next, it’s a matter of pluging in the sortTable(event,col) call in the onclick of the header.

The key idea here is to be able to keep the data and the related UI element (the row), together as an object and do sorting on those objects.

Leave a comment

Filed under DHTML, javascript