Create a Pelican plugin to minify HTML, CSS, and JS
TL;DR - Minify you Pelican Website
Minification of wesite resources is an essential step for good PageSpeed / Lighthouse scores, and as I've bragged in past, CloudBytes/dev> scores a perfect 100.
This is partly because Website generated by SSGs are generally faster than the ones generated using CMS solutions like WordPress, etc. But the main reason is non-redundant JS & CSS code.
To make websites faster still, you minify the contents of all the HTML, CSS & JS files which typically results in smaller file sizes that consequently means faster load times for users.
Minify your Pelican Website
There are a lot of options in Python to minify your webassets, but none of them work. Either they break your website (e.g. remove embedded JS code) or are outdated and not maintained. I personally tried the below in dev environment:
- β Unofficial Pelican Plugin: css-html-js-minify: Broke the website π, removed embedded JS, deleted some CSS variables & class definitions.
- βOfficial Pelican Plugin: Extremely promising, is useless, and doesn't work. Becase it doesn't minify HTML pages, and it relies on additional 3rd party modules for minification and those modules are either unmaintained (cssmin,css_yui, etc) or simply doesn't work and breaks the site (cssutils), or requires NPM/NodeJS modules that needs to be installed manually (cleancss)
- βNon-Python packages such as html-minifier, minimize, etc. These could have been used but the hassle of integrating them into the CI/CD workflow was too much
- β minify-html: This seemed to work without breaking the website. Minify HTML is a Rust app but with APIs available in several languages (Python, Ruby, NodeJS, Java, etc) which made it easy to write a simple plugin.
Writing the Minification Plugin
First step is to install the minify-html package. Run the following command
pip install minify_html
Then create a plugin, using the below code
import minify_html
import glob
import os
import sys
import logging
from pelican import signals
logger = logging.getLogger()
def main(pelican):
for file in glob.iglob(pelican.output_path + "/**/*.html", recursive=True):
print(f"Processing {file}")
try:
with open(file, "r", encoding="utf-8") as html:
minified = minify_html.minify(html.read(), do_not_minify_doctype=True)
with open(file, "w", encoding="utf-8") as html:
html.write(minified)
except Exception as error:
logging.error(error)
def register():
signals.finalized.connect(main)
Add it to the plugins list in pelicanconf.py
and you're good to go with a website that is almost 20-30% faster