渲染繁重的SVG文件(提高性能)

时间:2017-10-06 09:26:15

标签: javascript reactjs svg react-native

在我们公司,我们希望提出通用解决方案来创建作为移动应用程序的交互式演示文稿。第一个想法是创建一个PDF文件并在手机中使用它,它没有成功 - 它太慢了。另一个想法是将PDF转换为SVG并将其用作场景(幻灯片)以及我现在正在处理的内容。我忘了提到,PDF包含内部链接注释以在页面之间导航。

因此,对于PDF到SVG转换,我使用pdf2svg cli工具。我还编写了PHP cli应用程序来解析PDF中的所有链接及其位置。对于概念,我首先使用ReactJS在WEB上测试这个想法(我之前从未使用过React Native)。

现在的问题是:PDF包含大量高分辨率图像和大量页面,因此一些SVG文件非常大(最大11MB),所有SVG的大小约为70MB。渲染这些大型SVG文件时,存在延迟(约1-10秒),与PDF文件相比,这不是一个巨大的胜利,因此我需要优化加载时间。

到目前为止我尝试过:

  1. 通过前面提到的PHP CLI实用程序,我写了一些关于SVG文件(<rect x="..." y="..." width="..." height="..." data-target-page="..." opacity="0"/>)内部链接的数据。然后我通过在<object data="..."/>状态内包含页码来呈现SVG,并在每个渲染中为SVG内的onClick标签创建<rect>事件监听器以进行导航。嗯,这是第一次尝试,我对表现并不满意。

  2. 我尝试使用react-svg-loader将SVG作为组件注入。它没有成功,性能更差(好吧,将70MB SVG转换为JSX组件听起来并不好)。顺便说一下,我试图建立生产项目,花了这么长时间我才等不及了。所以,不是一个选择。

  3. 我尝试使用分辨率较小的PNG图像(每个PNG大约为800kb)而不是SVG,并将链接作为div元素放在图像上,性能非常好,但是我失去了质量。所以不是一个选择。

  4. 与3相同,但使用SVG和<img src="..."/>。我认为它稍微好一点,但仍然不是一场胜利。

  5. 您是否有任何建议仍然可以通过使用SVG来提高性能?它应该在React Native中表现更好还是更差?

1 个答案:

答案 0 :(得分:1)

我认为问题的主要部分是:pdf2svg将所有光栅图像嵌入到SVG内的base64-encoded ASCII strings。转换和渲染它们似乎比加载和渲染在外部PNG或JPEG文件中引用和存储的图像花费更多的时间。

遗憾的是,我不知道一种CLI工具,在导入PDF时,可以将嵌入的光栅图像拆分为额外的文件。但GUI SVG编辑器Inkscape可以:使用Inkscape打开PDF文件,弹出一个对话框,询问您不仅要选择哪个页面,还要显示一个选项&#34;嵌入所有图像&#34;。如果取消选中此复选框,图像将作为单独的文件存储在加载PDF的目录中,并仅以表格形式引用

<image xlink:href="image0.png" ... />

我的建议是立即将导入的页面保存为&#34; Plain SVG&#34;然后使用其他工具调整文件夹和路径,因为生成的SVG的结构有点复杂。使用搜索和替换例程找到<image>标记比在Inkscape中搜索它们更容易。

另一种方法可能是最初让图像嵌入。它们都有

形式
<image xlink:href="data:[<mediatype>][;base64],<data>" ... />

您可以使用某些搜索工具从SVG中删除它们,然后使用uudecode将它们解码为图像文件,然后用引用替换数据字符串。