如何加快内联 SVG 更改



在我的混合Android应用程序中,我使用内联SVG来显示大型(2Mb量级)和复杂(每张图像数百个SVG元素)的图像。 当我需要更改图像时,我会执行以下操作

var puzzle = document.createElementNS(SVGNS,'svg'),
kutu = document.getElementById('kutu');   

puzzle.id = 'puzzle';
puzzle.setAttribute('preserveAspectRatio','none');
puzzle.setAttribute('width','100vw');
puzzle.setAttribute('height','85.5vh');
puzzle.setAttribute('xmlns',SVGNS);
puzzle.setAttribute('xmlns:xlink',XLINK);
puzzle.setAttribute('fill-rule','evenodd');
puzzle.setAttribute('clip-rule','evenodd');
puzzle.setAttribute('stroke-linejoin','round');
puzzle.setAttribute('stroke-miterlimit','1.414');
puzzle.setAttribute('viewBox','0 0 1600 770');
puzzle.innerHTML = SVG;
//SVG here is the SVG image content shorn off the outer <svg>..</svg>
if (0 < kutu.children.length) kutu.children[0].remove();
//remove old image, iff any
kutu.appendChild(puzzle);
//append the new image

虽然这正在工作,但显示新图像的过程很慢。 我怀疑这是因为上面的内部HTML赋值。 通过一系列createElementNS重新创建,puzzle.àppendChild需要我首先解析传入的原始SVG内容等。 这是要走的路还是有更快的方法来显示内容。

再次为清楚起见 - SVG 这里是要显示的新 SVG 图像的内容,其外部<svg>...</svg>wrrapper。

只是附带说明一下,出于一致性目的,最好使用setAttributeNS代替setAttribute,因为使用了createElementNS,尽管它可能对加速 SVG 图像更改没有影响。

对于本机应用程序,如果使用Android Studio 3.0及更高版本,则可以使用Android Profiler之类的工具来分析性能瓶颈。但是,由于你的应用是混合应用,因此适用于混合应用的某种性能探查器(无论是 Ionic 还是 Cordova 等)可以帮助查明性能瓶颈所在。

由于您的应用程序是混合的,在不知道您的 android 应用程序会话的资源容量的情况下,猜测它似乎是一个可能的原因,它调用类似 .setAttribute 的东西来在图像更改期间动态设置会话级属性,会话资源可能不够,而且 DOM 必须执行 .innerHTML 和 appendChild, 这是动态操作。众所周知,DOM 操作很慢。

转换所有 SVG 的属性并将结果存储在某种存储或缓存中,并在需要时从持久存储或缓存调用它可能会有所帮助。

或者考虑使用 AngularJS 事先进行 SVG 更改并预加载 SVG 图像,请参阅在 Angular 应用程序中轻松预加载图像。这是另一个与您的代码类似的代码,除了它使用 AngularJS 为初学者添加 SVG。

另一种更简单的方法是,无需更改代码,如果可以事先缩小传入的 SVG,则使用 SVG 优化器或 SVGO(一个节点.js开源项目来压缩您的 SVG。 引用自 SVGO 链接,它说:

"SVG文件,尤其是从各种编辑器导出的文件,通常包含大量冗余和无用的信息。这可能包括编辑器元数据、注释、隐藏元素、默认值或非最佳值以及其他可以安全删除或转换的内容,而不会影响 SVG 渲染结果。尽管走这条路的性能提升可能并不明显。

最新更新