I'm building a virtualised grid in JS/HTML and finding browser performance with large grids fairly slow, particularly in IE10/11. The following jsfiddle roughly represents my worst case scenario, approx 1000 cells:
function test(count) {
var self = window;
var limit = 25;
if (count < limit) {
//settimeout to give ui chance to render
setTimeout(function () {
self.render(count);
count++;
test(count);
}, 0);
}
if (count >= limit) {
alert((1000 / ((performance.now() - self.startTime) / limit)) + " fps");
}
}
function render(count) {
for (var x = 0; x < this.cellCount; x++) {
this.cells[x].textContent = count + " _c_" + x;
}
}
window.render = render;
$().ready(function () {
var self = window;
self.cellCount = 1000;
self.cells = [];
self.grid = document.createElement("div");
self.grid.style.position = "relative";
self.grid.style.height = "100%";
self.grid.style.overflow = "hidden";
for (var c = 0; c < cellCount; c++) {
var cell = document.createElement("div");
cell.style.width = "49px";
cell.style.height = "24px";
cell.style.padding = "10px";
cell.style.position = "absolute";
cell.style.overflow = "hidden";
cell.style.borderTop = "1px solid lightgray";
cell.style.borderLeft = "1px solid lightgray";
cell.style.backgroundColor = "whitesmoke";
cell.style.left = (c % 28) * 50 + "px";
cell.style.top = (Math.floor(c / 28) * 25) + "px";
cell.className = cell.className += " test_cell";
var span = document.createElement("span");
cell.appendChild(span);
self.grid.appendChild(cell);
self.cells.push(span);
}
document.getElementById("grid").appendChild(self.grid);
self.startTime = performance.now();
self.count = 0;
test(self.count);
self.totalTime = 0;
});
<div id="grid" style="width: 1500px; height: 900px"></div>
.test_cell {
text-align: right;
font: 8pt Segoe UI, Tahoma, Arial, Verdana;
width: 49px;
height: 24px;
border-left: 1px solid lightgray;
border-top: 1px solid lightgray;
position: absolute;
overflow: hidden;
}
I get around 10fps in IE at full screen, and around 30 in Chrome, assuming my performance measurement code is correct, it is consistent with the fps tools in Chrome so I think it is.
So far I've tried different methods of DOM manipulation - building a HTML string of the whole grid and inserting into the DOM (slower), using DOM fragments (slower), using a table instead of an array of absolute divs (slower), various ways of setting the span's content - innerHTML, textContent etc (made little difference), using different fonts/sizes (no difference).
Based on profiling I suspect that the majority of the time is painting rather than any java script code so I think any large improvements would like come from optimising the HTML/CSS so it is quicker to render, but any suggestions/modifications would be hugely appreciated.
If it makes any difference I am not targeting older browser versions.