Sukka's Blog

童话只美在真实却从不续写

  1. 1. 测试环境
  2. 2. Fragment Cache
  3. 3. Highlight.js
  4. 4. 结论

Hexo 是一款基于 NodeJS 的性能优异的静态博客框架。但是随着需要生成的页面数量越来越多,Hexo 也出现了性能瓶颈:在 Hexo 的 issue 页面 搜索 performance 可以找到一些关于 Hexo 性能问题的报告。总结一下,一般都是这几个方面的问题:

我针对这些 issue 和讨论中提到的一些问题进行了测试,得到了一些有趣的结果。

测试环境

测试使用 300+ 篇文章,每篇文章都有三个不同的 categories 和五个不同的 Tags(也就是生成总计超过 900 个 categories 和 1500 个 tags),还有 3 个特别长的代码块;在性能测试前将所有 css、js 和图片文件全部删除,确保生成的文件全部都是渲染生成的 HTML 文件;所有测试都使用 hexo clean && hexo g 确保完全冷启动。
原始测试结果可以看 Travis CI Build Log

Fragment Cache

Hexo Issue #1749

2014 年的时候 Hexo 从 Ruby on Rails 获取灵感为 Hexo 推出了 Fragment Cache 特性,可以缓存编译后的主题局部结构并重复使用,大大提升了速度和性能。分别启用、禁用 Fragment Cache 后进行测试,得到的结果是:

Fragment CacheDisableEnable
HighlightEnableEnable
Highlight line_numberDisableDisable
Highlight tab_replaceEnableEnable
生成文件数12081208
用时1.55min (93s)1.22min (73.2s)
平均每秒生成页面1316.5

结论是使用 Fragment Cache 可以使 Hexo 的渲染性能增加 30%。所以如果主题尚不支持 Fragment Cache 的话应该要跟进了。

Highlight.js

Hexo Issue #1036

Hexo 3.2 版本发布时,推荐用户禁用 Highlight 的 auto_detect 选项(用来自动判断语言)来实现对 Highlight 语言文件的 Lazyload、提升 Highlight 相关文件载入速度,但是 Hexo 开发团队仍然认为 Highlight 非常缓慢。
在 Hexo 中提供了三个关于 Highlight 的选项,除了 auto_detect 以外还有 linenumber 用来渲染行号、tab_replace 把 Hard Tab 替换成空格。
分别测试三个选项后得到的结果是:

HighlightEnableEnableDisable
Highlight line_numberDisableEnableDisable
Highlight tab_replaceEnableDisableDisable
Fragment CacheEnableEnableEnable
生成文件数120812081208
用时51s1.22min (73.2s)22s
平均每秒生成页面23.716.555

测试结果表明 line_number 的确会产生一定的性能影响,禁用后生成速度提高了 43% 左右;但是如果完全禁用 Highlight 的话,性能会达到原来的 3 倍。所以 Hexo 内置的 Highlight 的确会对 Hexo 的性能产生影响。

结论

影响 Hexo 生成页面耗时的因素自然远远不止上文提到的这些,但是就这些测试,我们已经可以开始优化 Hexo 的生成:首先排除设计不良的插件带来的影响;使用浏览器端渲染代码高亮而不是使用 Hexo Highlight 可以大大提升渲染效率——在浏览器内渲染,访客每访问一个页面只需要访客渲染一次,如果使用 Hexo 内进行代码高亮则需要把每一个页面都渲染一次;充分利用 Fragment Cache 缓存一些耗时较长的 widget。

当然 Hexo 本身是一个 NodeJS 应用,如果需要进行多线程改造就需要启动多个 Hexo 实例,所以 Hexo 目前仍不支持多核渲染,这也是为什么 Hexo 的渲染速度没有 Hugo 那么快。

本文作者 : Sukka
本文采用 CC BY-NC-SA 4.0 许可协议。转载和引用时请注意遵守协议!
本文链接 : https://blog.skk.moe/post/hexo-performance/

本文最后更新于 天前,文中所描述的信息可能已发生改变