PDF.js 的速度有多快?

大家好,我叫 Thorben,我在奥斯陆的 Opera Software 工作,不是 Mozilla。那么,我怎么会为 Mozilla Hacks 写文章呢?也许你知道 Opera 浏览器没有默认的 PDF 阅读器,这是我们想改变的事情。但如何添加一个呢?从 Adobe 或 Foxit 购买?自己开发?

介绍 PDF.js

在我们调查选项时,我们很快发现了 PDF.js。该项目的目的是使用 JavaScript 和 Canvas 在浏览器中创建一个功能齐全的 PDF 阅读器。是的,这听起来有点疯狂,但它是有道理的:浏览器需要擅长处理文本、图像、字体和矢量图形 - 这正是 PDF 阅读器必须擅长的。PDF 中的绘图命令是 Postscript 的一个子集,它们与 Canvas 提供的功能并没有太大区别。此外,安全性几乎不是问题:使用 PDF.js 与打开任何其他网站一样安全。

参与 PDF.js 的开发

因此,Christian Krebs、Mathieu Henri 和我开始更详细地研究 PDF.js,并对此印象深刻:它设计良好,看起来很快,并且代码的大部分令人惊叹!

但我们也发现了一些问题,主要是非常大或图形密集型 PDF 的性能问题。我们认为,了解 PDF.js 的最佳方法,以及推动该项目进一步发展的方法,就是帮助该项目并解决我们发现的主要问题。这让我们对该项目及其巨大潜力有了相当好的了解。我们也对我们在开发过程中 PDF.js 的性能提升印象深刻。这是一个活跃且管理良好的项目。

对 PDF.js 进行基准测试

当然,我们的测试让我们对性能产生了错误的印象。我们试图找到超大、奇怪和难以渲染的 PDF,但这并不是大多数人想要查看的内容。您实际上想要在 PDF.js 中查看的大多数 PDF 都很好。但如何测试呢?

好吧,您可以查看互联网上最受欢迎的 PDF - 因为这些 PDF 可能是您想要查看的 - 并对它们进行基准测试。5 到 10k 个 PDF 的快照应该足够了……但如何获取它们呢?

我认为搜索引擎将是我的朋友。如果您告诉它们只搜索 PDF,它们会为您提供与该关键字最相关的 PDF,这些 PDF 也可能是最受欢迎的 PDF。如果您使用搜索次数最多的关键字,您最终会得到一个很好的近似值。

对如此多的 PDF 进行基准测试是一项大任务。所以我给自己弄了一小群旧电脑,并构建了一个不错的服务器应用程序,为它们提供任务。当前存储库中有近 7000 个 PDF,对一个版本的 PDF.js 进行基准测试大约需要 8 个小时。

结果

让我们直接跳到有趣的部分,也就是漂亮的图片。此图表

histogram

让我们一目了然地了解几乎所有有趣的结果。您会看到一个直方图,它显示了处理 PDF 中所有页面所需的时间与处理 Tracemonkey Paper(打开 PDF.js 时看到的默认 PDF)的平均页面所需时间的平均时间之间的关系。查看 Tracemonkey Paper 时的用户体验很好,根据我的测试,即使慢 3 到 4 倍仍然可以接受。这意味着从所有基准测试页面中,超过 96%(不包括崩溃的 PDF)将转化为良好的用户体验。这是一个非常好的消息!或者使用一个非常简单的饼图(以页面百分比表示)

overview

您可能已经注意到一个小小的陷阱:在测试过程中,大约 0.8% 的 PDF 使 PDF.js 崩溃。我们仔细查看了其中大部分 PDF,至少三分之一实际上严重损坏,可能任何 PDF 阅读器都无法显示它们。

这让我们想到了另一个要点:我们必须记住,这些结果只是独立存在,没有比较。互联网上有一些 PDF 非常复杂,即使是原生 PDF 阅读器也不可能快速完美地显示它们。测试中最慢的 PDF 是里斯本公共交通系统的一张极其详细的矢量地图。尝试在 Adobe Reader 中打开它,那可不有趣!

结论

