Optimize Web assets with Gulp
Images, css, javascript, fonts, we’re using a lot of things in today’s websites. Every time you add an asset <link>
, <script>
, @import
, the browser will issue a request to fetch it. The number of requests that you’ll send might not matter compared to how heavy your ressources are.
Still, this website for example can improve a lot:
# Ldlc assets:
And this is far not the worse I’ve seen.
# Use case
This blog has:
- css assets - theme, gridly, highlightjs and the base16-tomorrow scheme
- no javascript assets except hightlightjs, comments are powered with disqus (and they really could improve their javascript load time…)
- images
# Disqus assets on my blog:
# Gulp
Gulp is handy for this kind of things, I’ll give you some examples.
# SASS to CSS
I’m using Cloudflare’s CDN for highlightjs only for the javascript part. As I already tweaked the base16 color scheme in SASS, I added the hightlight.min.css
file. This way, I’ve only 1 css file to request, FYI it’s about 12Kb
.
'use strict'
const gulp = require('gulp')
const nano = require('gulp-cssnano')
const rename = require('gulp-rename')
const sass = require('gulp-sass')
const autoprefixer = require('gulp-autoprefixer')
gulp.task('scss', () => {
//the screen.scss file already import assets
return gulp.src('static/scss/screen.scss')
.pipe(sass())
.pipe(autoprefixer({browsers: ['last 2 versions']}))
.pipe(rename('main.css'))
.pipe(gulp.dest('static/build'))
//css nano works great!
.pipe(nano())
.pipe(rename('main.min.css'))
.pipe(gulp.dest('static/build'))
})
Launch gulp task, and static/build
now has:
12K Apr 23 16:45 main.min.css
21K Apr 23 16:45 main.css
If you want to add source maps, try not to add them in the minified version.
# Images
My blog has a bunch of images, which can also be optimized. This is better done just before releasing a new version. Just before my rsync
task that deploys the static blog, I’m running gulp-imagemin
:
This is mostly a copy of the readme:
'use strict'
const gulp = require('gulp')
const imagemin = require('gulp-imagemin')
// $ npm i -D imagemin-pngquant
const pngquant = require('imagemin-pngquant')
//the hugo task builds the blog from markdown to html
gulp.task('images', ['hugo'], () => {
//I'm then optimizing every pictures
return gulp.src('static/images/**/**')
.pipe(imagemin({
progressive: true,
use: [pngquant()]
}))
//and sending them to the public directory
.pipe(gulp.dest('public/images'))
})
My next task here involves rsync -trvu -e '/usr/bin/ssh' public soyuka.me:soyuka.me/
. The deployed images in public/images
are optimized.
Check the results, there is almost half the size less in the public directory:
❯ du -hs static/images
14M static/images
❯ du -hs public/images
8.3M public/images
# Javascript
Here I’m using a CDN, but javascript files can easily be optimized. I’m usually using gulp-uglify
, gulp-ng-annotate
, see this related article.
# Fonts
I’m using google fonts and fontello (icon fonts). I haven’t done anything to optimize, but it’s advised to ensure that fonts are gziped. Fontello is doing it here.
# CDN or no CDN
That’s what’s nice about using CDN’s, you mostly haven’t anything to add. Still, in most cases involving lot of dependencies, you should better use a package manager and a build system.
In my experience, CSS always ends up in a single file. There are many advantages over using a CDN, especially when working with pre-processors (LESS, SASS).
To me with Javascript it depends. If you only need jQuery and some script of yours, it’s just fine to use the CDN and one script file. If you’re starting an angular2 stack (Rx, Typescript, angular2 to start with), you’ll be more productive with a proper-set build system. Also, you might want to use angular2/http
but not angular2/router
. Javascript is about modularity nowadays, isn’t it?
I think that your development must not be impacted by how dependencies are handled. Keep things simple, light and safe. By doing so, you’ll improve your load time.
# Homepage load time:
Inspired by The web is doom