gohugoio / hugo

The world’s fastest framework for building websites.
https://gohugo.io
Apache License 2.0
74.61k stars 7.45k forks source link

Performance Improvements in Template Execution #12654

Open lyind opened 1 month ago

lyind commented 1 month ago

Summary

As part of a sustainability initiative, I found that Hugo builds for complex themes (e.g. Docsy in my case) can take longer and consume more CPU cycles than expected.

Expectation

Hugo needs single-digit milliseconds to render an individual page: grafik

Observed Condition

Hugo needs (133685ms / 1707) = ~78ms per page:

...
INFO  build: running step render duration 2m13.152050519s
INFO  build: running step postProcess duration 8.827µs

                   |  EN   
-------------------+-------
  Pages            | 1707  
  Paginator pages  |    5  
  Non-page files   |  485  
  Static files     |   40  
  Processed images |    2  
  Aliases          |   39  
  Sitemaps         |    1  
  Cleaned          |    0  

Total in 133685 ms

Analysis

Some profiling, tracing and experimentation lead to the following result:

  1. Hugo scales very well when one throws more cores on it. Tracing indicated that for our site around 18 cores would be the optimum (the tested GitHub runner features 2).
  2. There does not seem to be a a single slow function or low hanging fruit. The slowest syscall used (fstatat, which could maybe be optimized/avoided) just consumes ~1s of our total ~120s runtime. This is less than 1%. (!)
  3. Use of reflection in template execution, mostly for evaluating expression and especially calling functions slows Hugo down, when using complex themes.

Proposed Action

bep commented 1 month ago

While Go templates isn't the fastest on earth, I don't think your conclusion above is correct.

In all the examples of "slow Hugo sites" I have seen (and I have seen one), it always boils down to doing too much work.

lyind commented 1 month ago

Complex themes (e.g. docsy), combined with a decent amount of pages, do indeed highlight the limits of Hugo's current architecture, in particular around template execution.

Yes:

However:

lyind commented 1 month ago

I'd not request such optimizations from projects in incubating or prototype phase, but mature products with many users, like Hugo, could indeed profit.