从这些结果中,我们得出结论,PDF.js 是一个非常有效的候选者,可以作为 Opera 浏览器的默认 PDF 阅读器。要将 PDF.js 很好地集成到其中,仍然需要做很多工作,但我们现在正在努力将其集成到实验性标志后面(顺便说一下:有一个 扩展程序 可以使用默认的 Mozilla 阅读器添加 PDF.js。我所说的“良好”集成将更深入,包括一个全新的阅读器)。感谢 Mozilla!我们期待与你们一起在 PDF.js 上合作!

附注:计算系统代码结果 均公开可用。请查看并告诉我们您是否发现它们有用!

附注:如果有人在大型搜索引擎公司工作,并且可以给我一个包含实际使用最广泛的 10k 个 PDF 的列表,那就太棒了 :)

附录:接下来是什么?

我描述的语料库和计算框架可以用于做各种有趣的事情。在下一步中,我们希望通过使用的字体格式、图像格式等对 PDF 进行分类。这样,您就可以快速获得 PDF 来测试新功能。我们还想研究在 Postscript 中使用哪些绘图指令以及它们的频率,以便我们可以更好地优化非常常见的指令,就像我们在浏览器中对 HTML 所做的那样。让我们看看我们究竟能做些什么;)

关于 Thorben Bochenek

挪威奥斯陆 Opera Software 的 JavaScript 工程师。Thorben 在一家以 Java 为核心的公司实习并成为唯一的 JS 开发人员时,学会了喜欢 JavaScript 的精简本质。他在苏黎世联邦理工学院学习计算机科学,喜欢旅行,并且只在被要求时才写博客文章。

更多 Thorben Bochenek 的文章…

关于 Robert Nyman [荣誉编辑]

Mozilla Hacks 的技术布道者和编辑。发表演讲和撰写关于 HTML5、JavaScript 和开放网络的博客文章。Robert 是 HTML5 和开放网络的坚定支持者,自 1999 年以来一直在从事网络前端开发工作 - 在瑞典和纽约市。他还在 http://robertnyman.com 上定期撰写博客文章,喜欢旅行和结识新朋友。

更多 Robert Nyman [荣誉编辑] 的文章…


