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.
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"
}
}
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'));
});
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'));
});
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>
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>