patternjavascriptMinor
Optimise JavaScript DOM update
Viewed 0 times
javascriptoptimisedomupdate
Problem
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:
http://jsfiddle.net/FGr7g/1/
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 -
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.
http://jsfiddle.net/FGr7g/1/
function test(count) {
var self = window;
var limit = 25;
if (count = limit) {
alert((1000 / ((performance.now() - self.startTime) / limit)) + " fps");
}
}
function render(count) {
for (var x = 0; x
.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.
Solution
First off, your code doesn't seem very optimal. This doesn't effect the speed as far as I can see, but does effect the readability, which may limit the help you get here.
Here is the simplified code I used: http://jsfiddle.net/jJa8L/2/
Some experimentation show for me that the biggest speed hog seems to be the absolute positioning. When I comment it out, then I get speed improvements of 30 to 50% (40-45 fps) in Chrome. I haven't had a chance to try it out, but I'd try using a table layout (either using a
EDIT 4:
I just had another idea: There is a considerable speed up in Firefox and IE (but not Chrome for some reason) if you hide the grid while updating the cell texts: http://jsfiddle.net/jJa8L/8/
- Why do you create a second
divinside#grid?
- Why do you assign the styles of the cells twice (inline to the
styleattribute and a second time via the class)?
- Why are you using a class at all? A selector such as
#grid > div > div' would be easier.
Here is the simplified code I used: http://jsfiddle.net/jJa8L/2/
Some experimentation show for me that the biggest speed hog seems to be the absolute positioning. When I comment it out, then I get speed improvements of 30 to 50% (40-45 fps) in Chrome. I haven't had a chance to try it out, but I'd try using a table layout (either using a
directly in the HTML, or using display: table-* in the CSS).
EDIT: I just discovered one certain optimization: Moving the font property from the class to more global rule (body or #grid), raises the fps in Chrome to 35-38. See http://jsfiddle.net/jJa8L/3/
EDIT 2: Ok, here's a version with table layout: http://jsfiddle.net/jJa8L/4/ It's still at 40-45 fps.
EDIT 3: No idea why I didn't think of this before: Simply let the cells flow with display: inline-block giving #grid` an appriopriate width. http://jsfiddle.net/jJa8L/5/ This is slightly faster (42-47 fps).EDIT 4:
I just had another idea: There is a considerable speed up in Firefox and IE (but not Chrome for some reason) if you hide the grid while updating the cell texts: http://jsfiddle.net/jJa8L/8/
Context
StackExchange Code Review Q#44651, answer score: 4
Revisions (0)
No revisions yet.