[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:
@@ -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,
|
||||
};
|
||||
});
|
||||
@@ -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"><!DOCTYPE html>
|
||||
<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);
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
});
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
})();
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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">
|
||||
|
||||
Reference in New Issue
Block a user