It's not every day you get find a major bug in a browser rendering engine. I am honestly happy to have found this. Our team spent months investigating this issue before realizing it was not our Control that was the problem, but a single CSS property! OK, without further ado, here is the issue.

The Problem

In all versions of IE, FlexGrid's scrolling performance was terrible. You can see it for yourself by running this sample: And here is a visualization of the problem. Pay attention to the FPS (Frames Per Second). It drops to nearly zero FPS during the entire scroll process.

Our FlexGrid virtualizes the DOM for its cells as a performance optimization. Because of this, you can data-bind a million records in less than a second. If we created a DOM element for every property of every record the browser would come to a hault. For example, even a grid with 1,000 rows and 10 columns would need 10,000 DOM elements. So what we do is simply generate enough elements to show in the grids viewport, including a slight buffer.

In order to virtualize the DOM, we attach to the scroll event and manipulate the DOM to display the necessary cells.

Naturally, it seemed like the cause for the problem was our JavaScript. We thought the scroll performance problem must be related to our implementation.

We worked with the IE team to see if they could help us identify this problem. They were eager to help (thanks pals), but like us, they assumed the problem was JavaScript related. They had a lot of suggestions and we tried all of them.

Here are some of the things we tried:

  • Removing inline styles on cells and generating dynamic classes at runtime

  • Throttling scroll events to only call every n milliseconds

  • Using requestAnimationFrame to prevent paint reflows too often

  • Fine-tuned every DOM API call during our scroll event

  • Adding row elements instead of only cells

  • Anything else we could desperately think of...

The Cause

As we were desperately trying all of these solutions, we accidentally left out our CSS file. We noticed that without our CSS file, performance was fine. And just like that, we identified that our crippling performance issue was not in JS, but in CSS. It was a relief to narrow the problem down and have a lead.

We then went through and tested every CSS property until we identified the problem. It came down to a single line of CSS in our core CSS.

The cause was line 7 in wijmo.css that set border-radius:4px. Here is the culprit:
.wj-content {
/* Primary wj control style - applies to all controls */
display: inline-block;
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 4px;
background-color: #fff;
outline: none;
box-sizing: border-box;

I could not believe that removing border-radius suddenly made our grid scroll as smooth as hot butter. It was too good to be true. I tested 100 times and then finally let it sink in that a single CSS rule was destroying our entire grid in IE.

Just in case you don't believe that it is not our controls causing problems, we made these static pages that demonstrate the issue using just HTML and CSS. You can see try the sample including border-radius (bad) and excluding border-radius (good).

I believe the problem is isolated to having a scrollable parent element with border radius > 0 and containing many absolute positioned elements.

The Solution

So, I added style="border-radius:0" to the element hosting my FlexGrid and the sample was as fast as can be in IE. You can see the fix for yourself by running this sample: You can also see how our FPS is back to normal just by changing that single CSS rule. Honestly, this blew my mind.

Update: The IE team has confirmed that this is a high priority bug and that they will be fixing it. 

Hot Fixes

To fix this problem, you just need to use Build 51 (just released).

If you need to keep you current version, then add this style to your application:
border-radius: 0 !important;

Either way, you can quickly patch this nasty IE bug.

Thank you to all of our customers that helped us test all of our other performance tunings, and hung in there while we solved this problem.

This problem could easily still be unsolved. I wanted to blog about all of this detail to possibly help others that run across it. Because this was one hell of a bug to isolate.