# Production release
- The Lighthouse report from the previous release gives us some tips about optimizing our website for production
- We are going to:
- add some favicons to all our HTML pages
- optimize (compress) all images for faster downloads
- minimize all HTML, CSS and JS files by removing white spaces and commands
- We can do this fully automatic with the Gulp tasks already present in this project
REMARKS
- Setting up those Gulp tasks is not the focus of this course
- We just want you to understand what's happening behind the scenes
- If you want to use those techniques inside your future projects, just copy the necessary Gulp tasks, and your ready to go
- The Gulp task
build
runs a serie of 5 tasks:
gulp.task('build', gulp.series('clean', 'copy', 'generate-favicon', 'inject-favicon-markup', 'minify'));
Copied!
1
- Run
gulp build
ofnpm run build
to build a production ready version of your site
# Explanation of Gulp tasks
# Step 1: copy files
- First, remove some tasks so that we can better understand what each task exactly does
- Let's start with the first two tasks:
- Change the
build
task to:
gulp.task('build', gulp.series('clean', 'copy'));
Copied!1- Run the task with
gulp build
ofnpm run build
and examine the documents inside the newly created dist folder
- Change the
task 1: clear
task 2: copy
- Package used: del (opens new window)
- If there is a dist folder from a previous build, delete all files and folders inside this dist folder
const del = require('del'); ... // Delete all files and folders inside the dist folder gulp.task('clean', () => { return del(['dist/**/*']); });
Copied!
1
2
3
4
5
6
2
3
4
5
6
- After those two tasks, we have an exact copy of the development folder (src) inside the production folder (dist)
- From now on, all the optimization happens inside the dist folder (the src folder is left untouched)
# Step 2: add favicons
- Add the third and fourth task:
- Change the
build
task to:
gulp.task('build', gulp.series('clean', 'copy', 'generate-favicon', 'inject-favicon-markup'));
Copied!1- Run the task again with
gulp build
ofnpm run build
and examine the documents inside the dist folder
- Change the
task 3: generate-favicon
task 4: inject-favicon-markup
result after task 4
- Package used: gulp-real-favicon (opens new window)
- The only parameters that you may need to change are:
- Line 5: set the name of your mobile app (we use this in our PWA version)
- Line 6: the original image - a square (transparant) PNG with a minimum of 512x512 pixels - to create all icons from
- Line 7: the folder where all the icons and config files are stored
- Line 8: the background color for the splash screen when your mobile app starts up
- This script is a slightly modified version of the code that RealFaviconGenerator (opens new window) generates for us (once you have generated the online icons)
const realFavicon = require('gulp-real-favicon'); ... // RealFavIcon config const FAVICON = { name: 'My App', // The name for your mobile app startImage: './favicon.png', // Original image (min 512*521 px) to start from destination: './dist/assets/icons', // Save generated icons and config files inside this folder androidThemeColor: '#ffffff', // Theme color for Android app dataFile: './dist/assets/icons/faviconData.json', }; // Generatie real favicon gulp.task('generate-favicon', (cb) => { realFavicon.generateFavicon( { masterPicture: FAVICON.startImage, dest: FAVICON.destination, iconsPath: '/assets/icons', design: { ios: { pictureAspect: 'noChange', assets: { ios6AndPriorIcons: false, ios7AndLaterIcons: false, precomposedIcons: false, declareOnlyDefaultIcon: true, }, }, desktopBrowser: { design: 'raw', }, windows: { pictureAspect: 'noChange', backgroundColor: '#da532c', onConflict: 'override', assets: { windows80Ie10Tile: false, windows10Ie11EdgeTiles: { small: false, medium: true, big: false, rectangle: false, }, }, }, androidChrome: { pictureAspect: 'shadow', themeColor: FAVICON.androidThemeColor, manifest: { name: FAVICON.name, startUrl: '/', display: 'standalone', orientation: 'notSet', onConflict: 'override', declared: true, }, assets: { legacyIcon: false, lowResolutionIcons: true, }, }, safariPinnedTab: { pictureAspect: 'silhouette', themeColor: '#5bbad5', }, }, settings: { scalingAlgorithm: 'Mitchell', errorOnImageTooSmall: true, readmeFile: false, htmlCodeFile: true, usePathAsIs: false, }, markupFile: FAVICON.dataFile, }, () => { cb(); } ); });
Copied!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
TIP
- If you want a new favicon for your website, just replace the favicon.png in the root of your project with a new PNG file and re-run the
build
task- favicon.png must be a square image of at least 512px by 512px
# Step 3: minimize all files and images
- Add the last task:
- Change the
build
task to:
gulp.task('build', gulp.series('clean', 'copy', 'generate-favicon', 'inject-favicon-markup', 'minify'));
Copied!1- Run the task again with
gulp build
ofnpm run build
and examine the documents inside the dist folder
- Change the
task: minify
result
- Packages used: gulp-imagemin (opens new window) and gulp-minifier (opens new window)
- Line 10 to 15: make all images interlaced/progressive (opens new window) so that they load faster on slow internet connections
- Line 11: reduce the compression for JPEG files to 70%
- Line 20-31: minimize all textual files (HTML, CSS en JS) by removing whitespaces and comments
- Line 29: create a source map (opens new window) (a reference to the original, uncompressed JavaScript source) for the JavaScript files
const imagemin = require('gulp-imagemin'); const minify = require('gulp-minifier'); ... // Minify all files an copy to dist folder gulp.task('minify', () => { return gulp .src('./dist/**/*') .pipe( imagemin([ imagemin.gifsicle({ interlaced: true }), imagemin.mozjpeg({ quality: 70, progressive: true }), imagemin.optipng({ optimizationLevel: 5, interlaced, true}), imagemin.svgo({ plugins: [{ removeViewBox: true }, { cleanupIDs: false }], }), ]) ) .pipe( minify({ minify: true, minifyHTML: { collapseWhitespace: true, conservativeCollapse: true, removeComments: true, minifyJS: true, // minify inline JavaScript minifyCSS: true, // minify inline CSS }, minifyJS: { sourceMap: true, }, minifyCSS: true, }) ) .pipe(gulp.dest('./dist')); });
Copied!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# Hosting
- Hopefully you are convinced that the optimized files in the dist folder are better suited for publishing on the web then the original files in the src folder
- Let's update our hosting
# FTP hosting
- Run the
build
task every time want to publish a new version of your website - Delete all content inside the root folder of your hosting
- Upload the content of the dist folder (not the content of the src folder!) to the root of your hosting
# Netlify hosting
- You don't have to run the
build
task locally because Netlify can run this task on the server 😊 - Go to your website settings on Netlify and update the build settings:
- Set the Build command to
gulp build
ornpm run build
- Change the Publish a directory from src to dist
- Set the Build command to
- Every time you push a modified version of your website to Github, Netlify will automatically pick this up and publish the updated version on your hosting
REMARKS
- We have already optimized our files quite a lot, but there are other, more advanced techniques to take the optimization even further
- For example, all JavaScripts are often bundled in one JavaScript file, unused code is automatically removed (tree shaking) and the code is optionally transformed into ES5 code that even older browsers (e.g. Internet Explorer) understand
- The most common tools to accomplish this are: webpack (opens new window) (used in Angular and Laravel for example), rollup (opens new window) and parcel (opens new window)
- These tools sometimes require additional configuration and are outside the scope of this course
# Lighthouse report
- Let's perform a new audit to see if we score better this time
- Open the online version of the website in Chrome
- Open DevTools and generate a Lighthouse report for mobile devices and compare it with the previous report
- The overall performance score has increased from 92% in the previous report to 99% in the current report
- Thanks to the realfavicon generator (which created a manifest file for us), we now also have a good starting point for a Progressive Web App (PWA)
- Let's make a fully working PWA for the site in the next step: the PWA release