Enfasten is a tool written in Go which takes in a static site, scales the images down to a number of different sizes, then rewrites all of your HTML to use responsive image tags with srcset
attributes. It can also run all of your images through an optimizer like ImageOptim.
This makes your static site faster for people to load because their browser can load the best image for their screen size and resolution, and it's backwards compatible with older browsers.
Even though they save tons of bandwidth, few sites use optimized responsive images because it requires creating a custom image processing pipeline that has to be incremental in order to achieve good performance. Enfasten solves this problem by doing everything for you!
I wrote this because on my site I frequently include images which are absurd sizes, such as a 2146x1258
screenshot from a high-DPI display. The user's browser downloads this huge image and promptly resizes it down to fit in my 660px wide blog. This is especially bad when people without high-DPI displays visit my site, but I still want things to look nice on high-DPI displays. The fact that I don't always remember to optimize my images makes this waste even worse.
With Enfasten, no matter what static site generator you use, you can run your site through Enfasten before you deploy and get free bandwidth savings!!
Enfasten has a bunch of features that would take a long time to replicate in a script or Gulp task you set up yourself:
0.36s
, plus it only processes new images when necessary and uses a fast resizer.1345px
wide and you tell Enfasten to make a version that is 1320px
wide, by default it won't bother. You can configure the "close enough" threshold if you want. For .jpg
file the threshold for this is separate since resizing JPEG files often comes with a quality hit because of re-encoding, so small changes in size really aren't worth it.srcset
attribute to the image tags.img
src
attributes.png
and jpg
files, everything else is left alone.Below is an example of what the input and output of Enfasten look like. Basically it copies your entire site from an input to an output folder, adding in an images folder with hashed, optimized and resized versions of your images. Then it rewrites all your HTML to reference those. For now the original images are still copied in case they are referenced by RSS, scripts, CSS, etc.
test
├── _fastsite
...
│ ├── archive.html
│ ├── assets
│ │ ├── images
│ │ │ ├── 1-bing-4da5feb8-original.png
│ │ │ ├── 1-ddg-eb1bf143-original.png
│ │ │ ├── 1-google-6efffef5-original.png
│ │ │ ├── 1-samuru-93e3f1fc-660px.png
│ │ │ ├── 1-samuru-93e3f1fc-original.png
│ │ │ ├── 2-bing-078cbd23-original.png
│ │ │ ├── 2-ddg-68249286-original.png
│ │ │ ├── 2-google-c8456412-original.png
│ │ │ ├── 2-samuru-c6b17722-660px.png
│ │ │ ├── 2-samuru-c6b17722-original.png
│ │ │ ├── 3-google-caf9e182-original.png
│ │ │ ├── Beowulf-f3168a7d-660px.png
│ │ │ ├── Beowulf-f3168a7d-1320px.png
│ │ │ ├── Beowulf-f3168a7d-original.png
│ │ │ ├── canus-loot-6549ac19-original.jpg
│ │ │ ├── case-6b5e62c5-original.jpg
...
│ │ ├── postassets
...
│ │ │ ├── hackEnglish
│ │ │ │ ├── Beowulf.png
│ │ │ │ ├── Colours-of-Gatsby.png
│ │ │ │ ├── lotf-1.png
│ │ │ │ ├── lotf-2.png
│ │ │ │ └── markov-poster.png
...
│ │ │ ├── keyboardhw
│ │ │ │ ├── canus-loot.jpg
│ │ │ │ ├── case.jpg
...
│ │ │ ├── search
│ │ │ │ ├── 1-bing.png
│ │ │ │ ├── 1-ddg.png
│ │ │ │ ├── 1-google.png
│ │ │ │ ├── 1-samuru.png
│ │ │ │ ├── 2-bing.png
│ │ │ │ ├── 2-ddg.png
│ │ │ │ ├── 2-google.png
│ │ │ │ ├── 2-samuru.png
│ │ │ │ └── 3-google.png
...
├── _site
...
│ ├── archive.html
│ ├── assets
│ │ ├── postassets
...
│ │ │ ├── hackEnglish
│ │ │ │ ├── Beowulf.png
│ │ │ │ ├── Colours-of-Gatsby.png
│ │ │ │ ├── lotf-1.png
│ │ │ │ ├── lotf-2.png
│ │ │ │ └── markov-poster.png
...
│ │ │ ├── keyboardhw
│ │ │ │ ├── canus-loot.jpg
│ │ │ │ ├── case.jpg
...
│ │ │ ├── search
│ │ │ │ ├── 1-bing.png
│ │ │ │ ├── 1-ddg.png
│ │ │ │ ├── 1-google.png
│ │ │ │ ├── 1-samuru.png
│ │ │ │ ├── 2-bing.png
│ │ │ │ ├── 2-ddg.png
│ │ │ │ ├── 2-google.png
│ │ │ │ ├── 2-samuru.png
│ │ │ │ └── 3-google.png
...
├── enfasten.yml
└── enfasten_manifest.yml
On the releases page you can download pre-built static binaries for macOS and Linux that you can put somewhere in your PATH
.
If you have Go installed you should be able to run:
$ go get github.com/trishume/enfasten
and then make sure your Go bin
folder is in your PATH
. Alternatively, clone the repo and run go get
and then go install
.
After you've installed enfasten, create an enfasten.yml
config file in your static site's directory (see "Configuration" section below for an example) and then run:
# Looks for an enfasten.yml file in the current directory
$ enfasten
# Looks for an enfasten.yml in the specified directory
$ enfasten -basepath my/site/folder
# Runs with culling, only do this once all your images are optimized
$ enfasten -cull
Enfasten is configred through an enfasten.yml
file. All keys are optional, here's a good basic config file for a Jekyll site that is a static 660px wide:
# Jekyll by default outputs to _site, we'll put our result in _fastsite
inputfolder: _site
outputfolder: _fastsite
sizesattr: 660px
# Normal and retina resolutions:
widths: [660,1320]
# ImagOptim is a great optimizer for macOS, here's how to connect it:
optimcommand: ['open', '-a', 'ImageOptim']
# Sometimes there's files we don't want to bother processing and rewriting
blacklist:
- favicon.png
And here's the full slate of config options, the default values and documentation of what they do:
# The folder to take files and images from, relative to enfasten.yml
inputfolder: _site
# The folder to put output in, relative to enfasten.yml
outputfolder: _fastsite
# The folder to put all images in, relative to outputfolder
imagefolder: assets/images
# The file name for the manifest, relative to enfasten.yml If this is set to the
# empty string, no manifest will be used.
manifestfile: enfasten_manifest.yml
# The contents of the "sizes" attribute for responsive image tags, if this is
# the empty string the attribute will be omitted.
sizesattr: ""
# An array of strings specifying a command and arguments to run to optimize
# images. If non-null, Enfasten will append all the files needing optimization to
# this, run it and wait for it to finish.
optimcommand: null
# Whether to copy/transform non-image files into the output. Set this to false if
# you're only using Enfasten as an image resizing tool and parsing the generated
# manifest with your own script.
docopy: true
# The threshold of scaling above which Enfasten won't bother. In this case if the
# destination width is greater than 0.9 times the source width, that size won't be
# created.
scalethreshold: 0.9
# Same as above, but for .jpg files. Separate because re-encoding is bad.
jpgscalethreshold: 0.7
# The quality with which to re-encode JPG files, higher is larger but less lossy.
jpgquality: 90
# The array of widths to which Enfasten will try and downscale each image
widths: []
# An array of Go file glob patterns relative to inputfolder of files not to process
blacklist: []
Note: When changing the options that affect image processing like widths
, jpgquality
and scalethreshold
, you may want to delete your manifest file and possibly also the processed images themselves. If you don't the old images won't be re-processed and will be left as is, if you do, Enfasten will rebuild any missing images.
Enfasten can output an enfasten_manifest.yml
file that describes all the images it knows about and has built. You can delete this file and for the most part Enfasten will do the exact same thing it would have done otherwise, but slower. The manifest provides the following benefits:
1.3s
on my site. With the manifest, Enfasten only has to load files and hash them, which only takes about 0.3
s on my site.This was a weekend project, there's a few things I haven't got around to yet. If you want to see these features, I welcome contributions!
It sounded like a word that would mean "to make fast". It also sounds like Emscripten which is another project about making the web fast, although in a totally different and unrelated way. In my head I alternate between pronouncing it "En-fast-en" and "En-fassen". I also Googled it and it didn't look like it collided with anything too important.
This project is released under the Apache license and was written by Tristan Hume