dequelabs / axe-core-npm

Mozilla Public License 2.0
577 stars 65 forks source link

Choppy performance in a third party component after introducing axe-core #886

Open ashishbairwa opened 8 months ago

ashishbairwa commented 8 months ago

Product

react

Product Version

4.4.2

Latest Version

Issue Description

Expectation

Actual

After introducing axe-core into our project which is using stream-chat-react, we are facing a visible lag in the performance of emoji picker. On profiling the performance, we can see a function is constantly getting invoked from axe without any specific errors in the console

How to Reproduce

Here is the reproducible demo link https://codesandbox.io/s/bold-tesla-3mtyhf Steps to reproduce the issue:

Demo video - https://youtu.be/tWQtOKuJlZ4

Please find all the traces in the attachments. It includes snapshot and traces from performance profiler Trace-with emoji picker opened.json

Additional context

Stream chat react - https://www.npmjs.com/package/stream-chat-react Stream chat official website - https://getstream.io/chat/docs/sdk/react/

michael-siek commented 8 months ago

Hi @ashishbairwa we will look into this issue and provide an update when possible.

michael-siek commented 8 months ago

Hey @ashishbairwa have you tried updating to the latest version of @axe-core/react (4.8.1) to see if this is still an issue?

ashishbairwa commented 8 months ago

Hey @michael-siek , In sandbox I've used the latest available version 4.8.1 and it's happening on it.

straker commented 8 months ago

@ashishbairwa I tried to experiment with the codesandbox. It looks like when the emoji picker is open axe is constantly running in the background, and even takes up 100% of the CPU. I tried to run axe just by itself and it takes ~800ms to run when the emoji picker is open, so I'm surprised that it's always running. My current guess is that there is an element on the page that is constantly refreshing / reloading and causing our DOM watcher to constantly fire. I noticed the chat feature is frequently showing a connection error, so that might help contribute to the problem.

Would you be able to figure out what the constant DOM reloading is and see if removing the problem also fixes the axe performance problem?

ashishbairwa commented 8 months ago

Sure @straker , but could you please shed some light on how your dom watcher actually works? What kind of events do you actually look for? If you can point me to the line of code where the dom watcher is implemented. Maybe I can put some debug logs to pin point the events

straker commented 8 months ago

Sure. Our code overrides the React.createElement function to register all React components. We then listen to the componentDidMount and componentDidUpdate events and run axe when they fire. We debounce these functions and do some logic to run axe only once per debounce, so multiple nodes triggering an update will only result in a single axe run.