pdfjs优化,实现按需加载,节省流量和内存
1 问题
当使⽤pdfjs来实现预览功能的时候,遇到了2个问题:
⼀是带宽占⽤过⼤,会下载整个pdf⽂件,这对部署在公⽹的应⽤来说,成本压⼒很⼤,因为云服务带宽是很贵的。
⼆是内存占⽤过⼤,⼀个80M的pdf,在预览时占⽤内存⾼达600M,在⼀些内存较⼩的⼿机上容易发⽣崩溃。
pdfjs默认配置下,会加载所有的分⽚(内容),即使只预览⼀个页⾯也会加载整个⽂件。能不能实现按需加载呢?只加载所预览的页⾯?答案是可以,下⾯我就详细地介绍如何做。
2 测试环境
pdfjs 1.10.100 prebuild
chrome 76
springboot 2.1
3 步骤
3.1 原理
要实现按需下载,需要⽤到HTTP协议的范围(Range)请求。MSN站点中有关Range的介绍如下:
The Range HTTP request header indicates the part of a document that the server should return. Several parts can be requested with one Range header at once, and the server may send back these ranges in a multipart document. If the server sends back ranges, it uses the Partial Content for the response. If the ranges are invalid, the server returns the Range Not Satisfiable error. The server can also ignore the Range header and return the whole document with a status code.
chrome直接下载 这段⽂字的⼤概意思是,客户端使⽤Range请求头,可以要求服务端返回⽂档的某个部分。如果服务端不⽀持,则响应200状态码并直接返回整个⽂档的内容。如果服务端⽀持,则在响应中使⽤206状态码并返回部分内容。
Range⽰例:
Range: bytes=200-1000
Range: bytes=0-499, -500
在HTTP服务器上,当它⽀持Range请求头时,也就实现了所谓的“分⽚下载”、“断点续传”功能。为⾏⽂的⽅便,下⾯都使⽤’分⽚下载’这个术语。
3.2 HTTP服务器启⽤分⽚下载功能
服务器要启⽤功能,springboot web默认开启了这个功能,不需要再额外配置。
如果使⽤其它的技术栈,⼀定要确保开启这个功能!这是必要条件。
那如何测试HTTP服务器是否开启了分⽚?可以使⽤chrome开发者模式来确认,如果看到有很多状态码为206的报⽂,就说明开启了,如下图所⽰:
3.3 pdfjs关闭⾃动获取
在pdfjs发⾏包的web/viewer.js⽂件中,到配置项disableAutoFetch,可以看到它的默认值是false,意味着会⾃动获取所有分⽚。
将它改为true,意味着关闭⾃动获取,它仅仅会下载所需要的分⽚,实现了按需加载。
3.4 效果确认
可以看到,除了加载开头的⼏个分⽚之外(这⼏个分⽚中包含pdf元数据,⽬录等),不会再加载其它。只有等到要访问某个页⾯的时候,才会接着发起请求,做到了按需加载。如下图所⽰。
4 参考资料
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论