37 条评论

  1. Robert

    太好了,越来越多的人帮助 PDF.js。别忘了打印,显示很重要,但许多网站上的简单 PDF 是由于浏览器缺乏直接打印 API 而生成的。PDF.js 在某些平台(Linux,不确定 OS X)上会向打印机发送大型打印作业,因为它会渲染成位图(有时结果是低分辨率且模糊的)。

    2014 年 5 月 8 日 下午 9:11

    1. Mariano Semelman

      +1

      2014 年 5 月 8 日 下午 11:16

    2. David

      Robert 说得对。从 pdf.js 打印往往不太顺利
      https://bugzilla.mozilla.org/show_bug.cgi?id=932313
      https://bugzilla.mozilla.org/show_bug.cgi?id=932289

      2014 年 5 月 8 日 下午 1:30

    3. Jorge Jenson

      我在一家财富 100 强公司工作,我们发现 OS X 不可能用于任何与浏览器内 PDF 查看相关的任务。Linux 是我们唯一的选择。自切换开发以来,生产效率提高了 30%。

      2014 年 5 月 8 日 下午 1:38

    4. Matěj Cepl

      这很奇怪(或者是我误解了您)……在 Linux(和 Mac OS X)上,默认的打印服务是 CUPS,它使用 PDF 作为其内部打印格式。为什么 pdf.js 不会将 PDF 直接发送到 CUPS 而不进行任何修改呢?

      2014 年 5 月 9 日 上午 5:06

      1. Robert

        @Matěj,没错,至少 PDF.js 应该能够从原始数据生成一个缩减的 PDF,用户应该能够打印页面范围

        2014 年 5 月 9 日 上午 6:13

  2. Zubair Quraishi

    我们实际上使用 Pdf.js 作为 nemCV.com 上简历的内部查看器。我们这样做是因为我们需要人们能够从许多设备和网络浏览器中查看他们的简历,这些简历是 PDF 格式,但必须下载 Adobe 阅读器确实很麻烦,因为许多设备都被锁定,或者像 Apple 设备那样根本无法使用。

    我们在 Pdf.js 的字体渲染方面遇到了一些问题,但我认为这些问题可能已在更新版本的 pdf.js 中得到解决,我们还需要进行测试。但总的来说,pdf.js 是市场上的领导者,甚至比 Google Docs 查看器还要好,Google Docs 查看器通常无法在 PDF 文档上渲染高分辨率图像。

    2014 年 5 月 8 日 上午 10:21

  3. Steve

    您图表上的轴标签应该互换。

    2014 年 5 月 8 日 上午 10:29

    1. Robert Nyman [编辑]

      哈!:-) 谢谢提醒,我已经更新了。

      2014 年 5 月 8 日 下午 3:16

  4. Marcy Sutton

    我很好奇这个解决方案的可访问性。Canvas 被认为是一个不可访问的黑盒子。PDF.js 是否提供任何 Shadow DOM 来配合视觉实现?这样做的安全隐患是什么?

    2014 年 5 月 8 日 上午 10:36

    1. Thorben Bochenek

      是的,PDF.js 具有这样的“影子”DOM,所以可访问性应该很好。
      性能的影响是,对于复杂的文本文档,这可能成为瓶颈。我们正在努力解决这个问题。

      2014 年 5 月 9 日 上午 1:54

  5. Zane

    令人印象深刻的结果,您现在可以随时随地使用 pdf。即使它在处理更大的页面/图像时速度较慢,它仍然值得一试,毕竟您是在客户端执行此操作,因此最终可以在服务器端节省大量资源。
    感谢您在 HN 上分享此内容!

    2014 年 5 月 8 日 上午 11:14

  6. Damien

    我很乐意欢迎对 PDF.js 的工作,我正在 chromium 中使用它,而不是 chrome,以便获得真正的 FLOSS 浏览器。

    我用我拥有的各种查看器测试了里斯本地铁地图:okular(poppler 库)、带有 PDF.js 的 firefox、带有 PDF.js 的 chromium 和带有 google pdf 插件的 chromium。
    带有 PDF.js 的 firefox 绝对是最慢的,okular 和 chromium+PDF.js 给出了或多或少相似的用户体验,而 google pdf 插件是四者中最快的。我的电脑比较新,CPU 和 RAM 都很多,所以我想这就是它能正常工作的原因,它在旧硬件上显然会太慢,但您应该在将来继续使用它进行基准测试;)。

    2014 年 5 月 8 日 上午 11:17

  7. Henrik Gemal

    如何向 PDF.js 添加一些遥测数据,将 URL + 定时信息发送到中央服务器?Mozilla 拥有基础设施。

    2014 年 5 月 8 日 上午 11:24

    1. async5

      给你 http://telemetry.mozilla.org/#beta/29/PDF_VIEWER_USED

      2014 年 5 月 8 日 下午 2:54

  8. Aranjedeath

    Joepie91 创建了一个类似 scribd 的 pdf 共享网站(减去所有让 scribd 变得糟糕的东西),该网站使用 pdf.js{1]。也许过段时间您可以联系他获取最常访问的列表?:D

    [1]: http://pdf.yt/

    2014 年 5 月 8 日 下午 4:38

  9. DB

    许多扫描页面的 PDF 很常见,等待时间可能长达几分钟。更糟糕的是,如果您打算打印 PDF,您必须等待 PDF.js 完全加载文档才能单击下载按钮在 Adobe 中打开 PDF。

    2014 年 5 月 8 日 下午 6:52

    1. Thorben Bochenek

      我们在 Opera 中打印 PDF 的方式将不同于 FF 的方式。我们将直接将 PDF 发送到现有的 PDF 打印 API,因此无需等待。

      2014 年 5 月 9 日 上午 1:51

  10. Aaron Boxer

    我看到你们正在优化 pdf.js 中的 jpeg 2000 和 jpeg 编解码器。
    太棒了!

    2014 年 5 月 8 日 下午 6:57

    1. Thorben Bochenek

      我改进了 JPG 的功能,但 JBIG2 和 JPX 主要归功于 Mathieu – p01 – Henri。

      2014 年 5 月 9 日 上午 1:53

  11. jm

    1) “我们试图找到超大型、笨拙且难以渲染的 PDF,但这不是大多数人想要查看的内容。”
    2) “我们仔细查看了其中大部分,至少三分之一实际上损坏严重,可能没有 PDF 查看器能够显示它们。”
    3) “如果你告诉他们只搜索 PDF,他们会给你与该关键字最相关的 PDF,而这些 PDF 很可能也是最受欢迎的。”

    “大多数”、“可能”、“大多数”、“可能”……得了吧,这应该是一个至少具有统计意义的基准测试。所有这些都表明你正在对纯文本 pdf 进行基准测试。

    1) 许多使用 pdf 的人之所以使用 pdf,是因为它们不是纯文本,我是一名博士生,多次遇到 PDF.js 难以渲染包含一半数学公式一半文字的两个页面。
    2) 不确定我是否理解,如果你没有使用 PDF 查看器,你如何仔细查看?
    3) 搜索引擎当然偏向于文本 pdf。

    2014 年 5 月 9 日 上午 2:49

    1. Thorben Bochenek

      感谢您开启关于数据生成方式的讨论。我同意我们收集 PDF 的方式并不完美。正如我所说,这只会给我们一个关于人们查看内容的近似值。这不是一篇科学论文,“大多数”和“可能”是为了告诉读者我们做出了哪些假设来获得这个近似值,这仅仅是不正式的语言。我仍然认为这些假设是合理的。如果您有更好的方法来抓取 PDF,请告诉我,或者直接向 [1] 提交一个 pull request。我们很乐意采用更好的想法。

      关于你的三个要点
      1) 我想作为一名博士生,你是特殊的,并且会查看大多数用户不会查看的东西。可以公平地说,大多数数学论文并不“流行”。作为一个轶事:当我阅读论文时,我更喜欢下载它们并使用本机查看器查看它们,这样我就可以随时查看它们,无论是在线还是离线,并且我确信我“拥有”它们。
      2) 你可以使用你选择的文本编辑器(例如,sublime)查看 pdf 的内容并对其进行分析。格式很好,人类可以阅读。我还构建了一个工具来帮助我分析 PDF,它在 [2] 中提供。
      举一个 pdf 文件可能损坏的方式的例子:PDF 包含一个名为 xref-table 的表,其中包含对文档中对象的引用。当此表损坏时,可能无法找到某些对象。
      3) 我不确定你的假设“搜索引擎偏向于文本 pdf”是否正确,下载的语料库中包含许多非常图形密集的 PDF。如果您有一个关于建筑的页面,它链接到一个只有图片的 pdf,我认为您可以在搜索“建筑”时找到这个 pdf。

      [1] https://github.com/bthorben/pdfRepo
      [2] https://github.com/bthorben/pdf-analyser

      2014 年 5 月 9 日 上午 3:47

  12. Mathieu ‘p01’ Henri

    您好,

    PDF.js 具有透明文本层(带有实际文本的 DOM 元素)。这对两件事很有用:可访问性和文本选择。

    我们 - Opera - 也测试了各种插件。虽然我们无法准确衡量性能,但它让我们很好地了解了 PDF.js 的位置。此测试阶段表明 PDF.js 的渲染质量和整体用户体验与原生解决方案相当。除此之外,与许多插件不同,PDF.js 递增地渲染,尽管速度较慢,但提供了更好的体验。

    正如 Thorben 和 Aaron 所说,我们正在改进 PDF.js 的性能,并且已经贡献了字体缓存、颜色转换、JBIG2、JPG、JPG 2000 解码器等方面的改进。

    Opera 正在与 Mozilla 合作,让 PDF.js 变得更快,让每个人都能受益。

    2014 年 5 月 9 日 上午 2:53

  13. theor

    您好,

    加拿大移民和公民署有很酷的扭曲 pdf
    http://www.cic.gc.ca/english/pdf/kits/forms/IMM0008ENU_2D.pdf

    花哨的东西。

    2014 年 5 月 9 日 上午 7:33

  14. Jim

    PDF.js 比任何类型的插件都具有速度优势,因为它会立即开始渲染,而使用 adobe,您必须等待插件加载。

    Joepie91 是一位自学成才的程序员,我一直对他印象深刻。

    2014 年 5 月 9 日 下午 3:04

    1. Charlie

      速度和感知速度并不相同。我有 PDF,它们在 PDF.js 中 30 秒内毫无反应,但在 Acrobat Reader 中加载需要 5 秒(包括生成)。

      2014 年 5 月 12 日 上午 2:32

      1. Thorben Bochenek

        这些 pdf 有些是公开的吗?您可以在 PDF.js Issues 中提交错误报告吗?我们会看看的。

        2014 年 5 月 12 日 上午 2:57

  15. Luke

    其他人也注意到 Mozilla PDF.js 查看器不允许双页视图吗?

    如果我没记错的话,您可以在检查器中通过将某些内容设置为 inline-block 而不是 block 来轻松更改它。为它创建一个扩展会更容易,但这只是 html,而不是可扩展的 xul(也许可以在未来的版本中添加?)。

    2014 年 5 月 9 日 下午 9:59

    1. Thorben Bochenek

      有一个半成品的 PR 将在 Firefox 中解决这个问题。
      https://github.com/mozilla/pdf.js/pull/3723

      正如我们已经说过的,Opera 将使用不同的查看器。

      2014 年 5 月 12 日 上午 3:00

  16. Kurt Pfeifle

    > 在下一步中,我们希望根据使用的字体格式、图像格式等对 PDF 进行分类。

    我对此非常感兴趣。它部分与我的私人宠物项目一致:我正在尝试创建一个包含至少 1,000,000 个从互联网下载的 PDF 文件的存储库,并分析所有这些文件,将其各种属性放入 SQLite3 数据库中。

    到目前为止,我一直在使用 Shell 脚本(这是我唯一知道的“编程”)。我目前的收藏量刚刚超过 100,000 个文件。脚本使用 `pdfinfo`、`pdffonts`、`pdfimages`、`pdfresurrect`、`md5sum`、`pdfid.py`、`pdf-parser.py` 等命令行工具来提取文件中可用的统计数据。我的 SQLite3 DB 文件现在大约 8 GB 大小(它没有经过任何优化,而且我目前也正在边学边用 SQL[ite3])。

    我收集这些信息的目的是为了能够创建一组符合特定条件的 PDF 文件(+ 它们的 URL),这些条件可能需要用于测试 PDF 处理软件的特定功能,或者运行回归测试等。

    因此,您在这方面可能正在做的事情对于所有必须处理 PDF 文件的软件项目来说都可能很有用。

    2014 年 5 月 10 日 上午 0:56

    1. Thorben Bochenek

      > 因此,您在这方面可能正在做的事情对于所有必须处理 PDF 文件的软件项目来说都可能很有用。

      我希望如此。如果您发布了关于这项工作的任何内容,我很乐意听到它 :)

      2014 年 5 月 12 日 上午 2:58

  17. Charlie

    FWIW,我发现 Firefox 最新 LTS 版本中的 PDF.js 在处理超过两页的内容时速度令人失望地慢。这很令人沮丧,因为我必须用它来检查 PDF。生成 Acrobat 的新实例感觉快得多,可能是因为它在后台运行。

    尽管如此,PDF.js 仍然是一个非常有趣的开发项目。

    2014 年 5 月 10 日 上午 8:37

  18. Ryan

    Opera 做出的 PDF.JS 改进是否也出现在 Firefox 中,还是只适用于 Opera?

    2014 年 5 月 12 日 下午 1:37

    1. Thorben Bochenek

      我们直接贡献给 https://github.com/mozilla/pdf.js。因此所有改进将使浏览器受益。只要我们没有自己的浏览器,只有 Firefox 才能使用它;)

      2014年5月14日 下午09:53

      1. Adam

        @Thorben,由于 Opera 基于 Chromium,为什么不构建一个原生 PDF 阅读器作为 PPAPI/PNaCl 插件,可能基于开源的 Evince 浏览器插件?它应该比 JavaScript 更快。

        接下来,您是否愿意支持使用 WebODF 查看 Open Document Format?

        2014年5月21日 上午07:25

  19. momo

    当我打开一个 PDF 文件(例如 15 页)时,第一页会被渲染。然后我切换到另一个标签/窗口,并稍后(例如 3 分钟)返回到 PDF 文件(它仍然打开在第 1 页)。现在我要去第 7 页,但它需要重新渲染。

    我的期望
    当我跳转到/滚动到第 7 页时,它应该已经被预渲染,因为 Firefox 有足够的时间和电脑有足够的资源来完成。

    保持您的浏览器出色!

    2014年5月23日 下午20:07

  20. Ian

    现在,Chromium 有一个叫做 pdfium 的开源 PDF 查看器。

    2014年5月24日 下午17:47

本文评论已关闭。