The previous version of this post died, because I by accident overwrite it with another story. I feel lazy to restore full version. Here is the main idea: to build a Hugo theme which will load fast we can follow recommendations of AMP project (I don't want to use AMP itself, but checklist makes sense).
Demo is here. Source code is here.
Only asynchronous scripts. Non-async scripts block DOM construction and delay page rendering.
I have one and only one script bundled with Parcel (Parcel is optional) and placed before the closing tag of body.
{{ if (fileExists "./assets/output/index.js") }}
{{ $js := resources.Get "output/index.js" }}
{{ with $js }}
{{ $secureJS := . | resources.Fingerprint }}
<script src="{{ $secureJS.Permalink }}" integrity="{{ $secureJS.Data.Integrity }}" crossorigin="anonymous" async></script>
{{ end }}
{{ end }}
External resources need to have set dimensions.
For iframes user (author of blog) would need to provide dimensions, but for local images, we can calculate dimensions automatically with the help of shortcode. See my other post on the subject.
CSS must be inlined and size bound.
I use a minimal amount of CSS:
- postcss-normalize any other normalize would work as well
- syncope for vertical rythm
- Code for highliting generated with
hugo gen chromastyles --style=manni > assets/css/code.css
Then I inline it directly in the header:
{{ with resources.Get "output/index.css" | minify }}
<style>{{ .Content | safeCSS }}</style>
{{ end }}
Font loading must be efficient.
I don't use custom fonts. I use so-called system font stack. Other option would be self-hosted web fonts with font-display: swap;
Only run animations on the GPU.
I don't have any animations for now, but I will take this into account in the future.
Other
I added quicklink for faster between pages navigation.