Another Year, Another Site Refresh
Published on:Table of Contents
Let’s track current progress:
- 2012: move from homegrown static site solution to jekyll
- 2013: incorporate LESS CSS, RequireJS, minification using
Gruntfile.js
. I can laugh at it now as the title is “The Perfect Blogging Workflow”. Heh. - 2014: migrate from GoDaddy/IIS/WCF/C#/MySQL to DigitalOcean/Apache/Flask/Python/SQLite.
- 2015: I didn’t write about it, but change did happen. Move frontend dependencies to bower. Still using grunt but starting to use webpack to generate sourcemaps and minify. Use skeleton.css for theme.
- 2016: this post!
Theme Update
Skeleton.css, while a good fit for general content, didn’t quite feel right from a blogging perspective. It didn’t seem to emphasize the content like I had hoped. Skeleton also recommended the usage of the Raleway font, which increased the number of requests sent and time to download. A blog, should really be the fastest page on the internet. Taking a fast site and making it faster will be a theme in this post (no pun intended).
I stumbled upon lanyon, which is a beautifully minimalist design. In a lot of ways this motiviation to use to design spurred my enthusiasm to give the site an update. The typography looks crisp, code (inline and block) more elegant, sane lists. The one regression are that tables have a tad worse appearance, but that’s a compromise I’m willing to make.
One customization I made to lanyon is the removal of the sidebar. I thought it added zero values and removing it led to a sizeable reduction to css and js. Also, no more additional request for fetching fonts!
Less to cssnext
There is not a ton of custom css on the site and that’s probably a good thing[citation needed]. It used to be written in Less. Less has served me well over the years. I’ve used it in countless project and it always resulted in a boon.
Working with Less wasn’t always easy. If you’re familiar with Less questions on stackoverflow you may even recognize me from the famous question “Less Aggressive Compilation with CSS3 calc” (it’s the second hit for the google search “less css calc”).
Recently it has seemed that Less has become less popular (again, pun not intended). Bootstrap 4 is moving away from Less. “Why Bootstrap 4 Means Sass Has Won”. “Less vs Sass? It’s time to switch to Sass”
I would fault no one for believing that this site using Sass, but they would be wrong. I chose cssnext. It’s a simpler language, but contains all the features of Less that I want. The best part is that cssnext represents features that will most likely land in the next version of the css spec. From the site:
In a near future, browsers will implement new CSS specifications. As time passes, cssnext will remove some transformations that won’t be necessary anymore. And maybe one day, you will be able to completely remove cssnext from your workflow without touching your CSS.
That’s a huge selling for me. Since I don’t modify this site very often, I want css that is going to last.
I’ve also moved to PostCSS for processing cssnext, as
well as inlining css @import
, linting styles, and
minifying the css via cssnano. It was almost too easy to
use.
Removal of most of Grunt functionality
Before the rework, Grunt was preforming the following actions in about 200 lines of configuration:
- Compiling Less files into css
- Concat said css files into a single file
- Run Jekyll
- Copy files to a build directory
- Clean folders
- Run webpack
- Run requirejs
- Optimize images
- Resize images
- Autoprefixer
- Rename files
- Replace java script tag with hashed version
After the rework, Grunt is still present but its role has greatly diminished (an +80% reduction in configuration size)
- Run webpack
- Run postcss
Bower has been eliminated from the repo with no traces remaining. Read why use bower when there is npm. It’s dying and that’s fine.
Since the original functionality didn’t just disappear from the site, the next couple sections will explain where the behavior has been moved to.
Jekyll Assets
This website sits behind the CDN, DNS, and DDos protection company,
Cloudflare. In order to better serve your
content, Cloudflare asks how long it should keep your site’s assets in the
cache before refreshing them. I used to have it set at four hours because
there was main.js
, main.css
, images, etc, and if I updated one of these
files I would only have to wait four hours to know they’ve been refreshed.
Sitespeed and Page
Insights complained
about the short cache time.
Jekyll assets is a beautiful solution to the caching problem. It will take css, js, and images referenced in the posts and replace the path with a version that is digested (the file name will contain a hash). This hash will only ever change if the content changes. Once deployed, this file could be cached forever. With this simple update, I changed Cloudflare to cache all files (except the html files) for one year. Increasing the cache time nearly 9000x appeased performance tools.
I do not have Jekyll assets handle any js or css transformations, instead use webpack and postcss for the transformations.
I use the resize feature for images so that all banner images are the same size. Jekyll assets will also inline the width and height so that the browser doesn’t need to calculate the image manually. It’s the small things, but they add up.
Previously, images were optimized on every build. While initially convenient, build times started to creep up. So instead of wasting time doing the same operation every build, optimize the images once before commit. Additionally, the image optimizations was done using a node.js package and I couldn’t help but think that there were some bytes left on the table.
Using the image tools recommended by
google,
I first used optipng to optimize the pngs. For jpegs, the lossless jpegtran -optimize
was followed by mozjpeg -optimize
. These two commands yielded
the best result. The result was a 80% in reduction of images (from 20MB to
4MB) with minimal reduction in quality.
ESLint over JSHint
A small change, but one still worth mentioning is a move from JSHint to ESLint. ESLint is just like JSHint except it has the potential to be so much more by being pluggable. I’ll admit that I can’t articulate all the benefits so I’ll paste from ESLint’s README.
How is ESLint different from JSHint?
The most significant difference is that ESlint has pluggable linting rules. That means you can use the rules it comes with, or you can extend it with rules created by others or by yourself!
Is ESLint just linting or does it also check style?
ESLint does both traditional linting (looking for problematic patterns) and style checking (enforcement of conventions). You can use it for both
I do know one thing. The ESLint plugin for webpack integrated seamlessly with the babel plugin. I’m unsure if JSHint can say the same thing.
Below is the contents of my .eslintrc
notice that it extends from the very
popular airbnb-base with a few
modifications of my own.
{
"extends": "airbnb-base",
"env": {
"browser": true
},
"rules": {
"no-use-before-define": [2, { "functions": false }],
"no-plusplus": ["error", {"allowForLoopAfterthoughts": true}]
}
}
Deployment
Previously, I’d tar up the temporary build directory and pipe over ssh like the following:
tar cf - _site | ssh nick@<host> \
'D=`mktemp -d`;tar xf - -C $D;cp -r $D/_site/* /var/www/nbsoftsolutions/.'
This is slow and permissions weren’t ideal for apache. I decided to give rsync a try, and I’m glad I did. Some of the benefits seen:
- Much faster file transfers
- Customize permissions on resulting remote server
- Dry runs
- Delete files on remote but not on local (great for those hashed assets)
The rsync script ended up looking like:
# Pass in `-n` for a dry run deployment. Exclude deleting python environment
# on remote side as well as Let's Encrypt certificate information. Chgrp the
# files so that apache can read the files
rsync $@ -rvP --delete --exclude=env/ --exclude=.well-known/ \
-g --groupmap=*:www-data \
_site/ nick@<host>:/var/www/nbsoftsolutions
Results
- Pingdom gives us a 100% for performance and we’re faster than 99% of sites.
- Sitespeed gives a 99% across all categories
- Google page insights gives a 97/100 for speed and a 99/100 for user experience
Comments
If you'd like to leave a comment, please email [email protected]