Improve performance by reducing array slices and RegExp recreation #2128
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.
Checklist
npm run test
Motivation
Our app recently switched to using i18next. It works great, but the app felt slower. We have hundreds of strings on-screen at a time, so i18next code is run a lot.
After profiling, some i18next functions were the top contributors to time taken within our 20s stacktrace:
off
: used by react-i18next (and base library i18next) for detaching event handlers on unmount. It looks like it calls a array.filter according to source code. This may be iterating through a very large arraygetLastOfPath
: 158ms - code does a lot of recursive retrieval and also creates a RegExp, which may take longerlooksLikeObjectPath
: 293ms - code constructs RegExpgetResource
: 221ms - code runs concat anddeepFind
, which does a lot of O(n) array operationsLooking at the causes, the 2 main causes are:
.slice
,.concat
Fix
off
from anO(n)
toO(1)
looksLikeObjectPath
RegExp
that can be constructed so memory is trivialresetRegExp
new RegExp
every time, just setlastIndex = 0
to reset a globalRegExp
statedeepFind
performanceslice
, use indexing and string appending instead ofjoin
O(n^2)
toO(n)
getLastOfPath
performancenew RegExp
every time, setlastIndex = 0
O(1)
rather thanarray.shift
O(n)
getResource
performancepush
items into itTesting
deepFind
andeventEmitter.test.ts