美文网首页
pdfjs 渲染页面上下颠倒和内容尺寸异常

pdfjs 渲染页面上下颠倒和内容尺寸异常

作者: xun66 | 来源:发表于2024-09-20 19:32 被阅读0次

背景

在项目中使用pdfjs渲染页面,出现缩放和dpr异常,表现为文档内容等比缩放到页面左上部分,且上下颠倒。

问题排查

问题出现之前,使用的渲染方式是getDocument完成后,逐页面循环调用page.render,直到所有页面都加载完成。为了节省资源,引入 Intersection Observer以后,发现此问题出现。

查找资料得知,出现此问题的原因99%都是因为并行操作canvas导致的。

现在逻辑是每次收到Observer回调,就调一次渲染单页(先设置canvas宽高,再调用page.render)。Intersection Observer有时会反复针对某一页面进行回调,虽然我们已经使用了一个set进行标记加锁防止重复渲染,但是只保护了page.render的调用,漏掉了设置canvas尺寸的逻辑,这就导致了在page.render过程中依然可以设置了canvas宽高的情况,也就出现了开头这种异常情况。将canvas尺寸修改也加到保护范围后,问题解决。

解决方法

想办法确保不要同时操纵canvas,包括page.render和修改canvas height/width等。此处使用的方案是一个set,渲染中将pageNum放到set中,每次请求渲染前检查page是否在set中。注意,这只是个简单的实现,极端情况下依然可能存在竞争的情况。

伪代码如下:

const busyPageSet = new Set();
const renderPage = async (pageNum) => {
  // 关键代码,判断当前页面是否被标记为正在渲染状态
  if (busyPageSet.has(pageNum)) {
    return;
  }
  busyPageSet.add(pageNum); // 标记当前页面为渲染状态
  const page = await pdfDoc.getPage(pageNum);
  const viewport = page.getViewport(); // 并处理scale和dpr等缩放逻辑
  const canvas = getCanvasRef(pageNum); // 获取canvas
  canvas.width = ...; // 设置canvas高度
  await page.render({context: ..., viewport: ...}).promise; // 调用pdfjs渲染canvas
  busyPageSet.delete(pageNum); // 解除标记当前页面的渲染状态
}

补充

当重复调用page.render时,pdfjs会在控制台输出告警。但是若渲染时进行了canvas的尺寸修改、直接调用draw命令,pdfjs不会发出告警。

本次问题主要原因是加锁保护时,设置的保护范围不全面,漏掉了其他canvas操作,而这又不会触发告警,导致排查的时间有点长,值得吸取经验。

参考资料

https://stackoverflow.com/questions/44885973/pdf-js-document-is-presented-upside-down-randomly
https://github.com/mozilla/pdf.js/issues/11277#issuecomment-546498526

相关文章

  • Error:did you register the compo

    新项目集成 UI 库之后在页面中调用组件,编译 code 重启服务,抛出如下异常且组件样式失效: 从页面渲染的内容...

  • 移动端性能优化(5)

    渲染类 使用Viewport固定屏幕渲染,可以加速页面渲染内容 一般认为,在移动端设置Viewport可以加速页面...

  • 项目使用pdf.js

    实现pdf预览主要有两种方式:1、使用pdfjs已经写好的viewer.html页面。需要将pdfjs代码到服务器...

  • 5(2)页面示例-页面状态

    APP页面设计过程中,除了设计正常状态下的页面,还需考虑异常页面状态。如:页面内容为空、网络异常、服务器异常、页面...

  • 移动端性能优化(5)

    渲染类使用Viewport固定屏幕渲染,可以加速页面渲染内容一般认为,在移动端设置Viewport可以加速页面的渲...

  • 渐进式页面渲染思想:Bigpipe

    《深入浅出 Node.js》阅读随笔 Web 应用中页面渲染的大概过程:服务器端的页面渲染包含内容响应和视图渲染两...

  • CSS语法,选择器

    CSS: 定义:css全称是层叠样式表; 作用:为页面内容设置好看的样式,渲染页面内容; 注释:css注释格式:/...

  • Hexo在GitHub上的异常处理

    一、意外的标记异常 1.异常内容: 2.异常原因: 3.解决方案:(参考Markdown语法) 二、模版渲染错误异...

  • SSR 服务端渲染

    什么是浏览器端渲染(CSR)? 浏览器端渲染是后端提供数据,前端做视图和交互逻辑。页面初始加载的HTML种无内容,...

  • web前端

    一个页面由三部分组成:html、css、javascript HTML 页面的内容 CSS 渲染页面的样式建议直接...

网友评论

      本文标题:pdfjs 渲染页面上下颠倒和内容尺寸异常

      本文链接:https://www.haomeiwen.com/subject/elooljtx.html