No longer use global setImmediate function due to performance issues #335
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
async.nextTick
Metal core currently provides an async module which has been brought over from google closure library, one of the most used methods from that module is
async.nextTick
. This method makes use of the browser’ssetImmediate
function if it is defined (currently only IE10+/Edge have a native implementation).Because most browsers do not have
setImmediate
defined, the async module provides a fallback for this functionality. In addition, commonly used babel presets will automatically provide a polyfill from core-js. If the polyfill is defined, it will win over the fallback.The problem is that the polyfill from core-js is significantly slower than the fallback provided by google closure. In addition, the
setImmediate
implementation in IE has known issues. This means the only reliable native implementation is in Edge.Due to these issues, closure library has introduced a change to their
nextTick
function so that it only uses the globally definedsetImmediate
function in Edge, or if the global function is an instance of their MockClock utility (which we do not provide in Metal).My proposal is to never use the globally defined
setImmediate
method in Metal, and to always use the fallback provided byasync
. That way we know we are using an optimized solution, and it is consistent across all browsers and environments.Metrics
My test case consisted of a table with 10,000 rows, and another with just 1000 rows. Each row being a sub component of the parent.
In both scenarios, the time it took to update the rows with new data was reduced by ~48% by no longer using the polyfill on Chrome.
10,000 row update with
setImmediate
polyfill10,000 row update with closure library's fallback