File tree 2 files changed +45
-12
lines changed
2 files changed +45
-12
lines changed Original file line number Diff line number Diff line change @@ -1107,4 +1107,36 @@ describe('reactivity/computed', () => {
1107
1107
end . prop4 . value ,
1108
1108
] ) . toMatchObject ( [ - 2 , - 4 , 2 , 3 ] )
1109
1109
} )
1110
+
1111
+ test ( 'performance when removing dependencies from deeply nested computeds' , ( ) => {
1112
+ const base = ref ( 1 )
1113
+ const trigger = ref ( true )
1114
+ const computeds : ComputedRef < number > [ ] = [ ]
1115
+
1116
+ const LAYERS = 30
1117
+
1118
+ for ( let i = 0 ; i < LAYERS ; i ++ ) {
1119
+ const earlier = [ ...computeds ]
1120
+
1121
+ computeds . push (
1122
+ computed ( ( ) => {
1123
+ return base . value + earlier . reduce ( ( sum , c ) => sum + c . value , 0 )
1124
+ } ) ,
1125
+ )
1126
+ }
1127
+
1128
+ const tail = computed ( ( ) =>
1129
+ trigger . value ? computeds [ computeds . length - 1 ] . value : 0 ,
1130
+ )
1131
+
1132
+ const t0 = performance . now ( )
1133
+ expect ( tail . value ) . toBe ( 2 ** ( LAYERS - 1 ) )
1134
+ const t1 = performance . now ( )
1135
+ expect ( t1 - t0 ) . toBeLessThan ( process . env . CI ? 100 : 30 )
1136
+
1137
+ trigger . value = false
1138
+ expect ( tail . value ) . toBe ( 0 )
1139
+ const t2 = performance . now ( )
1140
+ expect ( t2 - t1 ) . toBeLessThan ( process . env . CI ? 100 : 30 )
1141
+ } )
1110
1142
} )
Original file line number Diff line number Diff line change @@ -426,23 +426,24 @@ function removeSub(link: Link, soft = false) {
426
426
nextSub . prevSub = prevSub
427
427
link . nextSub = undefined
428
428
}
429
- if ( dep . subs === link ) {
430
- // was previous tail, point new tail to prev
431
- dep . subs = prevSub
432
- }
433
429
if ( __DEV__ && dep . subsHead === link ) {
434
430
// was previous head, point new head to next
435
431
dep . subsHead = nextSub
436
432
}
437
433
438
- if ( ! dep . subs && dep . computed ) {
439
- // if computed, unsubscribe it from all its deps so this computed and its
440
- // value can be GCed
441
- dep . computed . flags &= ~ EffectFlags . TRACKING
442
- for ( let l = dep . computed . deps ; l ; l = l . nextDep ) {
443
- // here we are only "soft" unsubscribing because the computed still keeps
444
- // referencing the deps and the dep should not decrease its sub count
445
- removeSub ( l , true )
434
+ if ( dep . subs === link ) {
435
+ // was previous tail, point new tail to prev
436
+ dep . subs = prevSub
437
+
438
+ if ( ! prevSub && dep . computed ) {
439
+ // if computed, unsubscribe it from all its deps so this computed and its
440
+ // value can be GCed
441
+ dep . computed . flags &= ~ EffectFlags . TRACKING
442
+ for ( let l = dep . computed . deps ; l ; l = l . nextDep ) {
443
+ // here we are only "soft" unsubscribing because the computed still keeps
444
+ // referencing the deps and the dep should not decrease its sub count
445
+ removeSub ( l , true )
446
+ }
446
447
}
447
448
}
448
449
You can’t perform that action at this time.
0 commit comments