From ce3f689b2f6f6138a5e52b875a4b31362e9ba079 Mon Sep 17 00:00:00 2001 From: "Arthur Detroux (ard)" Date: Thu, 2 Mar 2023 09:22:34 +0000 Subject: [PATCH] [FIX] web_editor: improve perfs of background animations on Chrome Prior to this commit, animations on SVG shapes could use a lot of CPU and make the page stutter on some website + machine combo. This does not seem to be an "Odoo Only" issue as browsers seem to struggle to optimise SVG movements and end up consuming a decent amount of CPU depending on the machine, the size of the SVG and its position (behind or on top of other elements). This commit applies a new class which will warn the browser that the element is animated. Depending on the browser, some optimisations are done. On Chrome and Safari, a new layer is created which simplifies the rendering of the page and sometimes takes advantage of hardware acceleration. On Firefox, no optimisation is done yet. This might change in an update which would take advantage of the CSS Property. The documentation says to only use `will-change` when an element is about to change. This is the case however, as most of the shape's animations are looping. Which is why it's applied to every shape that is animated. This optimisation only applies to background shapes with this commit. Performance improvements observed by (at)rdeodoo on his machine: - SVG: 200% CPU - SVG + fix (will-change): 55% CPU (additional infos available in the PR) To note: one way to easily see the improvement is on the "Layers" tab of the Chrome devtools. Before this commit, the entire #wrapwrap is repainted every time the shape changes (so 60 times per second since that is the framerate the browser aims for). With this commit, the #wrapwrap and the shape are contained in their own layers so the #wrapwrap is only painted once. Other solutions were considered but not used at this time: - Reducing the frame rate of the animations. This is not currently possible because browsers do not offer any way of doing that. - Removing bits of the shape can reduce its CPU consumption, but whenever a transform animation is present, the CPU usage remains high. task-3142001 closes odoo/odoo#114252 X-original-commit: 03418be1c67e71a22f6d2ce79675280f889b663c Signed-off-by: Benoit Socias (bso) --- .../static/src/js/editor/snippets.options.js | 11 +++++++++-- .../web_editor/static/src/scss/web_editor.common.scss | 4 ++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/addons/web_editor/static/src/js/editor/snippets.options.js b/addons/web_editor/static/src/js/editor/snippets.options.js index fd92343e147..10b69817aa2 100644 --- a/addons/web_editor/static/src/js/editor/snippets.options.js +++ b/addons/web_editor/static/src/js/editor/snippets.options.js @@ -6833,7 +6833,12 @@ registry.BackgroundShape = SnippetOptionWidget.extend({ */ shape(previewMode, widgetValue, params) { this._handlePreviewState(previewMode, () => { - return {shape: widgetValue, colors: this._getImplicitColors(widgetValue, this._getShapeData().colors), flip: []}; + return { + shape: widgetValue, + colors: this._getImplicitColors(widgetValue, this._getShapeData().colors), + flip: [], + animated: params.animated, + }; }); }, /** @@ -7015,7 +7020,7 @@ registry.BackgroundShape = SnippetOptionWidget.extend({ // Updates/removes the shape container as needed and gives it the // correct background shape const json = target.dataset.oeShapeData; - const {shape, colors, flip = []} = json ? JSON.parse(json) : {}; + const {shape, colors, flip = [], animated = 'false'} = json ? JSON.parse(json) : {}; let shapeContainer = target.querySelector(':scope > .o_we_shape'); if (!shape) { return this._insertShapeContainer(null); @@ -7027,6 +7032,8 @@ registry.BackgroundShape = SnippetOptionWidget.extend({ // Compat: remove old flip classes as flipping is now done inside the svg shapeContainer.classList.remove('o_we_flip_x', 'o_we_flip_y'); + shapeContainer.classList.toggle('o_we_animated', animated === 'true'); + if (colors || flip.length) { // Custom colors/flip, overwrite shape that is set by the class $(shapeContainer).css('background-image', `url("${this._getShapeSrc()}")`); diff --git a/addons/web_editor/static/src/scss/web_editor.common.scss b/addons/web_editor/static/src/scss/web_editor.common.scss index 8a2b4a924a5..949a217c063 100644 --- a/addons/web_editor/static/src/scss/web_editor.common.scss +++ b/addons/web_editor/static/src/scss/web_editor.common.scss @@ -976,6 +976,10 @@ section, .oe_img_bg, [data-oe-shape-data] { .o_we_shape { @extend %o-we-background-layer; + &.o_we_animated { + will-change: transform; + } + // Default map to use to map shape file colors to color combination // background colors. $default-color-to-cc-bg-map: (