Saturday, September 21, 2013

Why is the tree slow?

An explanation of what goes on with the tree component in apex and why it grows increasingly slow as more data is presented.

I've speculated and written down some about this here and there, but haven't ever gotten into much detail of it. Partially because I didn't have the time and partially because I was confused about it. When people ask about the tree being slow, it always has to do with the amount of data in it. Let's say 6000 records. That is a lot of data though, and so beside the technical why-is-it-slow you have to consider that that is just a lot of data. Nevertheless, it's understandable to say that control over that can be a bit out of your hands. After all, you simply want to display hierarchical data and then preferably correct - so no arbitrary leaving out of records.

What actually happens

When you define a tree component you provide the query to it that will supply the data. The tree component is based on the jQuery plugin jsTree. It can work with several types of datastores, and the apex team has decided to work with a json container. This container is built up according to the query and settings in the tree component, and it will create one giant json object. This is then emitted in script tags in the tree region, and assigned to a global variable. The structure is not flat either, but objects nested in objects to represent the tree structure. Thus, a root node will have a children object, and those children will have children objects again etc.
Already you could imagine that having one such huge object in javascript would be taxing on the memory of the browser.

When the page has loaded however, you will not see any json objects. Rather, you will have a functional tree. JSON data is not just presented, that is what HTML is used for. Evident when looking at the code with dev tools: you will find an unordered list (UL) structure. This code is not generated (emitted) by apex however, it is generated at load (runtime) by the jstree plugin. Since the tree has to use the json-object with all nodes, it will transform that object into a presentable structure, and thus it will perform a lot of DOM manipulation: creating elements and attaching them to the document. This is probably the most taxing part, and why some browsers deal better than others with it.
Of course, what makes it worse is how undynamical this setup inherently is. The node selection will cause a page redirect, meaning that if the tree is to be shown on that other page it has to be rebuilt all again - even if all you want to do is refresh a report to the right of it. It is not out of the box refreshable of very interact-able with dynamic actions, but requires some understanding of html/javascript to get things working.

Apex so far has used version 0.9.9a2 of jsTree for its tree component, and this version has actually been outdated for quite some time. It does have documentation but nowadays it can be hard to find examples of implementations, which hasn't helped in deciphering everything. In hindsight, when I may have defended the tree component and said there is documentation, it is a bit obscured and put to the side and it could've all gone a bit clearer. The tree is, probably - in my book, one of those components that simply haven't been touched on for a while because it "may" be sufficient for what most want to achieve with it: simple data presentation with not too much data.

Basically, the best solution for when you want to use the tree but don't want an unnecessary huge load on that page then using an ajax-fed tree is ideal. But not very much out-of-the-box, although I found this to be pretty easy to implement. Personally I've looked at the 1.0.0 version of the tree plugin, found this to be a huge improvement, and then went on to implement it. It's rather easy and painless - but I'll handle that in the next post.

No comments:

Post a Comment