Skip to content

Commit a6c0081

Browse files
AaronOHazAT
authored andcommitted
Optimize supportsNativeFetch() with a fast path that avoids DOM I/O (#2326)
* Optimize supportsNativeFetch() with a fast path that avoids DOM I/O * Fix dumb typo / bad keypress
1 parent feb00cf commit a6c0081

File tree

1 file changed

+17
-9
lines changed

1 file changed

+17
-9
lines changed

packages/utils/src/supports.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,13 @@ export function supportsFetch(): boolean {
7676
return false;
7777
}
7878
}
79+
/**
80+
* isNativeFetch checks if the given function is a native implementation of fetch()
81+
*/
82+
function isNativeFetch(func: Function): boolean {
83+
return func && /^function fetch\(\)\s+\{\s+\[native code\]\s+\}$/.test(func.toString());
84+
}
85+
7986

8087
/**
8188
* Tells whether current environment supports Fetch API natively
@@ -88,30 +95,31 @@ export function supportsNativeFetch(): boolean {
8895
return false;
8996
}
9097

91-
const isNativeFunc = (func: Function) => func.toString().indexOf('native') !== -1;
9298
const global = getGlobalObject<Window>();
93-
let result = null;
99+
100+
// Fast path to avoid DOM I/O
101+
if (isNativeFetch(global.fetch)) {
102+
return true;
103+
}
104+
105+
// window.fetch is implemented, but is polyfilled or already wrapped (e.g: by a chrome extension)
106+
// so create a "pure" iframe to see if that has native fetch
107+
let result = false;
94108
const doc = global.document;
95109
if (doc) {
96110
const sandbox = doc.createElement('iframe');
97111
sandbox.hidden = true;
98112
try {
99113
doc.head.appendChild(sandbox);
100114
if (sandbox.contentWindow && sandbox.contentWindow.fetch) {
101-
// tslint:disable-next-line no-unbound-method
102-
result = isNativeFunc(sandbox.contentWindow.fetch);
115+
result = isNativeFetch(sandbox.contentWindow.fetch);
103116
}
104117
doc.head.removeChild(sandbox);
105118
} catch (err) {
106119
logger.warn('Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ', err);
107120
}
108121
}
109122

110-
if (result === null) {
111-
// tslint:disable-next-line no-unbound-method
112-
result = isNativeFunc(global.fetch);
113-
}
114-
115123
return result;
116124
}
117125

0 commit comments

Comments
 (0)