From f95af92ae3bc6bd7d7d4a9e09042bcca9f35ffec Mon Sep 17 00:00:00 2001 From: Romain Derie Date: Fri, 13 Mar 2020 15:16:04 +0000 Subject: [PATCH 01/12] [FIX] website: perf - prefetch every website menus in one go Without this commit, the website menus would not be prefetch all in once. Thus, every call to `submenu` template (called recursively) would do SQL queries. One when accessing website.menu_id, then for every access on menu's child_ids. It would also make an extra request for groups since the menus have an ir.rule for that. with following structure, 13 SQL queries will be avoided, regardless if there is a group or not on the menus: - Top menu - Home - Contact us - Sub Contact us - Sub Sub Contact us Related to #47257 task-2211013 X-original-commit: 7fb016f9966bb5e2289ba17eacafb8887626514e --- addons/website/models/website.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/addons/website/models/website.py b/addons/website/models/website.py index c8dd03d8107..270a6199c95 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -133,9 +133,18 @@ class Website(models.Model): self.default_lang_id = language_ids[0] def _compute_menu(self): - Menu = self.env['website.menu'] for website in self: - website.menu_id = Menu.search([('parent_id', '=', False), ('website_id', '=', website.id)], order='id', limit=1).id + menus = self.env['website.menu'].search([('website_id', '=', website.id)]) + + # use field parent_id (1 query) to determine field child_id (2 queries by level)" + for menu in menus: + menu._cache['child_id'] = () + for menu in menus: + # don't add child menu if parent is forbidden + if menu.parent_id and menu.parent_id in menus: + menu.parent_id._cache['child_id'] += (menu.id,) + + website.menu_id = menus and menus.filtered(lambda m: not m.parent_id)[0].id or False @api.model def create(self, vals): From 1d981f22f36b748c4c7b548e9db33284e7eefc6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Theys?= Date: Fri, 13 Mar 2020 15:16:10 +0000 Subject: [PATCH 02/12] [FIX] website: perf - prefetch website.menu's mega_menu_content Since this field is not sanitized, it is safe (perf wise) to prefetch it. It should not be CPU heavy, plus whenever we access a `website.menu`, it is most likely we will read that field. with following structure, 5 SQL queries will be avoided: - Top menu - Home - Contact us - Sub Contact us - Sub Sub Contact us Related to #47257 task-2211013 X-original-commit: 20cddcd899e7a119fa9f365e62527499f8e5ff7d --- addons/website/models/website_menu.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/website/models/website_menu.py b/addons/website/models/website_menu.py index 1eaa513fb4d..bed9fb8cf26 100644 --- a/addons/website/models/website_menu.py +++ b/addons/website/models/website_menu.py @@ -44,7 +44,7 @@ class Menu(models.Model): group_ids = fields.Many2many('res.groups', string='Visible Groups', help="User need to be at least in one of these groups to see the menu") is_mega_menu = fields.Boolean(compute=_compute_field_is_mega_menu, inverse=_set_field_is_mega_menu) - mega_menu_content = fields.Html(translate=html_translate, sanitize=False) + mega_menu_content = fields.Html(translate=html_translate, sanitize=False, prefetch=True) mega_menu_classes = fields.Char() def name_get(self): From 30f24d1ca7d467dd3194eb75c44ba20a56f36f7f Mon Sep 17 00:00:00 2001 From: Jeremy Kersten Date: Fri, 13 Mar 2020 15:16:15 +0000 Subject: [PATCH 03/12] [FIX] website: perf - don't search backend menu if you will not see it Before this commit, in all cases, we search the backend menu to open if you click on edit backend menu. But the backend menu edit is useless for non editor user. This feature has been introduce in v13, since eLearning have his own apps, so when you edit in backend, you want to see the slide form view, into the elearning app and no website App. Related to #47257 task-2211013 X-original-commit: 1da7e53f4cdd82574688eb62f7a1cb8ddca871e6 --- addons/website/models/ir_ui_view.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/website/models/ir_ui_view.py b/addons/website/models/ir_ui_view.py index c2eb62acfb5..8a20ecc7f25 100644 --- a/addons/website/models/ir_ui_view.py +++ b/addons/website/models/ir_ui_view.py @@ -384,8 +384,9 @@ class View(models.Model): elif request.env.user.has_group('website.group_website_publisher'): new_context = dict(self._context, inherit_branding_auto=True) if values and 'main_object' in values: - func = getattr(values['main_object'], 'get_backend_menu_id', False) - values['backend_menu_id'] = func and func() or self.env.ref('website.menu_website_configuration').id + if request.env.user.has_group('website.group_website_publisher'): + func = getattr(values['main_object'], 'get_backend_menu_id', False) + values['backend_menu_id'] = func and func() or self.env.ref('website.menu_website_configuration').id # Fallback incase main_object dont't inherit 'website.seo.metadata' if not hasattr(values['main_object'], 'get_website_meta'): From 51c9599b79cfef7d1299b8c774b9e28917923509 Mon Sep 17 00:00:00 2001 From: Jeremy Kersten Date: Fri, 13 Mar 2020 15:16:20 +0000 Subject: [PATCH 04/12] [FIX] website: perf - use lang cached to check if rtl or not Before this commit, on each rendering of frontend layout, we make a new request to check if env lang was in rtl or ltr. Now we use a cached method, that have more than probably already cached this record. Related to #47257 task-2211013 X-original-commit: 7566b06500e42593919631cc6fa180aececfc623 --- addons/portal/views/portal_templates.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/portal/views/portal_templates.xml b/addons/portal/views/portal_templates.xml index 40b595518ed..a784e1def09 100644 --- a/addons/portal/views/portal_templates.xml +++ b/addons/portal/views/portal_templates.xml @@ -2,7 +2,7 @@