I've been using a service called Netlify recently, which is based entirely around the idea of static hosting. I decided to try and convert the popular TodoMVC application into a more complete progressive web app, and that's where we start our journey. I also published this article in video form, available here.

What's a progressive web app?

The concept behind being a progressive web app is to create a webpage providing a high enough level of quality to earn a place on a users home screen. There's a great page explaining more on the Google developers site, here.

Sounds great! Where do I start?

It's important to understand that progressive web apps are a concept, rather than a discrete set of rules. Each browser has its own set of criteria, and so you should research these before going forward. Lighthouse is a great starting point. It's a browser extension which generates a report for each page of your site identifying areas for improvement. For the sake of this article, we'll rely on it as our way of deciding what to focus on.

I ran the tool for our basic todo list app, and it highlighted a few things which we were missing:

  • HTTPS - our page isn't secure, and with services such as Let's Encrypt offering SSL for free, there's really no excuse not to encrypt your content. I was able to fix this quickly using Netlify's built in HTTPS integration, so I won't cover it too much in this article.
  • Critical Request Path - This is an indicator of the number of requests your browser has to make before it is able to reach what we call the 'first meaningful paint'. This refers to the point at which users can read the content on your site.
  • Application Manifest - Manifest files allow extra context to be given to the browser so that it can provide a native like experience when the app is added to a users home screen.
  • Service Workers - The ability to add a middleman between your browser and the internet, to provide a better experience with either unpredictable network conditions, or even in situations where the user is offline.

The easy bit - HTTPS, and optimising assets

2017 is a great year to be a web developer. HTTPS used to be so expensive it was reserved for large organisations and financial institutions, but it's now so cheap browsers such as Chrome (see here) are beginning to warn users against any site lacking this protection. Services such as Cloudflare and Netlify will add this for you, but if you're running your own server, tools such as Caddy are available which will setup TLS hassle free.


To optimise assets, I turned to the built in asset bundler in the Netlify panel (available to Pro users, and free for open source projects). If you aren't hosting a static site, you can achieve something similar with tools like Aspax for Node or Gulp for anything else.

Adding an Application Manifest

