本人使用Typescript开发了一款ofd 阅读器,参见文章《ofd轻阅读》。
web端实现阅读功能有两种方案: ofd转svg;使用h5 canvas。
两种方案各有优劣,本人采用了canvas方案,
劣势:开发难点较大,需要处理更多的细节(比如:文字选中)。
优势:对细节掌控能力更强,能满足用户更苛刻的需求。
打开超大文件时,需要对内存作优化,否则占用内存就会急剧上升,有导致程序崩溃的风险。
注:本文所指超大文件是指文件页数特别多,多达上千页。
阅读器内存占用分为两个来源:
- ofd文件本身:xml解析、图片资源、嵌入字体等,都会占用内存。
- canvas占用:canvas的个数、大小等都会影响内存占用。
本文只针对第二种内存占用情况作优化分析。
本人分析发现canvas占用内存有以下几个特点:
- canvas的宽度、高度越大(即面积越大),占用内存越多。(显而易见)
- 如果不在canvas上做任何绘制,canvas占内存较少。(下文会证明这个结论)
测试文件页数:500页。
ofd未加载前 占用内存:
加载ofd,不绘制,占用内存:
加载ofd,绘制,占用内存:
三种情况占用内存分别为:276M、500M、7.4G。得出结论:绘制的canvas占用内存较大。
基于上述结论,阅读器加载ofd文件处理步骤:
1 快速加载前几页,如果当前页可见,就绘制。
2 对后续的页,使用占位(placeholder)canvas。即只设置canvas的宽和高,使文档的滚动条正常显示。
3 监控页面是否可见,如果可见就显示(生成canvas并绘制);如果不可见,将canvas从dom中移除。
查看生成的html内容,就会发现有如下特点:
后记:本文分析了阅读器占用内存的来源,提出了对应的优化方案。本文提出的方案能解决内存占用的大部分问题;如遇特殊情形,采用具体问题具体分析的方法,解决起来并非难事。