microsoft / tabster

Web Application Keyboard Navigation Tools

Home Page:https://tabster.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Tabster causing costly recalculate styles when appending DOM elements to body

tejohans opened this issue · comments

The origin for the issue is based on a lazy loaded component that adds an aria live region in the body of Teams.

To reproduce the issue you can start the latest version of Teams and start a performance trace.

Then run the following code in the console.
document.body.appendChild((() => { e = document.createElement("div"); e.innerText = "Hello world!"; return e; })())

Stop the performance trace, and you should see something like this:
image

The 111ms is done on a fairly new desktop computer, with 4x slowdown the time to compute is more than 500ms.

The reason for the recalculate style is tabster, and specifically within

private _addDummyInputs() {

When the body gets the new child appended, tabsters timeout will later run, and move the <i> element to the bottom of the body. This causes the recalculate style to happen.

@tejohans, why is it needed to append elements to often enough for it to matter a lot?

I can imagine appending <script> tags might be necessary (which is not something that happens all the time). Anything else? These elements must be first and last focusable elements in the DOM for a specific purpose. We can try to adjust or to some extent throttle the updates, but I'd like to understand the scenarios to do it meaningfully and to understand why it is important.

@mshoho
For me there are two parts to this, one is the principle and the other is a real run-time issue.

The principle part is about the cost of adding a simple div to the body in the DOM should not be a several hundred millisecond task in an application. The exact same code in other applications uses 0-2ms on slowdown, compared to 500ms+ in Teams. When I discussed this internally I was asking if this was a tabster problem or an application problem, but I was encouraged to create the bug on tabster. At the moment, tabster is causing this to happen for any code that adds a div to the body - that is from my perspective not acceptable.

The second part is the run-time issue. When we lazy load our component and it is adding its aria live region, we get hit by this 100ms delay. However, its not the only recalculation outside of our control, there are several others as well. On my desktop PC, the totalt cost is 400ms+, on a slowdown we are seeing potentially seconds of recalculation. I need to get these issues solved one by one, else the first run experience for our component will not be good. And I think any other component that relies on similar logic will have a challenge with this.

If you think this behavior is something that cannot be improved, that is also an outcome that I can take into consideration when I continue my investigation.

The issue was caused by something else.

@mshoho can you explain what was causing this?

@ling1726 I cannot tell for sure. This particular issue is not reproducible anymore (Terje has confirmed that). Either Chromium has optimized something related (I tried to repro it in older public TMP version with current Chromium and it's not reproducible) or some styling change in TMP.