在我的混合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
这是可行的,但是显示新图像的过程很慢。我怀疑是因为上面的innerHTML分配。通过createElementNS
,puzzle.àppendChild
的序列重新创建将需要我首先解析传入的原始SVG内容等。这是一种解决方法,还是有一种显示内容的更快方法。
再次为清楚起见-SVG是新的SVG图像的内容,将在其外部<svg>...</svg>
包装盒中显示。
答案 0 :(得分:0)
请注意,出于一致性目的,使用setAttributeNS
代替setAttribute
可能会更好,因为使用了createElementNS
,尽管这可能不会加快速度。 SVG图像更改。
对于本机应用程序,可以使用Android Profiler之类的工具(如果使用的是Android Studio 3.0及更高版本)来分析性能瓶颈。但是,由于您的应用程序是混合应用程序,因此某种适用于混合应用程序的性能分析器(无论是Ionic还是Cordova等)都可以帮助您确定性能瓶颈在哪里。
由于您的应用是混合应用,因此不知道您的Android应用会话的资源容量,因此猜测可能是因为它在更改期间调用了诸如.setAttribute之类的内容来动态设置会话级属性的可能原因图像和会话资源的数量可能不够,DOM也必须执行.innerHTML和appendChild,它们是动态操作。众所周知,DOM操作很慢。
转换所有SVG的属性并将结果存储在某种存储或高速缓存中,并且在需要时从持久性存储或高速缓存中调用它可能会有所帮助。
或者考虑使用AngularJS预先进行SVG更改并预加载SVG图像,请参阅easily preload images in your Angular app。 Here与您的代码相似,只是它使用AngularJS为入门者添加SVG。
如果可以事先减少传入的SVG,另一种更简单的方法是使用SVG Optimizer或node.js开源项目SVGO压缩您的SVG,而无需更改代码。引用SVGO链接时说:
“ SVG文件,尤其是从各种编辑器导出的文件,通常包含许多冗余和无用的信息。其中包括编辑器元数据,注释,隐藏的元素,默认值或非最佳值以及可以安全删除或删除的其他内容转换而不会影响SVG渲染结果。”尽管在这种情况下性能提升可能并不明显。