Commit 8677f05a authored by Romain Courteaud's avatar Romain Courteaud

Fetch JS dependencies in parallel.

Allow browser to fetch the JS files in parallel.
Loading should stay synchronous.
parent 098c272c
...@@ -125,7 +125,7 @@ ...@@ -125,7 +125,7 @@
var gadget_model_defer_dict = {}, var gadget_model_defer_dict = {},
javascript_registration_dict = {}, javascript_registration_dict = {},
stylesheet_registration_dict = {}, stylesheet_registration_dict = {},
gadget_loading_klass, gadget_loading_klass_list = [],
loading_klass_promise, loading_klass_promise,
renderJS, renderJS,
Monitor, Monitor,
...@@ -1006,7 +1006,7 @@ ...@@ -1006,7 +1006,7 @@
if (selector === window) { if (selector === window) {
// window is the 'this' value when loading a javascript file // window is the 'this' value when loading a javascript file
// In this case, use the current loading gadget constructor // In this case, use the current loading gadget constructor
result = gadget_loading_klass; result = gadget_loading_klass_list[0];
} }
if (result === undefined) { if (result === undefined) {
throw new Error("Unknown selector '" + selector + "'"); throw new Error("Unknown selector '" + selector + "'");
...@@ -1041,7 +1041,7 @@ ...@@ -1041,7 +1041,7 @@
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// renderJS.declareJS // renderJS.declareJS
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
renderJS.declareJS = function (url, container) { renderJS.declareJS = function (url, container, pop) {
// https://www.html5rocks.com/en/tutorials/speed/script-loading/ // https://www.html5rocks.com/en/tutorials/speed/script-loading/
// Prevent infinite recursion if loading render.js // Prevent infinite recursion if loading render.js
// more than once // more than once
...@@ -1049,16 +1049,24 @@ ...@@ -1049,16 +1049,24 @@
if (javascript_registration_dict.hasOwnProperty(url)) { if (javascript_registration_dict.hasOwnProperty(url)) {
result = RSVP.resolve(); result = RSVP.resolve();
} else { } else {
javascript_registration_dict[url] = null;
result = new RSVP.Promise(function (resolve, reject) { result = new RSVP.Promise(function (resolve, reject) {
var newScript; var newScript;
newScript = document.createElement('script'); newScript = document.createElement('script');
newScript.async = false; newScript.async = false;
newScript.type = 'text/javascript'; newScript.type = 'text/javascript';
newScript.onload = function () { newScript.onload = function () {
javascript_registration_dict[url] = null; if (pop === true) {
// Drop the current loading klass info used by selector
gadget_loading_klass_list.shift();
}
resolve(); resolve();
}; };
newScript.onerror = function (e) { newScript.onerror = function (e) {
if (pop === true) {
// Drop the current loading klass info used by selector
gadget_loading_klass_list.shift();
}
reject(e); reject(e);
}; };
newScript.src = url; newScript.src = url;
...@@ -1159,8 +1167,7 @@ ...@@ -1159,8 +1167,7 @@
} }
var tmp_constructor, var tmp_constructor,
defer = RSVP.defer(), defer = RSVP.defer();
previous_loading_klass_promise = loading_klass_promise;
gadget_model_defer_dict[url] = defer; gadget_model_defer_dict[url] = defer;
...@@ -1170,30 +1177,22 @@ ...@@ -1170,30 +1177,22 @@
// Fetch the HTML page and parse it // Fetch the HTML page and parse it
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
return RSVP.all([ return ajax(url);
ajax(url),
// Wait for previous gadget loading to finish first
new RSVP.Queue()
.push(function () {
return previous_loading_klass_promise;
})
.push(undefined, function () {
// Forget previous declareGadget error
return;
})
]);
}) })
.push(function (result_list) { .push(function (result) {
tmp_constructor = parse(result_list[0], url); tmp_constructor = parse(result, url);
gadget_loading_klass = tmp_constructor;
var fragment = document.createDocumentFragment(), var fragment = document.createDocumentFragment(),
promise_list = [], promise_list = [],
i, i,
js_list = tmp_constructor.prototype.__required_js_list, js_list = tmp_constructor.prototype.__required_js_list,
css_list = tmp_constructor.prototype.__required_css_list; css_list = tmp_constructor.prototype.__required_css_list;
// Load JS // Load JS
for (i = 0; i < js_list.length; i += 1) { if (js_list.length) {
promise_list.push(renderJS.declareJS(js_list[i], fragment)); gadget_loading_klass_list.push(tmp_constructor);
for (i = 0; i < js_list.length - 1; i += 1) {
promise_list.push(renderJS.declareJS(js_list[i], fragment));
}
promise_list.push(renderJS.declareJS(js_list[i], fragment, true));
} }
// Load CSS // Load CSS
for (i = 0; i < css_list.length; i += 1) { for (i = 0; i < css_list.length; i += 1) {
...@@ -1204,15 +1203,12 @@ ...@@ -1204,15 +1203,12 @@
}) })
.push(function () { .push(function () {
defer.resolve(tmp_constructor); defer.resolve(tmp_constructor);
// Drop the current loading klass info used by selector
gadget_loading_klass = undefined;
return tmp_constructor; return tmp_constructor;
}) })
.push(undefined, function (e) { .push(undefined, function (e) {
// Drop the current loading klass info used by selector // Drop the current loading klass info used by selector
// even in case of error // even in case of error
defer.reject(e); defer.reject(e);
gadget_loading_klass = undefined;
throw e; throw e;
}); });
}; };
...@@ -1492,7 +1488,7 @@ ...@@ -1492,7 +1488,7 @@
} }
TmpConstructor.prototype.__acquired_method_dict = {}; TmpConstructor.prototype.__acquired_method_dict = {};
gadget_loading_klass = TmpConstructor; gadget_loading_klass_list.push(TmpConstructor);
function init() { function init() {
// XXX HTML properties can only be set when the DOM is fully loaded // XXX HTML properties can only be set when the DOM is fully loaded
...@@ -1526,7 +1522,7 @@ ...@@ -1526,7 +1522,7 @@
for (i = 0; i < css_list.length; i += 1) { for (i = 0; i < css_list.length; i += 1) {
stylesheet_registration_dict[css_list[i]] = null; stylesheet_registration_dict[css_list[i]] = null;
} }
gadget_loading_klass = undefined; gadget_loading_klass_list.shift();
}).then(function () { }).then(function () {
// select the target node // select the target node
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment