[IMP] website, *: lazy load most frontend javascript

* web, survey

This commit takes advantage of the other commits of this PR to enable
lazy loading for most frontend javascript:

1) Extract the minimum part of the assets common:
- promises library and polyfill
- boot.js

2) Create "assets_common_lazy" which is "assets_common" - "minimum"

3) Include the "minimum" assets in frontend layouts using "defer"
   loading and "assets_common_lazy" using "lazy" loading

4) Create a script to do the actual lazy loading in a "minimum" frontend
   assets

5) Lazy load the current frontend / website editor assets

Part of https://github.com/odoo/odoo/pull/32181
task-1961045
This commit is contained in:
qsm-odoo
2019-06-04 07:57:20 +00:00
parent 4f750e7056
commit 02dab5dc88
9 changed files with 148 additions and 38 deletions
+1 -1
View File
@@ -134,7 +134,7 @@
<!-- new layout for survey -->
<template id="survey.layout" name="Survey Layout" inherit_id="web.frontend_layout" primary="True">
<xpath expr="//head/t[@t-call-assets][last()]" position="after">
<t t-call-assets="survey.survey_assets"/>
<t t-call-assets="survey.survey_assets" lazy_load="True"/>
</xpath>
<xpath expr="//header" position="before">
<t t-set="no_header" t-value="no_header or survey.certificate"/>
@@ -0,0 +1,42 @@
odoo.define('web.public.lazyloader', function (require) {
'use strict';
var doResolve = null;
var _allScriptsLoaded = new Promise(function (resolve) {
if (doResolve) {
resolve();
} else {
doResolve = resolve;
}
});
window.addEventListener('load', function () {
setTimeout(_loadScripts, 0);
});
function _loadScripts(scripts, index) {
if (scripts === undefined) {
scripts = document.querySelectorAll('script[data-src]');
}
if (index === undefined) {
index = 0;
}
if (index >= scripts.length) {
if (typeof doResolve === 'function') {
doResolve();
} else {
doResolve = true;
}
return;
}
var script = scripts[index];
script.addEventListener('load', _loadScripts.bind(this, scripts, index + 1));
script.src = script.dataset.src;
script.removeAttribute('data-src');
}
return {
loadScripts: _loadScripts,
allScriptsLoaded: _allScriptsLoaded,
};
});
+39 -9
View File
@@ -40,6 +40,20 @@
<link rel="stylesheet" type="text/scss" href="/web/static/src/scss/bootstrap_review.scss"/>
</template>
<!-- The assets common minimal code should not require any library to work. -->
<!-- An exception is made for the promises polyfill and extensions that the -->
<!-- boot.js script needs to work -->
<template id="_assets_common_minimal_js">
<script type="text/javascript" src="/web/static/lib/es6-promise/es6-promise-polyfill.js"></script>
<script type="text/javascript" src="/web/static/lib/unhandled-rejection-polyfill/unhandled-rejection-polyfill.js"></script>
<script type="text/javascript" src="/web/static/src/js/promise_extension.js"></script>
<script type="text/javascript" src="/web/static/src/js/boot.js"></script>
</template>
<template id="assets_common_minimal_js">
<t t-call="web._assets_common_minimal_js"/>
</template>
<template id="assets_common" name="Common Assets (used in backend interface and website)">
<t t-call="web._assets_helpers"/>
@@ -65,8 +79,8 @@
<link rel="stylesheet" type="text/less" href="/web/static/src/scss/fontawesome_overriden.scss"/>
<script type="text/javascript" src="/web/static/lib/es6-promise/es6-promise-polyfill.js"></script>
<script type="text/javascript" src="/web/static/lib/unhandled-rejection-polyfill/unhandled-rejection-polyfill.js"></script>
<t t-call="web._assets_common_minimal_js"/>
<script type="text/javascript" src="/web/static/lib/underscore/underscore.js"></script>
<script type="text/javascript" src="/web/static/lib/underscore.string/lib/underscore.string.js"></script>
<script type="text/javascript" src="/web/static/lib/moment/moment.js"></script>
@@ -103,10 +117,6 @@
<script type="text/javascript" src="/web/static/lib/jSignature/jSignatureCustom.js"></script>
<script type="text/javascript" src="/web/static/lib/qweb/qweb2.js"></script>
<script type="text/javascript" src="/web/static/src/js/promise_extension.js"></script>
<script type="text/javascript" src="/web/static/src/js/boot.js"></script>
<script type="text/javascript" src="/web/static/src/js/libs/autocomplete.js"></script>
<script type="text/javascript" src="/web/static/src/js/libs/bootstrap.js"></script>
<script type="text/javascript" src="/web/static/src/js/libs/jquery.js"></script>
@@ -149,6 +159,10 @@
<script type="text/javascript" src="/web/static/src/js/widgets/rainbow_man.js"></script>
</template>
<template id="assets_common_lazy" inherit_id="web.assets_common" primary="True">
<xpath expr="//t[@t-call='web._assets_common_minimal_js']" position="replace"/>
</template>
<template id="assets_backend" name="Backend Assets (used in backend interface)">
<t t-call="web._assets_helpers">
<t t-call="web._assets_backend_helpers"/>
@@ -342,7 +356,15 @@
<link rel="stylesheet" type="text/scss" href="/web/static/src/scss/report_backend.scss"/>
</template>
<template id="web.assets_frontend" name="Website Assets">
<template id="_assets_frontend_minimal_js">
<script type="text/javascript" src="/web/static/src/js/public/lazyloader.js"/>
</template>
<template id="assets_frontend_minimal_js">
<t t-call="web._assets_frontend_minimal_js"/>
</template>
<template id="assets_frontend" name="Website Assets">
<t t-call="web._assets_helpers">
<t t-call="web._assets_frontend_helpers"/>
</t>
@@ -351,6 +373,8 @@
<link rel="stylesheet" type="text/scss" href="/web/static/src/scss/navbar_mobile.scss"/>
<link rel="stylesheet" type="text/scss" href="/web/static/src/scss/notification.scss"/>
<t t-call="web._assets_frontend_minimal_js"/>
<script type="text/javascript" src="/web/static/src/js/services/session.js"/>
<script type="text/javascript" src="/web/static/src/js/public/public_notification.js"/>
<script type="text/javascript" src="/web/static/src/js/public/public_root.js"/>
@@ -358,6 +382,10 @@
<script type="text/javascript" src="/web/static/src/js/public/public_widget.js"/>
</template>
<template id="assets_frontend_lazy" inherit_id="web.assets_frontend" primary="True">
<xpath expr="//t[@t-call='web._assets_frontend_minimal_js']" position="replace"/>
</template>
<template id="web.layout" name="Web layout">&lt;!DOCTYPE html&gt;
<html t-att="html_data or {}">
<head>
@@ -391,8 +419,10 @@
<script type="text/javascript">
odoo.session_info = <t t-raw="json.dumps(request.env['ir.http'].get_frontend_session_info())"/>;
</script>
<t t-call-assets="web.assets_common" t-css="false"/>
<t t-call-assets="web.assets_frontend" t-css="false"/>
<t t-call-assets="web.assets_common_minimal_js" t-css="false" defer_load="True"/>
<t t-call-assets="web.assets_frontend_minimal_js" t-css="false" defer_load="True"/>
<t t-call-assets="web.assets_common_lazy" t-css="false" lazy_load="True"/>
<t t-call-assets="web.assets_frontend_lazy" t-css="false" lazy_load="True"/>
</xpath>
<xpath expr="//t[@t-raw='0']" position="replace">
<div id="wrapwrap" t-attf-class="#{pageName or ''}">
@@ -0,0 +1,21 @@
odoo.define('web_tour.public.TourManager', function (require) {
'use strict';
var TourManager = require('web_tour.TourManager');
var lazyloader = require('web.public.lazyloader');
TourManager.include({
/**
* @override
*/
_waitBeforeTourStart: function () {
return this._super.apply(this, arguments).then(function () {
return lazyloader.allScriptsLoaded;
}).then(function () {
return new Promise(function (resolve) {
setTimeout(resolve);
});
});
},
});
});
+25 -5
View File
@@ -81,11 +81,32 @@ return core.Class.extend(mixins.EventDispatcherMixin, ServicesMixin, {
}
this.tours[name] = tour;
},
/**
* Returns a promise which is resolved once the tour can be started. This
* is when the DOM is ready and at the end of the execution stack so that
* all tours have potentially been extended by all apps.
*
* @private
* @returns {Promise}
*/
_waitBeforeTourStart: function () {
return new Promise(function (resolve) {
$(function () {
setTimeout(resolve);
});
});
},
_register_all: function (do_update) {
if (this._all_registered) return;
this._all_registered = true;
_.each(this.tours, this._register.bind(this, do_update));
var self = this;
if (this._allRegistered) {
return Promise.resolve();
}
this._allRegistered = true;
return self._waitBeforeTourStart().then(function () {
return Promise.all(_.map(self.tours, function (tour, name) {
return self._register(do_update, tour, name);
}));
});
},
_register: function (do_update, tour, name) {
if (tour.ready) return Promise.resolve();
@@ -193,7 +214,6 @@ return core.Class.extend(mixins.EventDispatcherMixin, ServicesMixin, {
* @returns {boolean} true if a tip was found and activated/updated
*/
_check_for_tooltip: function (tip, tour_name) {
if ($('body').hasClass('o_ui_blocked')) {
this._deactivate_tip(tip);
this._log.push("blockUI is preventing the tip to be consumed");
+10 -20
View File
@@ -56,29 +56,19 @@ return session.is_bound.then(function () {
}, 500);
var observer = new MutationObserver(check_tooltip);
var start_service = (function () {
return function (observe) {
var promise = new Promise(function (resolve, reject) {
$(function () {
/**
* Once the DOM is ready, we still have to wait all the modules are loaded before completing the tours
* registration and starting listening for DOM mutations.
*/
_.defer(function () {
tour_manager._register_all(observe);
if (observe) {
observer.observe(document.body, {
attributes: true,
childList: true,
subtree: true,
});
}
resolve();
});
return new Promise(function (resolve, reject) {
tour_manager._register_all(observe).then(function () {
if (observe) {
observer.observe(document.body, {
attributes: true,
childList: true,
subtree: true,
});
}
resolve();
});
});
return promise;
};
})();
+6
View File
@@ -18,5 +18,11 @@
<script type="text/javascript" src="/web_tour/static/src/js/debug_manager.js"></script>
</xpath>
</template>
<template id="assets_frontend" inherit_id="web.assets_frontend">
<xpath expr="//script[last()]" position="after">
<script type="text/javascript" src="/web_tour/static/src/js/public/tour_manager.js"/>
</xpath>
</template>
</data>
</odoo>
@@ -199,8 +199,9 @@ var AceEditorMenu = websiteNavbarData.WebsiteNavbarActionWidget.extend({
self.globalEditor = new WebsiteAceEditor(self, $(document.documentElement).data('view-xmlid'), {
initialResID: initialResID,
defaultBundlesRestriction: [
"web.assets_frontend",
"website.assets_frontend",
'web.assets_frontend',
'web.assets_frontend_minimal',
'web.assets_frontend_lazy',
],
});
return self.globalEditor.appendTo(document.body);
+1 -1
View File
@@ -230,7 +230,7 @@
<t t-call-assets="website.assets_editor" t-js="false" groups="website.group_website_publisher"/>
</xpath>
<xpath expr="//head/t[@t-css='false'][last()]" position="after">
<t t-call-assets="website.assets_editor" t-css="false" groups="website.group_website_publisher"/>
<t t-call-assets="website.assets_editor" t-css="false" groups="website.group_website_publisher" lazy_load="True"/>
</xpath>
<xpath expr="//header//a[hasclass('navbar-brand')]" position="replace">