diff options
| author | qsm-odoo <qsm@odoo.com> | 2019-03-29 11:13:05 +0000 |
|---|---|---|
| committer | qsm-odoo <qsm@odoo.com> | 2019-06-04 07:57:20 +0000 |
| commit | 02dab5dc88112fd5f5ee43882ca022529acb4abf (patch) | |
| tree | 050f2622037dd35e068ffaa43d596a4665faefc6 /addons | |
| parent | 4f750e705686617d48f73e93b87abeefb7fc87e2 (diff) | |
[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
Diffstat (limited to 'addons')
| -rw-r--r-- | addons/survey/views/survey_templates.xml | 2 | ||||
| -rw-r--r-- | addons/web/static/src/js/public/lazyloader.js | 42 | ||||
| -rw-r--r-- | addons/web/views/webclient_templates.xml | 48 | ||||
| -rw-r--r-- | addons/web_tour/static/src/js/public/tour_manager.js | 21 | ||||
| -rw-r--r-- | addons/web_tour/static/src/js/tour_manager.js | 30 | ||||
| -rw-r--r-- | addons/web_tour/static/src/js/tour_service.js | 30 | ||||
| -rw-r--r-- | addons/web_tour/views/tour_templates.xml | 6 | ||||
| -rw-r--r-- | addons/website/static/src/js/menu/customize.js | 5 | ||||
| -rw-r--r-- | addons/website/views/website_templates.xml | 2 |
9 files changed, 148 insertions, 38 deletions
diff --git a/addons/survey/views/survey_templates.xml b/addons/survey/views/survey_templates.xml index 834d148a95f..20426c852ca 100644 --- a/addons/survey/views/survey_templates.xml +++ b/addons/survey/views/survey_templates.xml @@ -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"/> diff --git a/addons/web/static/src/js/public/lazyloader.js b/addons/web/static/src/js/public/lazyloader.js new file mode 100644 index 00000000000..7c873e1938d --- /dev/null +++ b/addons/web/static/src/js/public/lazyloader.js @@ -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, +}; +}); diff --git a/addons/web/views/webclient_templates.xml b/addons/web/views/webclient_templates.xml index 1bcd6280dab..31a2e62ef53 100644 --- a/addons/web/views/webclient_templates.xml +++ b/addons/web/views/webclient_templates.xml @@ -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 ''}"> diff --git a/addons/web_tour/static/src/js/public/tour_manager.js b/addons/web_tour/static/src/js/public/tour_manager.js new file mode 100644 index 00000000000..a5b4c588833 --- /dev/null +++ b/addons/web_tour/static/src/js/public/tour_manager.js @@ -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); + }); + }); + }, +}); +}); diff --git a/addons/web_tour/static/src/js/tour_manager.js b/addons/web_tour/static/src/js/tour_manager.js index 18b2c47d6b3..fab05a7fb69 100644 --- a/addons/web_tour/static/src/js/tour_manager.js +++ b/addons/web_tour/static/src/js/tour_manager.js @@ -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"); diff --git a/addons/web_tour/static/src/js/tour_service.js b/addons/web_tour/static/src/js/tour_service.js index 92e8148a901..87cf69b7d83 100644 --- a/addons/web_tour/static/src/js/tour_service.js +++ b/addons/web_tour/static/src/js/tour_service.js @@ -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; }; })(); diff --git a/addons/web_tour/views/tour_templates.xml b/addons/web_tour/views/tour_templates.xml index 6830501ceeb..816405a39d5 100644 --- a/addons/web_tour/views/tour_templates.xml +++ b/addons/web_tour/views/tour_templates.xml @@ -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> diff --git a/addons/website/static/src/js/menu/customize.js b/addons/website/static/src/js/menu/customize.js index 00d2bef687b..4481d0f616c 100644 --- a/addons/website/static/src/js/menu/customize.js +++ b/addons/website/static/src/js/menu/customize.js @@ -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); diff --git a/addons/website/views/website_templates.xml b/addons/website/views/website_templates.xml index 9917615d803..8de35096b51 100644 --- a/addons/website/views/website_templates.xml +++ b/addons/website/views/website_templates.xml @@ -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"> |
