hero image

Project: Progressive web app

Assignment

In a previous project, I created this web application on the client-side making a Single Web Application. In this project, I will be redesigning this into a server-side rendered Progressive Web App. My assignment is to dive into the functionalities of a service worker and implement optimizations to improve the performance of this application.

Description

Do you also spend too much time looking for a decent movie to watch? With this progressive web application, you can see right away what the top movies are at this very moment! Find a movie to your liking, and make some popcorn instead of spending minutes to find a good title.

Highlights

Build scripts

In this course, I was introduced to building scripts. With these building scripts, I can concatenate and minify my CSS and js files and write them in another folder. Every time I start my app, the build scripts will run on pre-start. This means that before the apps starts up, it will build new javascript and CSS files from my original files. I used the NPM package gulp for this. Below here is an example of how I concatenate and minify my javascript files. const gulp = require('gulp') const concat = require('gulp-concat'); const minify = require('gulp-minify'); return gulp.src([ './src/js/homeSearch.js', './src/js/movieSearch.js', ]) .pipe(minify({ noSource: true, ext: { min: '.js' } })) .pipe(concat('index.js')) .pipe(gulp.dest('./static/js'))

Install the application

For this application, I added a manifest and a service worker. Because of this, you can install the application on your device as a (web)app.

Intall the app

After its installed, you can pin it on your dock

Installed app icon in menubar

Service-worker

I installed a service worker that caches an offline page. Once you have been on my web application, and your internet connection fails you will now see an offline page instead of the usual no internet page.

Caches and faster loading

My service worker also caches all the pages you visit. I fully realize this might not be the best strategy if you have a very large application, but for a small one like mine, this is in my opinion acceptable. The next time you visit a page that you've already visited, it renders it from the cache. This has advantages and disadvantages. The advantages are: faster loading (like a lot) and you can also visit the pages when your internet connection fails. The disadvantage is that you render out-of-date content from the cache.

For this disadvantage, I save the last updated content again to the cache while it's rendering. This means the next time you visit that page you will get the updated content. Not an ideal solution, but perhaps acceptable for pages that almost never change their content.

Render from web but cache it all the same

I have the /movie page that shows the most popular movies at that time. This isn't a page that you want to have outdated. So I wrote some exceptional rules for this page. If you have internet, render this page from the internet and save it in the cache. If you don't have internet, render this page from the cache. This is always better than no page at all, although it might be outdated.

Offline page

Compression

To make this app even faster I compress my files by using Gzip compression. This might be overrated in this small app, but I wanted to see what it does and how it works.

It turns out, using Gzip as compression is fairly easy. Just install the package and use it. There are some options you can use though. I used a threshold option here and gave it a value of 0. This means that it compresses all the files that are bigger than 0 bytes. You could if you want to set it to 1kb if you want to skip the compression of very small files. I also use a filter function shouldCompress that checks if the request headers are set to x-no-compression if so, it doesn't compress those files.

Critical CSS

Performance is all about perceived performance. And part of that is how to get most of the website as quickly to the user. Critical CSS is a big part of that for bigger websites or apps but I researched this topic nonetheless for my simple app.

In the screenshot below you can see the difference between the stylesheets coverage. About 72% of the normal stylesheet is not needed on this specific page at all, while there is no unused CSS code for the critical CSS stylesheet.

screenshot unnused css percentage

Minify

Every character costs bytes in your file. And you want every file to be as few bytes as it can be. Fewer bytes is faster loading, that's also why we compress the files as described above. Another step to lessen the amount of bytes is minifying your files. This means that you re-write the code with short names and less space. To rewrite these code files you can use packages like gulp-clean-css and gulp-minify. There are more, but in this project, I am already using gulp to concatenate files.

Web application & Github

More information about this project can be read in the readme on Github. Also the web application can be viewed and used online, just hit the button below.

Open the application Visit the Github Repo