{
  "name": "TodoMVC",
  "short_name": "TodoMVC",
  "start_url": ".",
  "display": "standalone",
  ...
  View Source

Adding an application manifest really doesn't take too long. If you've worked with JSON before, it's quite simply a case of running through the keys listed here and setting them to suit your app. You'll also need the following meta tag in your header:

<link rel="manifest" href="/manifest.json">
I was initially confused as to which extension I should use, but Addy from Google helped me out over on Twitter:

What's the point of all this? Browsers will notice that you're offering everything a user would need if the app was to be placed onto their home screen, and so it'll ask them if they're interested. If they say yes, your app will appear with a native-like splash screen and in a fullscreen window without any of the browsers usual chrome. If you'd like to know what this looks like in terms of UX, an animation and further explanation is posted here.

Service Workers

New to the web, but being adopted quickly, Service Workers allow you to take control of the network and speed up page load times by deciding yourself what should be cached. When used wisely, they can be of great benefit especially in letting users access your web app even when offline. They can also be used to provide push notifications and more, but that's beyond the scope of this article.

For TodoMVC, I decided the app wasn't likely to change. As a result, I implemented a basic service worker which simply permanently caches requests and serves them up when they are requested again.

if ('serviceWorker' in navigator) {
  //Let's register the ServiceWorker
  navigator.serviceWorker.register('/sw.js').then(function () {
    //We're good to go
    console.log("ServiceWorker registered correctly.");
  }).catch(function (err) {
    console.log("ServiceWorker registration failed: " + err);
  });
}
View Source

Registering the service worker is just a case of checking to see if our browser supports the feature, and if so, calling the register function. This then triggers an install event inside this file, at which point we call self.skipWaiting() to activate the Service Worker immediately rather than after all related tabs have been closed. The code for this is a bit longer, so take a look at GitHub if you're interested. MDN has a great article taking you through the process step by step if Service Workers are new to you.

Conclusion

After making the changes listed above, I've gone from scoring 25/100 on Lighthouse to a full 100%. It only took a few days, and the existing codebase remained almost identical, showing that any app can be turned into a progressive web app with some thought.

If you'd like to take a look for yourself:

  • Here's the original implementation of TodoMVC, which is available on GitHub too. This can be considered my starting point.
  • The final site is here, proudly hosted by Netlify. Netlify makes deploying static sites easy and their website is full of handy documentation to get started.

As you probably already know if you're taking a look at my blog, I'm very enthusiastic about development and along with often writing programs myself I dedicate a fair amount of my time to mentoring younger children in order to teach them vital coding skills. In an article on site TrustedReviews, technology journalist Jason Bradbury made a statement which I personally find baffling: that the recent Government initiatives to educate our children in coding are a "complete waste of time".

I'm strongly compelled to write this article because it seems to be a move in the complete wrong direction. Nonetheless, I respect Jason and his work and following his follow-up on Twitter, will leave out any criticism of the "bad social skills" he initially claimed developers today possess.

The fundamental point of the article, as far as I can tell, is that in years to come his "kids won't need to code because soon computers will just code for them." While I don't know how much coding experience Jason has, I think the key misconception here is that coding is simply a task executed by either a human or a robot. The fact of the matter is, that while coding is necessary to write modern day applications, I think it's a more of a mind-set then a skill. It's about being able to break down a task into a number of smaller steps, and being able to write algorithms which could, for example, solve a Rubik's Cube when followed one by one. Even if a program can be written using "drag-and-drop and a little imagination," as Jason later alludes to, knowing how to efficiently break a task down into this steps is a fundamental skill which should, in my opinion, be taught without doubt.

Delving further into his reasoning, the second point Jason makes is that the future will "just be about being creative." He talks about the fact that what STEM (Science, Technology, Engineering and Maths) is missing is the art, the 'element of creativity'. I agree that this is extremely important, but I don't think this is all that is needed. As a rather specific example of this, many self-taught programmers take a formal course not because they don't have the creativity or understanding but because they lack the established rules which creative individuals have pieced together so that they don't have to. The axioms of development are already established and we should help to teach children how to do something in the generally accepted manor rather than simply in the way in which their mind wanders.

Hopefully this article explains my views clearly, and if you ever do read this Jason, I hope you see that I appreciate the need for creativity. My actual concern is the lack of acknowledgment of the actual discipline of coding itself. I'd love to know what you, and anyone reading this, have to say and I'm always available by email (oliver@oliverdunk.com) or Twitter (@oliverdunk_).

Occasionally, an idea pops into my mind and I instantly dismiss it as crazy. A few weeks ago, however, I had the idea of harnessing the power of modern 'smart home' devices to create more immersive Minecraft experiences. I remembered reading about LIFX WiFi connected light bulbs, and this instantly made me wonder if I could sync the light level of my home with the game. It was a challenge, but I knew that it was possible and therefore couldn't turn it down.

I did a little research, and purchased a bulb for Christmas. Light screwed in, MacBook at hand, I threw together a rough and ready prototype in about an hour. I used a Java API which I found here, and used Spigot to get the light level of my player. In hindsight, actually modding the game may have been better, but my experience meant that I was better starting with an API I already had knowledge in.

As you can see, things worked out pretty well. The next day, I switched over from the Java API I was using to one written in python called lightsd. It was more up to date, and also allowed me to access some extra API methods which helped in cleaning up my code. That's the version you'll find on GitHub. I also made sure that the light never went below a certain level, as I found through experimentation that this could lead to the light turning itself off and it then took several seconds for it to turn back on.

If I was to do more work on this project, I'd like to investigate more into the hardware running on the actual bulb. As you can see in the demonstration, there is a delay between me sending a TCP packet to the bulb and anything happening, which I'd like to be able to fix if possible. A bulb with colour could also be interesting, as with some sampling I could perhaps take the shades of nearby blocks into account.

Overall, I really enjoyed working on this. I'd like to do more projects based around the 'internet of things', but time may say otherwise. If you've got any questions about the project, I'm always avaliable on Twitter.