Delays in performance have the potential to impact user engagement, experience and revenue. Thankfully, Google's 'Make The Web Faster' team recommend a set of best-practice rules for keeping your pages lean, fast and smooth. These include minifying resources like CSS and JavaScript, optimizing images, inlining and removing unused styles and so on.
If you have complete control over your server, an excellent PageSpeed Module for Apache and Nginx exists with filters for many of these tasks. If not however, or you feel the module isn’t quite for you, a number of build-tasks exist for tools you’re probably already using to fill in the gaps with more granular control.
The below represent Grunt and Gulp tasks the Yeoman team regularly use in our projects. We’ve tried our best to keep this list focused and exclude previous suggestions which no-longer offer as much value, but there’s plenty here to help you keep your pages and their resources as small as possible.
Compress & optimize images
The average web page is now over 1.5MB in size, with images responsible for the bulk of this. We aim to keep our image sizes as lean as possible to reduce the time it takes for a user to wait for that resource to load.
With the right balance of compression and formatting it's possible to still ship images as a part of your page whilst minimizing load time as much as possible. This is really important for users on mobile with limited data plans or slow connections.
Grunt
- grunt-contrib-imagemin
- grunt-imageoptim (OSX only)
Why two tasks? Well, here’s an excellent breakdown of differences between the two. Choose the one that is most suitable for you.
Gulp
Generate responsive images for the <picture>
element
If you have a responsive site which is visually flexible on multiple devices, you'll want a strategy to make images flexible too.
Serving unnecessarily large images to the browser can impact both rendering and load performance, but these aren't the only metrics that can suffer when large images are shipped to the browser.
This is one reason we need responsive images, and it's great to see srcset - hopefully leading to a full implementation of <picture>
- is already in Chrome Beta.
There are a number of Grunt tasks available that can help generate multi-resolution images as part of your build process.
Grunt
- grunt-responsive-images - use this along with Imager.js,
<picture>
or the picturefill polyfill. - grunt-clowncar
In addition, if you need to just resize/normalize images that are large in dimension, you can use grunt-image-resize.
Minify SVG images
SVG files created with editors usually contain a large quantity of redundant information (metadata, comments, hidden elements and so forth). This content can be safely removed or converted to a more minimal form without imacting the final SVG that's being rendered.
Grunt
Gulp
Generate spritesheets
Grunt
Gulp
Convert images to WebP
WebP is a recent image format that offers lossless and lossy compression for images on the web. WebP lossless images are up to 26% smaller in size compared to PNGs and WebP lossy images are 25-34% smaller in size compared to JPEGs. That's quite a saving and thankfully there exist tasks for encoding to WebP for both Grunt and Gulp.
Grunt
Gulp
Build SVG sprites with support for various browsers
Grunt
Gulp
We consider inlining images using Data URIs to now be an anti-pattern given their poor performance on mobile.
Minify CSS
Minification eliminates unnecessary space, line breaks, indendation and characters in your files, which are generally unnecessary in production. Compacting down your HTML, CSS and JS can improve on parsing, execution and doanload times. For CSS specifically, we recommend:
Grunt
Gulp
Remove unused CSS
In projects using CSS frameworks like Bootstrap, Foundation and so forth you typically don’t use the entire kitchen-sink of styles available. Rather than shipping the full framework to production, use UnCSS to remove unused styles across your pages. Some developers have seen anything up to 85% savings in stylesheet filesize.
Grunt
Gulp
Inline CSS
If the external CSS resources for a particular page are small, you can inline those directly in your markup to save on additional requests. Inlining small CSS in this way allows the browser to proceed with rendering the page.
Grunt
Gulp
Combine media queries
This isn't a PageSpeed recommendation, but allows you to combine matching media queries into a single media query definition. We've found it useful for handling CSS generated by preprocessors which may use nested media queries.
Grunt
Gulp
JavaScript
Minify, compress JS
Grunt
Gulp
RequireJS (optimization via r.js)
Grunt
Gulp
Minify HTML
Grunt
Gulp
Simple concatenation
Grunt
Gulp
General compression for files/folders
Grunt
Gulp
Zopfli compression
The Zopfli Compression Algorithm is an open-source compression library that generates output typically 3–8% smaller compared to zlib at maximum compression. It is best suited for apps where data is compressed just once and then sent over the network lots of times.
Grunt
Gulp
Inline Critical path CSS
The critical path represents the code and resources needed to render the "above-the-fold" content in the page - i.e what your users will first see when they load up your page. PageSpeed recommends inlining your critical path CSS for improved performance. Whilst tools like mod_pagespeed are highly efficient at achieving this, it’s more difficult to optimize for the critical path with other tooling.
You could probably use PhantomJS along with the above the fold scripts from speedreport to get an idea of what CSS is above the fold and can then work on optimizing this manually.
Asset pipeline (auto-handle all optimizations)
On the ‘tools to keep an eye on’ list is AssetGraph.
AssetGraph looks at projects as a set of graph problems where the nodes are considered assets (HTML, CSS, Images, JS) and edges, the relationships between them (image tags, anchor tag, script tags etc).
As AssetGraph can determine how project assets relate to each other it can perform many of the common performance optimizations developers may want to achieve on their own automatically. This works particularly well on smaller projects and support for larger projects is being worked on.
Grunt
Gulp
Gulp users should just use AssetGraph directly.
Benchmarking
The following benchmarking tasks are useful to integrate as a part of Continuous Integration. Although the following are currently only available for Grunt, you can use gulp-grunt to run Grunt tasks from Gulp. We recommend:
- grunt-pagespeed - fantastic for automating checking your PageSpeed score as a part of CI.
- grunt-topcoat-telemetry - get smoothness, load time and other stats from Telemetry as part of CI. This could help you set up a performance benchmarking dashboard similar to the one used by TopCoat
- grunt-wpt - CI for WebPageTest scores
- grunt-phantomas - response times for requests, responses, time to first image/CSS/JS, onDOMReady and more.
Framework Optimization
Grunt
- grunt-ngmin
- grunt-react
- grunt-vulcanize - excellent for concatenating and flatening Web Components.
Gulp
Misch
Conclusions
Delays in performance have the potential to impact user engagement, experience and revenue. Take time to experiment with the tasks available for performance optimization, find out what practical gains they can offer to your projects.
Visitors to your page will be happier as a result of a snappier experience and a faster web is better for all.
~ Addy Osmani
With thanks to Sindre Sorhus, Pascal Hartig and Stephen Sawchuk for their review