⚡️ 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);
|
||||
// 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
|
||||
if ('prototype' in value) boundValue.prototype = value.prototype;
|
||||
Object.defineProperty(value, boundValueSymbol, { enumerable: false, value: boundValue });
|
||||
|
|
@ -37,7 +42,7 @@ export function getTargetValue(target: any, value: any): any {
|
|||
return value;
|
||||
}
|
||||
|
||||
const getterInvocationResultMap = new Map<CallableFunction, any>();
|
||||
const getterInvocationResultMap = new WeakMap<CallableFunction, any>();
|
||||
|
||||
export function getProxyPropertyValue(getter: CallableFunction) {
|
||||
const getterResult = getterInvocationResultMap.get(getter);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ const SCRIPT_TAG_NAME = 'SCRIPT';
|
|||
const LINK_TAG_NAME = 'LINK';
|
||||
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) {
|
||||
return (
|
||||
|
|
|
|||
22
src/utils.ts
22
src/utils.ts
|
|
@ -22,16 +22,22 @@ export function nextTick(cb: () => void): void {
|
|||
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 classRegex = /^class\b/;
|
||||
|
||||
// 有 prototype 并且 prototype 上有定义一系列非 constructor 属性,则可以认为是一个构造函数
|
||||
return (
|
||||
const constructable =
|
||||
(fn.prototype && fn.prototype.constructor === fn && Object.getOwnPropertyNames(fn.prototype).length > 1) ||
|
||||
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';
|
||||
|
||||
const boundedMap = new WeakMap<CallableFunction, boolean>();
|
||||
export function isBoundedFunction(fn: CallableFunction) {
|
||||
if (boundedMap.has(fn)) {
|
||||
return boundedMap.get(fn);
|
||||
}
|
||||
/*
|
||||
indexOf is faster than startsWith
|
||||
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