Google Chrome 是否缓存渲染的 SVG?如果不是,我们应该如何针对 Chrome 渲染优化 SVG?

Does Google Chrome cache rendered SVGs? If not, how should we optimize SVGs for Chrome rendering?

问题

live site is here,在Webflow中创建。当您将鼠标悬停在菜单项上时,background-img 会发生变化,将其他背景设置为 0% 不透明度并将此背景设置为 100% 不透明度。我的问题是第一个 SVG(标题为“390 KB SVG”),它有大约 1,000 个元素。

在 Firefox、Edge 和 Internet Explorer 中,这个相对较大的 SVG 渲染一次,然后缓存以便每次立即显示。 在Chrome中,每次悬停事件re-rendered强制使用相同的 SVG,每次耗时在 150 毫秒 (i5-8600K) 和 600 毫秒 (i5-6200U) 之间.

我们能否以某种方式在 Chrome 中启用 rendered-SVG 缓存?或者提高 SVG 整体渲染性能? 较小的 SVG 在 Chrome 中渲染速度足够快。

我已经尝试过的

SVG 是从 Adob​​e Illustrator CC 2019 导出的 2500px x 1250px、1 精度 SVG。Adobe Illustrator 的原始输出为 762 KB。我已经将有问题的 762 KB SVG 优化为 390 KB:

  1. 增加画板大小后将精度降低为 1 as described here

  2. Used SVGOMG 删除几乎所有元数据。

  3. Used Vecta.IO's SVG Nano tool 进一步缩小和压缩。

  4. Used SVGito 到 re-use 相同的路径。

虽然它肯定比初始输出渲染得更快,但在较慢的系统上渲染仍然需要 ~500+ 毫秒。

我也尝试过其他方法来更改背景,例如显示:none 或者,不是通过 0% 不透明度隐藏背景,而是只使用 1% 不透明度:bt 即使是 1%,Chrome 需要 re-render 才能将不透明度从 1% 提高到 100%。

SVG 代码及其调用方式

SVG 的代码可以在这里查看:https://codepen.io/TG2-/pen/EBXEGO

SVG 是通过 Javascript 调用的,就像这样,使用 Webflow's built-in JavaScript(称为 "Interactions IX2"):

            }, {
                "id": "a-11-n-7",
                "actionTypeId": "STYLE_OPACITY",
                "config": {
                    "delay": 0,
                    "easing": "",
                    "duration": 0,
                    "target": {
                        "id": "92202c53-63db-1dc1-831b-53546fc80f59"
                    },
                    "value": 0,
                    "unit": ""
                }
            }, {
                "id": "a-11-n-8",
                "actionTypeId": "STYLE_OPACITY",
                "config": {
                    "delay": 0,
                    "easing": "",
                    "duration": 0,
                    "target": {
                        "id": "92202c53-63db-1dc1-831b-53546fc80f60"
                    },
                    "value": 1,
                    "unit": ""
                }
            }]

预期结果:

1) 将鼠标悬停到第一个菜单项(“390 KB SVG”)应该会在 Chrome

中相对立即(最好在 50 毫秒以下)更改背景图像

(*要么像其他浏览器一样通过缓存渲染的 SVG,要么通过提高 Chrome 中的渲染性能)

实际结果:

1) 将鼠标悬停到第一个菜单项(“390 KB SVG”)会在 200 毫秒到 600 毫秒后更改背景图像,具体取决于用户 CPU.

的速度

解决方案(感谢 Kaiido 和 Paul LeBeua)

将 SVG 图案更改为 SVG 填充。这是 old SVG,使用模式:

<style>
        <![CDATA[.B {
            fill: url(#C)
        }

        .C {
            fill: url(#B)
        }

        .D {
            fill: url(#A)
        }

        .E {
            fill: url(#E)
        }

        .F {
            fill: url(#D)
        }

        ]]>
    </style>
    <defs>
        <pattern id="A" width="3" height="3" patternTransform="matrix(50 0 0 50 -892 -730.5)" patternUnits="userSpaceOnUse">
            <path fill="#7c26cc" d="M0 0h3v3H0z" />
        </pattern>
        <pattern id="B" width="3" height="3" patternTransform="matrix(50 0 0 50 -892 -730.5)" patternUnits="userSpaceOnUse">
            <path fill="#b45ffe" d="M0 0h3v3H0z" />
        </pattern>
        <pattern id="C" width="3" height="3" patternTransform="matrix(50 0 0 50 -892 -730.5)" patternUnits="userSpaceOnUse">
            <path fill="#b9b9b9" d="M0 0h3v3H0z" />
        </pattern>
        <pattern id="D" width="3" height="3" patternTransform="matrix(50 0 0 50 -892 -730.5)" patternUnits="userSpaceOnUse">
            <path fill="#e1e1e1" d="M0 0h3v3H0z" />
        </pattern>
        <pattern id="E" width="3" height="3" patternTransform="matrix(50 0 0 50 -892 -730.5)" patternUnits="userSpaceOnUse">
            <path fill="#e3d3ed" d="M0 0h3v3H0z" />
        </pattern>

这是新的 SVG,使用填充:

<style><![CDATA[.B {
    fill: #b9b9b9
}

.C {
    fill: #b45ffe
}

.D {
    fill: #7c26cc
}

.E {
    fill: #e3d3ed
}

.F {
    fill: #e1e1e1
}

]]></style>

@Kaiido 的直觉似乎是正确的。它似乎确实与该 SVG 中 <pattern> 元素的使用有关。如果您将该 SVG 中的 CSS 更改为直接使用颜色,则 SVG 的渲染速度会快得多。

例如:您只需将图案中的颜色复制到关联的样式即可:

.A { fill: #7c26cc; }

等等

这里使用模式没有任何意义。