⚡️ optimize sandbox performance (#978)
This commit is contained in:
parent
b7d5adeb2a
commit
1446c6b212
|
|
@ -27,7 +27,12 @@ export function getTargetValue(target: any, value: any): any {
|
||||||
|
|
||||||
const boundValue = value.bind(target);
|
const boundValue = value.bind(target);
|
||||||
// some callable function has custom fields, we need to copy the enumerable props to boundValue. such as moment function.
|
// some callable function has custom fields, we need to copy the enumerable props to boundValue. such as moment function.
|
||||||
Object.keys(value).forEach(key => (boundValue[key] = value[key]));
|
// use for..in rather than Object.keys.forEach for performance reason
|
||||||
|
// eslint-disable-next-line guard-for-in,no-restricted-syntax
|
||||||
|
for (const key in value) {
|
||||||
|
boundValue[key] = value[key];
|
||||||
|
}
|
||||||
|
|
||||||
// copy prototype, for performance reason, we use in operator to check rather than hasOwnProperty
|
// copy prototype, for performance reason, we use in operator to check rather than hasOwnProperty
|
||||||
if ('prototype' in value) boundValue.prototype = value.prototype;
|
if ('prototype' in value) boundValue.prototype = value.prototype;
|
||||||
Object.defineProperty(value, boundValueSymbol, { enumerable: false, value: boundValue });
|
Object.defineProperty(value, boundValueSymbol, { enumerable: false, value: boundValue });
|
||||||
|
|
@ -37,7 +42,7 @@ export function getTargetValue(target: any, value: any): any {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const getterInvocationResultMap = new Map<CallableFunction, any>();
|
const getterInvocationResultMap = new WeakMap<CallableFunction, any>();
|
||||||
|
|
||||||
export function getProxyPropertyValue(getter: CallableFunction) {
|
export function getProxyPropertyValue(getter: CallableFunction) {
|
||||||
const getterResult = getterInvocationResultMap.get(getter);
|
const getterResult = getterInvocationResultMap.get(getter);
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ const SCRIPT_TAG_NAME = 'SCRIPT';
|
||||||
const LINK_TAG_NAME = 'LINK';
|
const LINK_TAG_NAME = 'LINK';
|
||||||
const STYLE_TAG_NAME = 'STYLE';
|
const STYLE_TAG_NAME = 'STYLE';
|
||||||
|
|
||||||
const proxyContainerInfoMapper = new Map<WindowProxy, Record<string, any>>();
|
const proxyContainerInfoMapper = new WeakMap<WindowProxy, Record<string, any>>();
|
||||||
|
|
||||||
function isHijackingTag(tagName?: string) {
|
function isHijackingTag(tagName?: string) {
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
22
src/utils.ts
22
src/utils.ts
|
|
@ -22,16 +22,22 @@ export function nextTick(cb: () => void): void {
|
||||||
Promise.resolve().then(cb);
|
Promise.resolve().then(cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isConstructable(fn: () => void | FunctionConstructor) {
|
const constructableMap = new WeakMap<Function, boolean>();
|
||||||
|
export function isConstructable(fn: () => any | FunctionConstructor) {
|
||||||
|
if (constructableMap.has(fn)) {
|
||||||
|
return constructableMap.get(fn);
|
||||||
|
}
|
||||||
|
|
||||||
const constructableFunctionRegex = /^function\b\s[A-Z].*/;
|
const constructableFunctionRegex = /^function\b\s[A-Z].*/;
|
||||||
const classRegex = /^class\b/;
|
const classRegex = /^class\b/;
|
||||||
|
|
||||||
// 有 prototype 并且 prototype 上有定义一系列非 constructor 属性,则可以认为是一个构造函数
|
// 有 prototype 并且 prototype 上有定义一系列非 constructor 属性,则可以认为是一个构造函数
|
||||||
return (
|
const constructable =
|
||||||
(fn.prototype && fn.prototype.constructor === fn && Object.getOwnPropertyNames(fn.prototype).length > 1) ||
|
(fn.prototype && fn.prototype.constructor === fn && Object.getOwnPropertyNames(fn.prototype).length > 1) ||
|
||||||
constructableFunctionRegex.test(fn.toString()) ||
|
constructableFunctionRegex.test(fn.toString()) ||
|
||||||
classRegex.test(fn.toString())
|
classRegex.test(fn.toString());
|
||||||
);
|
constructableMap.set(fn, constructable);
|
||||||
|
return constructable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -45,12 +51,18 @@ export const isCallable = naughtySafari
|
||||||
? (fn: any) => typeof fn === 'function' && typeof fn !== 'undefined'
|
? (fn: any) => typeof fn === 'function' && typeof fn !== 'undefined'
|
||||||
: (fn: any) => typeof fn === 'function';
|
: (fn: any) => typeof fn === 'function';
|
||||||
|
|
||||||
|
const boundedMap = new WeakMap<CallableFunction, boolean>();
|
||||||
export function isBoundedFunction(fn: CallableFunction) {
|
export function isBoundedFunction(fn: CallableFunction) {
|
||||||
|
if (boundedMap.has(fn)) {
|
||||||
|
return boundedMap.get(fn);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
indexOf is faster than startsWith
|
indexOf is faster than startsWith
|
||||||
see https://jsperf.com/string-startswith/72
|
see https://jsperf.com/string-startswith/72
|
||||||
*/
|
*/
|
||||||
return fn.name.indexOf('bound ') === 0 && !fn.hasOwnProperty('prototype');
|
const bounded = fn.name.indexOf('bound ') === 0 && !fn.hasOwnProperty('prototype');
|
||||||
|
boundedMap.set(fn, bounded);
|
||||||
|
return bounded;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user