Consider the code below. <GridBody Rows={rows} />
and imagine that rows.length
would amount to any value 2000 or more with each array has about 8 columns in this example. I use a more expanded version of this code to render a part of a table that has been bottle necking my web application.
var GridBody = React.createClass({
render: function () {
return <tbody>
{this.props.Rows.map((row, rowKey) => {
return this.renderRow(row, rowKey);
})}
</tbody>;
},
renderRow: function (row, rowKey) {
return <tr key={rowKey}>
{row.map((col, colKey) => {
return this.renderColumn(col, colKey);
})}
</tr>;
},
renderColumn: function (col, colKey) {
return <td key={colKey} dangerouslySetInnerHTML={{ __html: col } }></td>;
}
});
Now onto the actual problem. It would seem that putation (even with my own code) seems to be suprisingly fast and even ReactJS's work with the virtualDOM has no issues.
But then there are these two events in reactJS.
ponentWillUpdate
up until where everything is still okay.
And then there is ponentDidUpdate
which seems to be fine and all on chrome.
The problem
But then there is IE11/Edge with about 4-6 SECONDS slower than any other browser and with the F12-Inspector this seems to be p to 8 SECONDS slower than Chrome.
The steps I have done to try and fix this issue:
Strip unnecessary code.
Shave off a handful of milliseconds in putation time.
Split the grid in loose ponents so that the virtualDOM doesn't try to update the entire ponent at once.
Attempt to concaternate everything as a string and allow react to only set innerhtml once. This actually seems to be a bug in IE here a large string takes about 25-30 seconds on IE11. And only 30 ms on chrome.
I have not found a proper solution yet. The actions I have done above seemed to make things less bad in IE but the problem still persists that a "modern" or "recent" browser is still 3-4 seconds slower.
Even worse, this seems to nearly freeze the entire browser and it's rendering.
tl;dr How to improve overal performance in IE and if possible other browsers?
I apologize if my question is unclear, I am burned out on this matter.
edit: Specifically DOM access is slow on IE as set innerHTML gets called more than 10.000 times. Can this be prevented in ReactJS?
Consider the code below. <GridBody Rows={rows} />
and imagine that rows.length
would amount to any value 2000 or more with each array has about 8 columns in this example. I use a more expanded version of this code to render a part of a table that has been bottle necking my web application.
var GridBody = React.createClass({
render: function () {
return <tbody>
{this.props.Rows.map((row, rowKey) => {
return this.renderRow(row, rowKey);
})}
</tbody>;
},
renderRow: function (row, rowKey) {
return <tr key={rowKey}>
{row.map((col, colKey) => {
return this.renderColumn(col, colKey);
})}
</tr>;
},
renderColumn: function (col, colKey) {
return <td key={colKey} dangerouslySetInnerHTML={{ __html: col } }></td>;
}
});
Now onto the actual problem. It would seem that putation (even with my own code) seems to be suprisingly fast and even ReactJS's work with the virtualDOM has no issues.
But then there are these two events in reactJS.
ponentWillUpdate
up until where everything is still okay.
And then there is ponentDidUpdate
which seems to be fine and all on chrome.
The problem
But then there is IE11/Edge with about 4-6 SECONDS slower than any other browser and with the F12-Inspector this seems to be p to 8 SECONDS slower than Chrome.
The steps I have done to try and fix this issue:
Strip unnecessary code.
Shave off a handful of milliseconds in putation time.
Split the grid in loose ponents so that the virtualDOM doesn't try to update the entire ponent at once.
Attempt to concaternate everything as a string and allow react to only set innerhtml once. This actually seems to be a bug in IE here a large string takes about 25-30 seconds on IE11. And only 30 ms on chrome.
I have not found a proper solution yet. The actions I have done above seemed to make things less bad in IE but the problem still persists that a "modern" or "recent" browser is still 3-4 seconds slower.
Even worse, this seems to nearly freeze the entire browser and it's rendering.
tl;dr How to improve overal performance in IE and if possible other browsers?
I apologize if my question is unclear, I am burned out on this matter.
edit: Specifically DOM access is slow on IE as set innerHTML gets called more than 10.000 times. Can this be prevented in ReactJS?
Share Improve this question edited Sep 22, 2017 at 17:44 CommunityBot 11 silver badge asked May 13, 2016 at 13:42 PerfectionPerfection 7214 gold badges14 silver badges36 bronze badges 7- 1 If you can override the rendering. What you can do to drastically speed up performance is, reusing rows. What I mean is, if you show 10 rows at a time, create 20 rows in the dom (not the entire 2000+) then when the user scrolls, show the next set, clear the previous 10 of data and put the next set of data in that. A reference to elaborate on the idea: (although for a different library) elements.polymer-project/elements/iron-list. Refer to "Why should <iron-list> be used section. Hope this helps! – Joey Roosing Commented May 17, 2016 at 7:54
- We were thinking of implementing a similar thing but the problem would be that we want users to be able to use CTRL+F to search in such large lists as it is a requirement. – Perfection Commented May 18, 2016 at 10:00
- 1 In that case, can you not just add a search field on-top or below the grid, or on the column, and then search through your dataset in javascript rather then traversing the dom, if found in your dataset (in memory in JS), load that item and maybe the surrounding 10 items into the dom. I do agree it will feel less seemless.. maybe some animations could help solve this. – Joey Roosing Commented May 19, 2016 at 6:57
- That would require me to load the entire dataset (which can go over 1 million rows) to achieve the same functionality. We are currently limiting it to 2000 and using pagination. A search function is already present in the application but doesn't really solve the performance issue with 2000 results. – Perfection Commented May 19, 2016 at 7:18
- Something crazy; I don't know if you can override cntrl+f search in Javascript. If so, you can catch the on-key event, search through your 2000 records that you hold in memory (but not in the dom!) right? Then you can still do the recycling, of maybe a 100-200 dom elements, while keeping 2k records at a time in memory. I think a bination of my first and second answer + how you currently handle a search that is outside your loaded 2k records should be able to solve your problem. – Joey Roosing Commented May 19, 2016 at 7:31
3 Answers
Reset to default 8 +50Things to try improve IE performance:
check you are running in production mode (which removes things like prop validation) and make Webpack / Babel optimisations where applicable
Render the page server side so IE has no issues (if you can support SS rendering in your setup)
Make sure render isnt called alot of times, tools like this are helpful: https://github./garbles/why-did-you-update
Any reason why you are using
dangerouslySetInnerHTML
? If you take out thedangerouslySetInnerHTML
does it speed things up dramatically? Why not just automatically generate the rows and cols based on a array of objects (or multidimensional array passed), im pretty sure then React will make less DOM interaction this way (makes use of the VDOM). The<tr>
and<td>
's will be virtual dom nodes.Use something like https://github./bvaughn/react-virtualized to efficiently render large lists
Shot in the dark: try not rendering, or not displaying, until everything is pletely done.
- make the table element display:none until it's done
- render it offscreen
- in a tiny DIV with hidden overflow
- or even output to a giant HTML string and then insert that into the DOM upon pletion.
In addition to @Marty's excellent points, run a dynaTrace session to pinpoint the problematic code. It should give you a better insight into where the bottleneck is. It's results are often more useful than the IE developer tools.
Disclaimer - I am not linked with the dynaTrace team in any way.