Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: defer rules rather than checks #1308

Merged
merged 3 commits into from
Jan 9, 2019
Merged

Conversation

stephenmathieson
Copy link
Member

@stephenmathieson stephenmathieson commented Jan 8, 2019

This patch removes setTimeout() call from Check#run() and adds it to Rule#run(). The setTimeout() was originally added in 4657dc5 in order to prevent browsers from "freezing up" while running 1000s of synchronous checks. This had the downside of creating ~10k timers which slows down axe.run() considerably.

Moving the setTimeout() to Rule#run() ensures we continue to run asynchronously to prevent "unresponsive script" warnings, but we defer as little as possible. With this patch, we should see ~40 timers created rather than 10k+ since we now create one per Rule rather than one per Check.

Hat tip to @paulirish for starting this conversation in #1172.

Reviewer checks

Required fields, to be filled out by PR reviewer(s)

  • Follows the commit message policy, appropriate for next version
  • Has documentation updated, a DU ticket, or requires no documentation change
  • Includes new tests, or was unnecessary
  • Code is reviewed for security by: @WilcoFiers

This patch removes `setTimeout()` call from `Check#run()` and adds it to `Rule#run()`. The `setTimeout()` was originally added in 4657dc5 in order to prevent browsers from "freezing up" while running 1000s of synchronous checks. This had the downside of creating ~10k timers which slows down `axe.run()` considerably.

Moving the `setTimeout()` to `Rule#run()` ensures we continue to run asynchronously to prevent "unresponsive script" warnings, but we defer as little as possible. With this patch, we should see ~40 timers created rather than 10k+ since we now create one per Rule rather than one per Check.

Hat tip to @paulirish for starting this conversation in #1172.
@stephenmathieson stephenmathieson requested a review from a team January 8, 2019 18:51
@stephenmathieson stephenmathieson requested a review from a team as a code owner January 8, 2019 18:51
@paulirish
Copy link
Contributor

thanks! This looks perfect to me. 👍

@WilcoFiers
Copy link
Contributor

@stephenmathieson can you confirm you've tested this solution in the Chrome and Firefox extensions? Can you give some numbers on how much this improves performance?

@stephenmathieson
Copy link
Member Author

Yes, I've manually tested this in both extensions.

I can put together some quick performance results today.

@WilcoFiers WilcoFiers merged commit 80c1c74 into develop Jan 9, 2019
@WilcoFiers WilcoFiers deleted the defer-rule-not-check branch January 9, 2019 16:03
@stephenmathieson
Copy link
Member Author

To benchmark, I built axe-core for each both 4489965 and 80c1c74 (npm run build && cat axe.js | pbcopy).

Once built, axe.js was pasted into the Chrome developer tools. I'd then run the following snippet 4 times to collect sample data:

console.time('axe')
await axe.run()
console.timeEnd('axe')

benchmarks from google.com

at revision 80c1c74 (where this commit landed):

  • axe: 199.033935546875ms
  • axe: 171.033203125ms
  • axe: 169.7431640625ms
  • axe: 165.174072265625ms

199.033935546875 + 171.033203125 + 169.7431640625 + 165.174072265625 = 704.984375
704.984375 / 4 = 176.24609375

at revision 4489965 (prior to this commit):

  • axe: 240.59912109375ms
  • axe: 179.072021484375ms
  • axe: 176.920166015625ms
  • axe: 175.220947265625ms

240.59912109375 + 179.072021484375 + 176.920166015625 + 175.220947265625 = 771.812255859
771.812255859 / 4 = 192.953063965

results

With this patch, it takes ~176ms for axe.run() to complete. Prior to this patch, it took ~192ms. This is an average savings of ~20ms per run.

benchmarks from https://www.guidetoonlineschools.com/online-schools

NOTE: this is the URL @paulirish originally shared.

at revision 80c1c74 (where this commit landed):

  • axe: 22537.302001953125ms
  • axe: 21808.623046875ms
  • axe: 23041.050048828125ms
  • axe: 23189.9990234375ms

22537.302001953125 + 21808.623046875 + 23041.050048828125 + 23189.9990234375 = 90576.9741211
90576.9741211 / 4 = 22644.2435303

at revision 4489965 (prior to this commit):

  • axe: 24342.35107421875ms
  • axe: 25822.697265625ms
  • axe: 24546.11181640625ms
  • axe: 23406.01513671875ms

24342.35107421875 + 25822.697265625 + 24546.11181640625 + 23406.01513671875 = 98117.175293
98117.175293 / 4 = 24529.2938232

results

With this patch, it takes ~22.6s to for axe.run() to complete. Prior to this patch, it took ~24.5s. This is a savings of ~1.8s per run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants