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:

ldlc load

And this is far not the worse I’ve seen.

# Use case

This blog has:

# Disqus assets on my blog:

disqus assets

# 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:

soyuka.me load

Inspired by The web is doom