跳到主要内容
  1. Skills/
  2. Hugo 使用指南/

使用 partialCached 时要小心

·字数 1329·3 分钟

虽然 gohugo 具有非常快的速度来生成静态网页,但它还是提供了一个方法还提高网页渲染的速度,就是 partialCached。但是这个 partialCached 是有限制的,不能把所有的 Partical 都更改为 partialCached

particalCached 的问题 #

官方文档中的说明, partialCached

partialCached
Allows for caching of partials that do not need to be re-rendered on every invocation.

语法,partialCached LAYOUT INPUT [VARIANT...]

这个 partialCached 是用在模板中的函数,利用缓存来提高静态页面的渲染效率。但是在文档中,并没有很清楚的说明,这个 partialCached 是缓存了模板、还是缓存了根据参数渲染后的结果?

熟悉 java、python 编程的同学,对缓存都有一定的认识。比如在 python 中,有一个叫 cache 的库,用来帮助用户缓存计算的结果,当函数调度的参数(funcname(args…))已执行过时,会取上一次已计算过的结果,减少重复计算,已达到提高效率的目的。 而当有悟看到 gohugo 中对于 partialCached 的语法定义与官方文档中用法例子时,很难不把它跟 python cache 的缓存用法等同。

{{ partialCached "footer.html" . }}

但事实上,有悟原先的理解是错的。

经验主义有时是比较危险的。

如果你没有编程经历或者在编程中使用缓存库的经历,也许不会像有悟这样误解了 partialcached

经过实践,发现 partialCached 模板函数的缓存效果是这样的:

  • particalCached 模板 参数,缓存该模板第一次渲染的结果
  • 无论第二次执行的参数具体值是什么,相同模板的渲染结果都一样

所以,这里不能把 partialCached 模板 参数 看成是编程语言的缓存系统,因为它不会根据参数来区别渲染结果。只要你的模板中,需要使用到传入参数中的属性具体值,并且该属性在不同页面的值会不同时,就不能使用 partialCached

partialCached 的常用场景 #

上一节说了,如果你的页面模板,需要在不同页面渲染使用不同参数值时,不能使用 partialCached。但如果是一个固定的模板,在所有使用到的页面中,都是一样的,那么可以使用 partialCached。比如最常见的 footerheader

hugo 还有一个优化建议的选项,可以帮助查看使用 partialCached 的潜在可能优化。

注意哦,优化建议只是建议潜在的可能,并不是全部建议都是正确的,因为 hugo 并不知道那段模板在不同页面上渲染结果是不是一样(hugo 没那么智能),它把这个选择交给用户来决定,它只是认为被用得比较多次的模板,优化可能性比较大。

hugo server 或者 hugo 启动命令后,加上选项 --templateMetrics --templateMetricsHints,如

# hugo 编译生成静态页面
> hugo --templateMetrics --templateMetricsHints
# hugo 运行测试环境
> hugo server --templateMetrics --templateMetricsHints

会看到类似于下面这段内容的统计信息:


Change detected, rebuilding site.
2021-05-29 21:00:57.488 +0800
Source changed "/Users/youwu/Projects/youwu.today/content/skill/hugo/partialcached.md": WRITE|CHMOD

Template Metrics:

      cache     cumulative       average       maximum
  potential       duration      duration      duration  count  template
      -----     ----------      --------      --------  -----  --------
          0   40.487803ms    5.060975ms     6.91314ms      8  skill/single.html
         43   17.895815ms    1.193054ms    5.028297ms     15  partials/head/head.html
         24    16.63074ms    1.108716ms    4.978481ms     15  partials/seo/seo.html
         22    15.79639ms    1.053092ms    4.931117ms     15  partials/seo/desc.html
          0   11.061415ms    2.212283ms    4.278359ms      5  index.html
        100    9.285415ms     619.027µs    2.195055ms     15  partials/header/header.html
... 此处省略若干行
        100      26.098µs      26.098µs      26.098µs      1  partials/head/favicons.html
        100      16.477µs      16.477µs      16.477µs      1  partials/page/copyright.html
        100       2.892µs       2.892µs       2.892µs      1  partials/content/grid.html
          0         688ns         688ns         688ns      1  robots.txt
        100         570ns         570ns         570ns      1  partials/assets/scripts.html
        100         376ns         376ns         376ns      1  partials/head/resource.html

Total in 117 ms

上面的统计信息中,第一列是潜在可以使用 partialCached 来优化的可能性;几个 duration 表示模板渲染所用的累计时间、平时时间、最大时间;count 表示渲染执行的次数。结合这几个统计项,对用时较长、执行次数较多的模板,分析其是否可以使用partialCached 来优化。再一次强调说明,第一列仅是可能性,并不是值为 100 就可以用 partialCached 优化的。