Skip to content

Commit

Permalink
perf: defer rules rather than checks
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
stephenmathieson committed Jan 7, 2019
1 parent 986c97a commit 54afd23
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 3 deletions.
4 changes: 1 addition & 3 deletions lib/core/base/check.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,7 @@ Check.prototype.run = function(node, options, context, resolve, reject) {

if (!checkHelper.isAsync) {
checkResult.result = result;
setTimeout(function() {
resolve(checkResult);
}, 0);
resolve(checkResult);
}
} else {
resolve(null);
Expand Down
4 changes: 4 additions & 0 deletions lib/core/base/rule.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,10 @@ Rule.prototype.run = function(context, options, resolve, reject) {
});
});

// Defer the rule's execution to prevent "unresponsive script" warnings.
// See https://github.com/dequelabs/axe-core/pull/1172 for discussion and details.
q.defer(resolve => setTimeout(resolve, 0));

if (options.performanceTimer) {
axe.utils.performanceTimer.mark(markEnd);
axe.utils.performanceTimer.measure(
Expand Down

0 comments on commit 54afd23

Please sign in to comment.