PDF.js 是一个非常强大的 JavaScript 库,用于在网页中渲染 PDF 文档。它的分片加载(或称为流式加载)是其性能优化的一部分,允许在需要时按需加载 PDF 的不同部分。这种机制使得大文件的加载过程更加高效,用户体验也得到了提升。
分片加载的原理:
优势
Canvas渲染代码
const loadingTask = pdfjsLib.getDocument({
url: 'path/to/document.pdf',
rangeChunkSize: 65536, // 64 * 1024,每次请求的字节数
disableAutoFetch: true, // 禁用 PDF 文档中附加页面的自动获取
disableStream: false // 开启 PDF 文档的流式加载
});
loadingTask.promise.then(pdf => {
console.log('PDF 加载完成');
// 加载特定页面
pdf.getPage(1).then(page => {
console.log('页面加载完成');
const scale = 1.5;
const viewport = page.getViewport({ scale: scale });
// 准备画布以显示页面
const canvas = document.getElementById('the-canvas');
const context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
// 渲染页面到画布
const renderContext = {
canvasContext: context,
viewport: viewport
};
page.render(renderContext);
});
}).catch(error => {
console.error('加载 PDF 时出错: ', error);
});Dom渲染代码
let pdfViewer = null
const eventBus = new pdfjsViewer.EventBus()
// 获取挂载点
const container = document.querySelector('#pageContainer')
// 实例化pdf视图
pdfViewer = new pdfjsViewer.PDFViewer({
container: container,
eventBus: eventBus
})
const loadingTask = pdfjsLib.getDocument({
url: pdfUrl,
cMapUrl: PdfCMapUrl, // 字体库地址
cMapPacked: true, // 字体打包
rangeChunkSize: 32_768, // 每次请求的字节范围大小,默认值为 32768 字节(32KB)
disableAutoFetch: true, // 禁用自动获取整个文件
disableStream: false // 启用流式加载
})
loadingTask.promise.then((pdf) => {
pdfViewer.setDocument(pdf)
})
eventBus.on('pagerendered', (event) => {
const page = event.pageNumber
console.log(`Page ${page} rendered`)
})官方示例
mozilla.github.io/pdf.js/web/…

服务端响应头
# makefile
Access-control-expose-headers: Accept-Ranges, Content-Encoding, Content-Length, Content-Range下面是对阿里云上传文件的响应头配置,配合PDF.js即可生效

# 后端设置响应头代码
ObjectMetadata metadata = new ObjectMetadata();
String bs64 = BinaryUtil.toBase64String("Accept-Ranges, Content-Encoding, Content-Length, Content-Range".getBytes(StandardCharsets.UTF_8));
metadata.setHeader("x-oss-persistent-headers","Access-Control-Expose-Headers: " + bs64);
client.putObject(ossTokenDTO.getBucketName(), infoDTO.getKey(), file, metadata);参考文档
本文由 小马哥 创作,采用 知识共享署名4.0 国际许可协议进行许可 本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名 最后编辑时间为: 2026/06/03 01:19