I have a web page that shows a bunch of data (trouble tickets) on different tabs.
In the first iteration, I was doing a ton of queries at load time, and building up the content of each tab using Perl Mason. Tabs that had no data on them were not even created on the page. There were three problems with this:
- It took a while to load the page
- Any time you did anything that would change the tickets that are on the page (like resolve or reassign one of them), I’d have to totally reload the page.
- You’d probably have to occasionally reload the page to see if anybody else had done anything that would cause more or fewer tickets to appear on one of your tabs.
In the second iteration, I changed it so each tab would only load itself when you clicked on it by making an AJAX call. This did wonders for the speed of the initial page load, you’d see the latest and greatest information on the tab when you clicked on it, and if you resolved or reassigned one, it would repopulate just that one tab. As an added bonus, I added paging and sorting to each tab. I was happy about the paging and sorting. The biggest problem is that I couldn’t hide the tabs with nothing in them, because I didn’t know there was nothing in them until you clicked on them. I didn’t like that.
In the third iteration, I added an argument to the AJAX call that would allow it to just return the count of tickets in the tab, instead of actually returning a page’s worth of tickets. This is fairly fast. So now when it goes to refresh tab “B”, it makes simultaneous ajax calls to get the count for tabs “A”, “C”, “D”, etc. This means that tabs that have no tickets are disabled, giving you a good visual indication of which tabs you need to look at. Also, any time you interact with the page, in the background it’s checking to see if any of the other tabs need to be enabled or disabled. I’ve checked in Firebug and it’s apparent that it does all these other tab count AJAX calls while the “repopulate the currently selected tab” AJAX call is processing, so it’s nice and fast. I’m pretty happy with this.
Next iteration would probably be to add some searching or filtering.
After that, maybe using a WebSocket or periodic polling to see if anything has changed instead of only refreshing when you interact with it.
I’m working on my first non-trivial web app. I’ve designed it much like I would an iOS/Android app: the HTML and CSS are the static “UI layout” and then there is a bunch of JavaScript that retrieves data via AJAX/WebSockets. I can’t tell yet whether this is The Right Way or The Wrong Way to make web apps these days.
I’m lucky in that I don’t have to support legacy browsers, and the number of users will be in the dozens rather than thousands or millions, so I’m hoping to avoid the compatibility and scaling issues that many web devs have to deal with.
One thing I wish I’d done early was find a decent Javascript templating engine. I’d taking a lot of json requests and making long statements like :
$table.append(
'<tr class="' + trClass + '" id="TicketRow' + ticket.id + '">' +
'<td class="collection-as-table" align="right">' +
'<b><a href="<%RT->Config->Get('WebPath')%>/Ticket/Display.html?id=' +
ticket.id + '" target="_new">' + ticket.id + '</a></b>' +
'</td><td class="collection-as-table"><b>' + ticket.subject + '</b></td>' +
'<td class="collection-as-table"><b>' + ticket.status + '</b></td>' +
</tr>
etc.
I’m using Underscore’s templates (http://underscorejs.org/#template) on the client side. They’re pretty easy to use.
The problem with underscore is that it drags in a bunch of stuff that is probably redundant since I’m already using jQuery. I’m thinking maybe dust or Google closure.
I agree that underscore has a lot of overlap with jQuery, but it has a lot of useful things that jQuery does not provide. I’m also using Backbone, which requires underscore.
Relevant SO question: http://stackoverflow.com/questions/8907373/do-underscore-js-and-jquery-complement-each-other