-
-
Notifications
You must be signed in to change notification settings - Fork 8.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(reactivity): use more efficient reactive checks
WeakSets and WeakMaps shows degrading performance as the amount of observed objects increases. Using hidden keys result in better performance especially when repeatedly creating large amounts of reactive proxies. This also makes it possible to more efficiently declare non-reactive objects in userland.
- Loading branch information
Showing
13 changed files
with
145 additions
and
78 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,18 +5,11 @@ import { reactive, isProxy, toRaw } from './reactive' | |
import { ComputedRef } from './computed' | ||
import { CollectionTypes } from './collectionHandlers' | ||
|
||
const isRefSymbol = Symbol() | ||
|
||
export interface Ref<T = any> { | ||
// This field is necessary to allow TS to differentiate a Ref from a plain | ||
// object that happens to have a "value" field. | ||
// However, checking a symbol on an arbitrary object is much slower than | ||
// checking a plain property, so we use a _isRef plain property for isRef() | ||
// check in the actual implementation. | ||
// The reason for not just declaring _isRef in the interface is because we | ||
// don't want this internal field to leak into userland autocompletion - | ||
// a private symbol, on the other hand, achieves just that. | ||
[isRefSymbol]: true | ||
/** | ||
* @internal | ||
*/ | ||
__v_isRef: true | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
pikax
Member
|
||
value: T | ||
} | ||
|
||
|
@@ -27,7 +20,7 @@ const convert = <T extends unknown>(val: T): T => | |
|
||
export function isRef<T>(r: Ref<T> | unknown): r is Ref<T> | ||
export function isRef(r: any): r is Ref { | ||
return r ? r._isRef === true : false | ||
return r ? r.__v_isRef === true : false | ||
} | ||
|
||
export function ref<T extends object>( | ||
|
@@ -51,7 +44,7 @@ function createRef(rawValue: unknown, shallow = false) { | |
} | ||
let value = shallow ? rawValue : convert(rawValue) | ||
const r = { | ||
_isRef: true, | ||
__v_isRef: true, | ||
get value() { | ||
track(r, TrackOpTypes.GET, 'value') | ||
return value | ||
|
@@ -99,7 +92,7 @@ export function customRef<T>(factory: CustomRefFactory<T>): Ref<T> { | |
() => trigger(r, TriggerOpTypes.SET, 'value') | ||
) | ||
const r = { | ||
_isRef: true, | ||
__v_isRef: true, | ||
get value() { | ||
return get() | ||
}, | ||
|
@@ -126,7 +119,7 @@ export function toRef<T extends object, K extends keyof T>( | |
key: K | ||
): Ref<T[K]> { | ||
return { | ||
_isRef: true, | ||
__v_isRef: true, | ||
get value(): any { | ||
return object[key] | ||
}, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { render, h, nodeOps, reactive, isReactive } from '@vue/runtime-test' | ||
|
||
describe('misc', () => { | ||
test('component public instance should not be observable', () => { | ||
let instance: any | ||
const Comp = { | ||
render() {}, | ||
mounted() { | ||
instance = this | ||
} | ||
} | ||
render(h(Comp), nodeOps.createElement('div')) | ||
expect(instance).toBeDefined() | ||
const r = reactive(instance) | ||
expect(r).toBe(instance) | ||
expect(isReactive(r)).toBe(false) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
I think this change introduced a regression, see #1111