GSoC Week: 4
The focus for the end of this week was to get ready with a basic prototype that can be released to the users. Therefore, most of the work was testing and finding bugs in the current working code.
Bugs
- A major bug was maintaining the scroll direction. Although it worked well for normal scrolling, every time a row with
load-next-set
came into view and the corresponding load and delete operations took place, the adjustment of the scroll heights always led to change in the value of the variable storing the direction (even though the user didn’t technically scroll).
A workaround for it is to maintain what function was executed previously. For eg, if the last thing to be executed had been the loading of next set, then we wouldn’t perform the loading of upper set within 250ms of it. This allows for the function to ignore the change in values caused due to scrollbar adjustments.
Here is how the variable flag
is maintained to do the above task:
var flag = 0;
$(table.parentNode.parentNode).bind('scroll', function(evt) {
// initialization of variables
// Condition to load next set && !flag {
flag = true; // set to true
// }
// Condition to load upper set && !flag {
flag = true; // set to true
// }
clearTimeout($.data(this, 'scrollTimer'));
$.data(this, 'scrollTimer', setTimeout(function() {
// other functions related to loading sets
flag = 0; // set to false
}, 250));
self._scrollTop = $(this).scrollTop();
});
- Since the calculations for the
sizeRowFirst
etc. were done in theresize
function, every time the window was resized, a lot of these values changed and became inconsistent with the table (this is because the resize event doesn’t necessarily change the table layout or row size anymore).
This was particularly easy to fix. All that was required was to shift these calculations to the renderDataTables
function. This ensured that the initial calculations related to size were done only once at the beginning.
- Another bug was with checking when the
first-row
comes into view. The problem was that usingposition.top
ofgetBoundingClientRect
gave us it’s position from the viewport top and not the parent element. This gave wrong calculations, as even when the element wasn’t visible (but was somewhere under the header and view-panel elements) the row would be evaluated as visible.
One way to fix this was to change the condition value from if(positionFirstElement.top < 0 && positionFirstElement.bottom >= window.innerHeight)
to if(positionFirstElement.top < self._headerTop + 1 &&
positionFirstElement.bottom >= window.innerHeight)
Here headerTop
is a variable that contains the height of the header and view-panel div
containers.
this._headerTop = $('thead').offset().top + $('thead').height();
Improvements
sizeRowFirst
stores the height of the first row in order to calculate the size of a given set ofn
number of rows. The problem with that is that it assumes that the rest of the rows would be similar to the first one, which often is not the case. A better way would be to calculate the average row size of the first set and then use that for the calculations instead. This average size can be calculated by calculating the height of the first set and dividing it by the total number of rows it contains. Here’s the code for it:
var total = 0;
for (var i = 1; i < table.rows.length; i++) {
row = table.rows[i];
total += row.offsetHeight;
}
this._sizeRowFirst = total / 100;
this._sizeRowsTotal = this._sizeRowFirst * theProject.metadata.rowCount;
this._sizeSinglePage = this._sizeRowFirst * this._pageSize;
- The current calculations were done with fixing the size to 100 and using that everywhere. It is better to use a variable instead (in order to be able to manipulate the size based on different conditions). Perhaps, later when we start working on the performance.
Alternatives
I have also been working on using Intersection Observer API instead of the scroll event. The performance improvement that might come with it is definitely something to try and test. The work on that is on another branch that you can see here.
Conclusion
The prototype should be released to the users soon, and that would mark a significant point of the project. Improvement and performance along with the reported bugs would be the next step to the project.