Some tips to optimize images

A gulp js workflow

I'm using Gulp as development web server, with browserSync reload and all you can imagine and also for deploy via ftp. I'm using gulp-load-plugins to load gulp plugins, obviously.
But I want to talk about image optimization today.

Add dependencies

To add project dependencies (package.json) use

npm install --save-dev [package]

My complete package.json (not only for images...) is

{
  "devDependencies": {
    "browser-sync": "^1.8.2",
    "del": "^1.1.1",
    "gulp": "^3.8.10",
    "gulp-autoprefixer": "^2.0.0",
    "gulp-changed": "^1.1.0",
    "gulp-concat": "^2.4.2",
    "gulp-ftp": "^1.0.1",
    "gulp-image-resize": "^0.6.0",
    "gulp-imagemin": "^2.0.0",
    "gulp-jshint": "^1.9.0",
    "gulp-load-plugins": "^0.8.0",
    "gulp-minify-css": "^0.3.11",
    "gulp-rename": "^1.2.0",
    "gulp-sass": "^1.2.4",
    "gulp-size": "^1.1.0",
    "gulp-sourcemaps": "^1.2.8",
    "gulp-uglify": "^1.0.2",
    "gulp-util": "^3.0.1",
    "gulp-webp": "^2.1.1",
    "imagemin-pngquant": "^4.0.0"
  }
}

Resizes

First of all: responsive images, so multiple image resizes served via srcet. Picturefill as polyfill.

The three resize tasks run in parallel. As you can see in the next paragraph firsts starts the bigger.

gulp.task('img-resize-300', function () {
    return gulp.src(['./src/img/**/*', '!./src/img/resize', '!./src/img/resize/*', '!./src/img/resize/**/*'])
            .pipe(plugins.changed('./src/img/resize/300'))
            .pipe(plugins.imageResize({width: 300}))
            .pipe(gulp.dest('./src/img/resize/300'));
});
gulp.task('img-resize-600', function () {
    return gulp.src(['./src/img/**/*', '!./src/img/resize', '!./src/img/resize/*', '!./src/img/resize/**/*'])
    .pipe(plugins.changed('./src/img/resize/600'))
    .pipe(plugins.imageResize({width: 600}))
    .pipe(gulp.dest('./src/img/resize/600'));
});
gulp.task('img-resize-1200', function () {
    return gulp.src(['./src/img/**/*', '!./src/img/resize', '!./src/img/resize/*', '!./src/img/resize/**/*'])
    .pipe(plugins.changed('./src/img/resize/1200'))
    .pipe(plugins.imageResize({width: 1200}))
    .pipe(gulp.dest('./src/img/resize/1200'));
});

File formats and compression

pngquant to optimize png, imagemin for jpg and tif. webp as alternative format.

gulp.task('img', ['img-resize-1200', 'img-resize-600', 'img-resize-300'], function () {
    var pngquant = require('imagemin-pngquant');
    gulp.src('./src/img/resize/**/*')
    .pipe(plugins.changed('./dist/img'))
    .pipe(plugins.imagemin({progressive: true,svgoPlugins: [{removeViewBox: false}],use: [pngquant()]}))
    .pipe(gulp.dest('./dist/img'));
    return gulp.src(['./src/img/resize/**/*.png','./src/img/resize/**/*.jpg','./src/img/resize/**/*.jpeg','./src/img/resize/**/*.tif','./src/img/resize/**/*.tiff'])
    .pipe(plugins.changed('./dist/img/resize/**/*'))
    .pipe(plugins.webp({quality:50}))
    .pipe(gulp.dest('./dist/img'));
});

Apache .htaccess for webp

You can use this in your .htaccess to serve webp only when the browser support this new format instead of jpg, png and tiff.

<IfModule mod_rewrite.c>
  RewriteEngine On
  #RewriteBase /
  RewriteCond %{HTTP_ACCEPT} image/webp
  RewriteCond %{REQUEST_FILENAME} (.*)\.(jpe?g|png|tif?f)$
  RewriteCond %1\.webp -f
  RewriteRule (.+)\.(jpe?g|png|tif?f)$ $1.webp [T=image/webp,E=accept:1]
</IfModule>
<IfModule mod_headers.c>
  Header append Vary Accept env=REDIRECT_accept
</IfModule>

Responsive images (srcset)

Simple srcset for full-width pics. Just add Picturefill polyfill in your javascript.

<a href="../img/1200/2015-01-01_01.png" target="_blank">
    <img 
    width="300" 
    height="169" 
    src="../img/300/2015-01-01_01.png" 
    sizes="100vw" 
    srcset="../img/300/2015-01-01_01.png 500w , ../img/600/2015-01-01_01.png 900w , ../img/1200/2015-01-01_01.png 1200w" 
    alt="Screenshot writing this posts in Chrome Developer Tools" /> 
</a>