Skip to content

Commit acfadc3

Browse files
committed
some optimizations
1 parent bba628b commit acfadc3

File tree

5 files changed

+48
-43
lines changed

5 files changed

+48
-43
lines changed

src/runtime/component_node.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,11 @@ export class ComponentNode implements VNode<ComponentNode> {
5757
this.parent = parent;
5858
this.parentKey = parentKey;
5959
this.pluginManager = parent ? parent.pluginManager : app.pluginManager;
60-
this.signalComputation = createComputation({
61-
compute: () => this.render(false),
62-
state: ComputationState.EXECUTED,
63-
isDerived: false,
64-
});
60+
this.signalComputation = createComputation(
61+
() => this.render(false),
62+
false,
63+
ComputationState.EXECUTED
64+
);
6565
this.props = Object.assign({}, props);
6666
contextStack.push({
6767
type: "component",

src/runtime/reactivity/computations.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,18 @@ export const atomSymbol = Symbol("Atom");
3333
let observers: ComputationAtom[] = [];
3434
let currentComputation: ComputationAtom | undefined;
3535

36-
export function createComputation(options: Partial<ComputationAtom> = {}): ComputationAtom {
36+
export function createComputation(
37+
compute: () => any,
38+
isDerived: boolean,
39+
state: ComputationState = ComputationState.STALE
40+
): ComputationAtom {
3741
return {
38-
state: ComputationState.STALE,
42+
state,
3943
value: undefined,
40-
compute() {},
44+
compute,
4145
sources: new Set(),
4246
observers: new Set(),
43-
isDerived: false,
44-
...options,
47+
isDerived,
4548
};
4649
}
4750

src/runtime/reactivity/computed.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ export function computed<TRead, TWrite = TRead>(
1515
getter: () => TRead,
1616
options: ComputedOptions<TWrite> = {}
1717
): ReactiveValue<TRead, TWrite> {
18-
const computation = createComputation({
19-
compute: () => {
18+
const computation = createComputation(
19+
() => {
2020
onWriteAtom(computation);
2121
return getter();
2222
},
23-
isDerived: true,
24-
});
23+
true
24+
);
2525

2626
function readComputed() {
2727
updateComputation(computation);

src/runtime/reactivity/effect.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,17 @@ import {
99
} from "./computations";
1010

1111
export function effect<T>(fn: () => T) {
12-
const computation = createComputation({
13-
compute() {
12+
const computation = createComputation(
13+
() => {
1414
// In case the cleanup read an atom.
1515
// todo: test it
1616
setComputation(undefined);
1717
unsubscribeEffect(computation);
1818
setComputation(computation);
1919
return fn();
2020
},
21-
isDerived: false,
22-
});
21+
false
22+
);
2323
getCurrentComputation()?.observers.add(computation);
2424
updateComputation(computation);
2525

src/runtime/reactivity/proxy.ts

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,33 +15,21 @@ type CollectionRawType = "Set" | "Map" | "WeakMap";
1515
const objectToString = Object.prototype.toString;
1616
const objectHasOwnProperty = Object.prototype.hasOwnProperty;
1717

18-
// Use arrays because Array.includes is faster than Set.has for small arrays
19-
const SUPPORTED_RAW_TYPES = ["Object", "Array", "Set", "Map", "WeakMap"];
20-
const COLLECTION_RAW_TYPES = ["Set", "Map", "WeakMap"];
21-
22-
/**
23-
* extract "RawType" from strings like "[object RawType]" => this lets us ignore
24-
* many native objects such as Promise (whose toString is [object Promise])
25-
* or Date ([object Date]), while also supporting collections without using
26-
* instanceof in a loop
27-
*
28-
* @param obj the object to check
29-
* @returns the raw type of the object
30-
*/
31-
function rawType(obj: any) {
32-
return objectToString.call(toRaw(obj)).slice(8, -1);
33-
}
3418
/**
3519
* Checks whether a given value can be made into a proxy object.
3620
*
3721
* @param value the value to check
3822
* @returns whether the value can be made proxy
3923
*/
4024
function canBeMadeReactive(value: any): boolean {
41-
if (typeof value !== "object") {
25+
if (typeof value !== "object" || value === null) {
4226
return false;
4327
}
44-
return SUPPORTED_RAW_TYPES.includes(rawType(value));
28+
const raw = toRaw(value);
29+
if (Array.isArray(raw) || raw instanceof Set || raw instanceof Map || raw instanceof WeakMap) {
30+
return true;
31+
}
32+
return objectToString.call(raw) === "[object Object]";
4533
}
4634
/**
4735
* Creates a proxy from the given object/callback if possible and returns it,
@@ -151,10 +139,16 @@ export function proxifyTarget<T extends Target>(target: T, atom: Atom | null): T
151139
return reactive as T;
152140
}
153141

154-
const targetRawType = rawType(target);
155-
const handler = COLLECTION_RAW_TYPES.includes(targetRawType)
156-
? collectionsProxyHandler(target as Collection, targetRawType as CollectionRawType, atom)
157-
: basicProxyHandler<T>(atom);
142+
let handler: ProxyHandler<any>;
143+
if (target instanceof Map) {
144+
handler = collectionsProxyHandler(target as unknown as Collection, "Map", atom);
145+
} else if (target instanceof Set) {
146+
handler = collectionsProxyHandler(target as unknown as Collection, "Set", atom);
147+
} else if (target instanceof WeakMap) {
148+
handler = collectionsProxyHandler(target as unknown as Collection, "WeakMap", atom);
149+
} else {
150+
handler = basicProxyHandler<T>(atom);
151+
}
158152
const proxy = new Proxy(target, handler as ProxyHandler<T>) as Reactive<T>;
159153

160154
proxyCache.set(target, proxy);
@@ -203,13 +197,21 @@ export function proxy<T extends Target>(target: T): T {
203197
function basicProxyHandler<T extends Target>(atom: Atom | null): ProxyHandler<T> {
204198
return {
205199
get(target, key, receiver) {
200+
onReadTargetKey(target, key, atom);
201+
const value = Reflect.get(target, key, receiver);
202+
// Fast path: signal-based proxies and primitive values don't need wrapping
203+
if (atom || typeof value !== "object" || value === null) {
204+
return value;
205+
}
206+
if (!canBeMadeReactive(value)) {
207+
return value;
208+
}
206209
// non-writable non-configurable properties cannot be made proxy
207210
const desc = Object.getOwnPropertyDescriptor(target, key);
208211
if (desc && !desc.writable && !desc.configurable) {
209-
return Reflect.get(target, key, receiver);
212+
return value;
210213
}
211-
onReadTargetKey(target, key, atom);
212-
return possiblyReactive(Reflect.get(target, key, receiver), atom);
214+
return proxifyTarget(value, null);
213215
},
214216
set(target, key, value, receiver) {
215217
const hadKey = objectHasOwnProperty.call(target, key);

0 commit comments

Comments
 (0)