當使用pdfjs來實現預覽功能的時候,遇到了2個問題:git
一是帶寬佔用過大,會下載整個pdf文件,這對部署在公網的應用來講,成本壓力很大,由於雲服務帶寬是很貴的。github
二是內存佔用過大,一個80M的pdf,在預覽時佔用內存高達600M,在一些內存較小的手機上容易發生崩潰。web
pdfjs默認配置下,會加載全部的分片(內容),即便只預覽一個頁面也會加載整個文件。能不能實現按需加載呢?只加載所預覽的頁面?答案是能夠,下面我就詳細地介紹如何作。spring
pdfjs 1.10.100 prebuildchrome
chrome 76springboot
springboot 2.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 206
Partial Content
for the response. If the ranges are invalid, the server returns the 416
Range Not Satisfiable
error. The server can also ignore the Range
header and return the whole document with a 200
status code.ui
這段文字的大概意思是,客戶端使用Range請求頭,能夠要求服務端返回文檔的某個部分。若是服務端不支持,則響應200狀態碼並直接返回整個文檔的內容。若是服務端支持,則在響應中使用206狀態碼並返回部份內容。spa
Range示例: Range: bytes=200-1000 Range: bytes=0-499, -500
在HTTP服務器上,當它支持Range請求頭時,也就實現了所謂的「分片下載」、「斷點續傳」功能。爲行文的方便,下面都使用’分片下載’這個術語。
服務器要啓用功能,springboot web默認開啓了這個功能,不須要再額外配置。
若是使用其它的技術棧,必定要確保開啓這個功能!這是必要條件。
那如何測試HTTP服務器是否開啓了分片?能夠使用chrome開發者模式來確認,若是看到有不少狀態碼爲206的報文,就說明開啓了,以下圖所示:
在pdfjs發行包的web/viewer.js文件中,找到配置項disableAutoFetch,能夠看到它的默認值是false,意味着會自動獲取全部分片。
將它改成true,意味着關閉自動獲取,它僅僅會下載所須要的分片,實現了按需加載。
能夠看到,除了加載開頭的幾個分片以外(這幾個分片中包含pdf元數據,目錄等),不會再加載其它。只有等到要訪問某個頁面的時候,纔會接着發起請求,作到了按需加載。以下圖所示。
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range