mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
PERF: avoid traversing DOM in loadScript
Once a script is loaded operation should be very fast. This optimisation avoids a DOM traverse and call to getURL on every invocation.
This commit is contained in:
@@ -45,34 +45,40 @@ export default function loadScript(url, opts) {
|
|||||||
|
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
|
|
||||||
|
if (_loaded[url]) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
// Scripts should always load from CDN
|
// Scripts should always load from CDN
|
||||||
// CSS is type text, to accept it from a CDN we would need to handle CORS
|
// CSS is type text, to accept it from a CDN we would need to handle CORS
|
||||||
url = opts.css ? Discourse.getURL(url) : Discourse.getURLWithCDN(url);
|
const fullUrl = opts.css
|
||||||
|
? Discourse.getURL(url)
|
||||||
|
: Discourse.getURLWithCDN(url);
|
||||||
|
|
||||||
$("script").each((i, tag) => {
|
$("script").each((i, tag) => {
|
||||||
const src = tag.getAttribute("src");
|
const src = tag.getAttribute("src");
|
||||||
|
|
||||||
if (src && src !== url && !_loading[src]) {
|
if (src && src !== fullUrl && !_loading[src]) {
|
||||||
_loaded[src] = true;
|
_loaded[src] = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return new Promise(function(resolve) {
|
return new Promise(function(resolve) {
|
||||||
// If we already loaded this url
|
// If we already loaded this url
|
||||||
if (_loaded[url]) {
|
if (_loaded[fullUrl]) {
|
||||||
return resolve();
|
return resolve();
|
||||||
}
|
}
|
||||||
if (_loading[url]) {
|
if (_loading[fullUrl]) {
|
||||||
return _loading[url].then(resolve);
|
return _loading[fullUrl].then(resolve);
|
||||||
}
|
}
|
||||||
|
|
||||||
let done;
|
let done;
|
||||||
_loading[url] = new Promise(function(_done) {
|
_loading[fullUrl] = new Promise(function(_done) {
|
||||||
done = _done;
|
done = _done;
|
||||||
});
|
});
|
||||||
|
|
||||||
_loading[url].then(function() {
|
_loading[fullUrl].then(function() {
|
||||||
delete _loading[url];
|
delete _loading[fullUrl];
|
||||||
});
|
});
|
||||||
|
|
||||||
const cb = function(data) {
|
const cb = function(data) {
|
||||||
@@ -82,17 +88,18 @@ export default function loadScript(url, opts) {
|
|||||||
done();
|
done();
|
||||||
resolve();
|
resolve();
|
||||||
_loaded[url] = true;
|
_loaded[url] = true;
|
||||||
|
_loaded[fullUrl] = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (opts.css) {
|
if (opts.css) {
|
||||||
ajax({
|
ajax({
|
||||||
url: url,
|
url: fullUrl,
|
||||||
dataType: "text",
|
dataType: "text",
|
||||||
cache: true
|
cache: true
|
||||||
}).then(cb);
|
}).then(cb);
|
||||||
} else {
|
} else {
|
||||||
// Always load JavaScript with script tag to avoid Content Security Policy inline violations
|
// Always load JavaScript with script tag to avoid Content Security Policy inline violations
|
||||||
loadWithTag(url, cb);
|
loadWithTag(fullUrl, cb);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user