-
-
Notifications
You must be signed in to change notification settings - Fork 8.8k
Description
What problem does this feature solve?
I propose a performance optimization.
Applications use plenty of arrays. Full array iteration is extremely common:
v-for
performs afor (i = 0; i < length; i ) array[i]
loop when rendering;- computed or watch often call
.filter()
,.sort()
,.map()
and co. All of these result in a full iteration; - user code can also do a for loop or call
.forEach()
.
This top use-case is tracked like any normal object, key by key. If I have a reactive array containing 100 items, then calling .filter
in a computed will result in 102 new tracking entries: one for filter
, one for length
and 100 more from [0] to [99].
Each one results in a Set
allocation one entry in the reverse deps
array the required upkeep every time the effect runs again.
Because both (1) full array iteration is very common; and (2) arrays can be quite big, making tracking expensive; I think this may be worthy of a special optimization.
Here's one idea: detect full enumeration and only register a single symbol ALL_KEY
in response.
It could work like this:
- Add
arrayRanges: Map<Array, number>
oneffect
. - When
track
is called on an arraytarget
, if the key is numeric:- if
target
is not inactiveEffect.arrayRanges
and key is 0, add it with value0
. - if
target
is inarrayRanges
andkey === arrayRanges.get(target) 1
then incrementarrayRanges
.
- if
- At the end of
run
:- for each
arrayRanges
that is equals totarget.length - 1
, create a dependency with symbolALL_KEY
. - Clear
arrayRanges
- for each
- When calling
trigger
, iftarget
is an array andkey
is numeric, additionally triggerALL_KEY
.
What does the proposed API look like?
No new public API