Hugo Dolan
Jun 21, 2017 · 4 min read

[Part 1] Get rapid offline capability in your Angular app with service worker

What it is, why you should use it and how to code it in less than one hour

Introduction

Service worker reduces your apps load time significantly by caching essential content to the browser. If you have any of the below capability in your app you should definitely read on:

  1. Significant quantities of static assets such as stylesheets, custom fonts or significant chunks of your app that don’t change much
  2. Considerable article / blog content which users may want to read later
  3. HTTP requests to external api’s which yield the same responses to clients for a prolonged period (> 1 day)
  4. Users which preform transactions offline which need to sync later (To be covered in a later guide)

A Big Plus is that service worker requires no changes to your app’s existing codebase / structure just an hour and 3 or 4 extra files.

How service worker functions

Service worker in its most basic form is a sw.js file which sits between the browser and the network. It intercepts every resource request and response and caches any route responses which match defined patterns.


Implementing service worker with an Angular 2/4 CLI app

I chose angular because thats what my project is written in, but the process is the same for any node based app.

First off you need to build your app for production (Which minifies all your js and packages for distribution):

# Build your app out to the direction /dist
ng build --prod

Saving time with Gulp (A must)

With angular using service workers going to be a real pain if every time we rebuild our app we have to manually reinsert the service worker files into the /dist folder.

Enter gulp task runner (This will make life much simpler, trust me)

# 1. Install gulp globally on your system 
sudo npm install -- global gulp
# 2. Go to your app's package.json and add gulp and its utilities to # the list:"devDependencies": {
...
"gulp": "latest",
"gulp-util": "latest",
"gulp-uglify": "latest",
"gulp-concat": "latest",
"gulp-connect": "latest"
}
# 3. Now install them to your apps node_modules
npm install

Register our (not yet existing) service worker

First go into your index.html and at the bottom of the body add the following:

<script>
if (‘serviceWorker’ in navigator) {
navigator.serviceWorker.register(‘/sw.js’)
.then(function(registration) {
console.log(‘Service Worker registered’);
})
.catch(function(err) {
console.log(‘Service Worker registration failed: ‘, err);
});
}
</script>

(This will install the service worker if the browser supports it)

Lighting fast setup with sw-precache (for static assets) and sw-toolbox

Now that gulp is installed and the index.html setup, we also need sw-precache, a library for service worker with creates a hash of all included files and only updates the browser cache if the hash changes:

#1. We need to install the module
npm install sw-precache
#2. Create our sw-precache-config.js in the directory ./sw-configmodule.exports = {
navigateFallback: '/index.html',
stripPrefix: 'dist',
root: 'dist/',
staticFileGlobs: [
'dist/index.html',
'dist/**.js',
'dist/**.css',
'dist/assets/**'
],
"importScripts": []
};
# The important bits are the staticFileGlobs which tells the service worker which files to cache /**.filetype will get every file with the specified filetype.# We need the import scripts bit later for non static caching

Now that we have a configuration file for our static assets, create a gulp task runner to generate the service worker:

Create gulpfile.js in the root directory of your app:

Add to it a task that will run as gulp sw-build which will listen for changes in our config and rebuild the service worker:

var gulp = require('gulp');
var gutil = require('gulp-util');
var swPrecache = require('sw-precache');
var swPrecacheConfig = require('./sw-config/sw-precache-config');
gulp.task('sw-build', function() {
gulp.watch('./sw-config/sw-precache-config.js', ['sw-generate']);
});

Add to it a task which will be called to rebuild the service:

gulp.task('sw-generate', ()=>{
gutil.log("[build-sw] Detected service-worker change:");
swPrecache.write(
'dist/sw.js',
swPrecacheConfig,
() => {
gulp.src('sw-config/sw-toolbox-config.js')
.pipe(gulp.dest('dist'));
gutil.log("[gulpfile] Task completed!:");

}
);
});

The above sw-generate uses the imported pre-cache module to take the config we write earlier and generate the sw.js in the /dist folder. It also copies the config file to the /dist folder for use by the service worker.

Now kick off the task runner and save your changes:

gulp sw-build

Great, you’ve created your first service worker which caches static assets!

Lets test it out. For this your going to need one last thing:

npm install live-server# Add to the package.json under scripts:
"scripts": {
...,
"static-serve": "cd dist && live-server --port=4200 --host=localhost --entry-file=/index.html"
},
# This will allow us statically serve our assets (currently sw.js won't work with the cli serve cmd)# To launch appnpm run static-serve

Great, now refresh the page and go into the network tab and you should see this: (If not go to application -> service worker and check the status)

Great, Everything we listed is coming from the service worker! Try turning off the wi-fi it still works

I realise this tutorial if getting long!

So check out part 2 on the publication!

Leave comments and recommends down below!

Thanks for reading!

OneHourCode

A blog for hobbyist coders and graphic designers

Hugo Dolan

Written by

UCD Statistics & ACM, Learning Data Science, Winning Team @ Citadel Dublin Data Open. www.hugodolan.com/linkedin | Mailing List: http://eepurl.com/gkV7ov

OneHourCode

A blog for hobbyist coders and graphic designers

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade