Progressive Web Application Development by Example

5 (1 reviews total)
By Chris Love
    What do you get with a Packt Subscription?

  • Instant access to this title and 7,500+ eBooks & Videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies
  1. Free Chapter
    Introduction to Progressive Web Apps
About this book

Are you a developer that wants to create truly cross-platform user experiences with a minimal footprint, free of store restrictions and features customers want? Then you need to get to grips with Progressive Web Applications (PWAs), a perfect amalgamation of web and mobile applications with a blazing-fast response time.

Progressive Web Application Development by Example helps you explore concepts of the PWA development by enabling you to develop three projects, starting with a 2048 game. In this game, you will review parts of a web manifest file and understand how a browser uses properties to define the home screen experience. You will then move on to learning how to develop and use a podcast client and be introduced to service workers. The application will demonstrate how service workers are registered and updated. In addition to this, you will review a caching API so that you have a firm understanding of how to use the cache within a service worker, and you'll discover core caching strategies and how to code them within a service worker.

Finally, you will study how to build a tickets application, wherein you’ll apply advanced service worker techniques, such as cache invalidation. Also, you'll learn about tools you can use to validate your applications and scaffold them for quality and consistency. By the end of the book, you will have walked through browser developer tools, node modules, and online tools for creating high-quality PWAs.

Publication date:
July 2018
Publisher
Packt
Pages
354
ISBN
9781787125421

 

Introduction to Progressive Web Apps

Over 80% of 328 million active Twitter users are mobile. Twitter knew they needed their mobile experience to be faster, more reliable, and engaging. They chose to launch their default mobile experience as a Progressive Web Application (PWA) in April 2017, called Twitter Lite.

Their goals were simple, faster load times, more engagement, and lower data consumption. They were able to achieve all three when comparing general activities to the non progressive web app version:

  • 65% increase in pages per session
  • 75% increase in Tweets sent
  • 20% decrease in bounce rate
"Twitter Lite is now the fastest, least expensive, and most reliable way to use Twitter. The web app rivals the performance of our native apps but requires less than 3% of the device storage space compared to Twitter for Android."
— Nicolas Gallagher, the Engineering Lead for Twitter Lite

This is just one example of online companies reaping the rewards that PWA offers. This book should serve as a starting point to arm you with the basic knowledge and confidence to create your first PWA.

In this book, you are going to learn how to build a PWA which will be ready for production use. In case you haven't created a PWA yet, you will learn how to make a simple PWA in the first part of this chapter.

This chapter will cover PWA fundamentals and the advantages they offer over classic websites and native applications. You will also see how to upgrade an existing 2048 game web application to a PWA. You will learn how to add a web manifest and service worker to the application, enabling PWA features using a localhost web server.

The purpose of this chapter is to get a general idea of how PWAs work, why you want to deliver PWAs, and to give you the skills to easily create PWAs with basic functionalities.

This chapter will cover the following points:

  • The purpose of PWA
  • PWA advantages
  • The basic technical requirements of a PWA
  • The three primary user experience PWA goals
  • How to upgrade an existing website and run it locally

The web as we know it is entering its third decade of existence. Over this time, the web has gone through many changes and enhancements. While the web possesses some great superpowers, it also had its limitations that inhibited it from delivering an experience in parity with native counterparts.

PWAs are a way to apply native browser technology to create web solutions that consumers want to add to their homescreen. Meanwhile, new web APIs are progressing to fill additional gaps in functionality between web and native apps.

The great thing about a PWA is existing websites can easily be upgraded to claim the PWA status. This can unlock new features in browsers and platforms to level up any website.

About a decade ago, not only was the web disrupted, but so was desktop computing when Apple released the iPhone. This ushered in a new era of mobile first computing. That era's web technology was not prepared for this rapid shift from desktops to handheld devices.

Changing to a mobile first world requires more than just responsive design techniques; it requires a new set of native APIs, capabilities, and coding techniques. The HTML, CSS, and JavaScript specifications and browsers have evolved over the past decade, catching up to the consumer expectations of client applications.

Today, we have a very rich set of native APIs and browsers, enabling everything from geo-location to voice input and camera manipulation. There are client platforms designed to provide a rich, mobile first canvas for developers to paint engaging user experiences.

In addition to great native APIs, browsers have added new features in service workers, web manifestations, and have begun requiring HTTPS to enable modern APIs. These three technical features are the core requirements to become a PWA. However, there is much more to the art of making a good PWA. This art requires a different approach to web development.

In this book, we are going to explore the requirements of a good PWA, and how to create new and upgrade existing websites as PWAs. Along the way, we will learn how to leverage new features such as IndexedDB, multi-media, and the Fetch API to add value to our applications.

As this book progresses, you will learn how to use service workers for caching, push notifications, and background synchronization. The next chapter delves into the web manifest file. Chapter 3, Making Your Website Secure, covers the subtleties of upgrading to HTTPS.

This book breaks down technical and experiential requirements so that you can create a good, PWA and demonstrates this with three sample applications:

  • The first application is a simple game, 2048. 2048 was very popular about three years ago and I still find it very addictive. Even though it's a simple game, it will demonstrate how the web can compete on an even level with common native applications.
  • Next, we will create a photo gallery website and see how to use service worker caching to create an application that loads instantly and runs with or without a network. The application will be comparable to many popular podcast players like iTunes and Stitcher.
  • The final application is a consumer event ticket application. This application will demonstrate advanced service worker techniques like cache invalidation. I will also cover tools you can use to validate your applications and help you scaffold them for quality and consistency.

All source code is available on GitHub, with links provided in this book. You're welcome to clone and fork these repositories. Make local copies and modify them as you wish. I would love to see how you enhance the demo applications.

 

Why we needed a new way to build websites

When Apple released the iPhone in 2007, they initially intended that applications to be built using HTML. They provided an initial platform to create web applications. However, Mac developers cried put for a better native application solution and Apple answered. Apple did so with the caveat of taking 30% of the application's revenue and controlling the applications that were distributed through a closed App Store.

The closed App Store violates the openness of the web by introducing a third-party gatekeeper. This creates a layer of delay as Apple reviews your application. The review process can result in your application being censored or denied entry. The one advantage App Store offers is a sense of security and trustworthiness for consumers.

To make the App Store model interesting for Apple, they decided to take a big cut for tax-native applications. In return, Apple handles all payment and distribution infrastructure for applications. However, the web has not had a problem collecting money from consumers, nor a distribution issue.

Credit card merchant accounts typically take 2% to 3% of a transaction. Hosting has become a cheap commodity, often costing $10 or less a month for most websites.

The next perceived problem the web has suffered from is performance. Performance issues are amplified on mobile devices. Smartphones and tablets have underpowered CPUs compared to their desktop counterparts. And while more mobile devices use WiFi, cellular connections, even in the developed world, are still unreliable.

When the iPhone was first released, the web was still very static compared to what we experience today. Up to that point, the web was not a platform with animations and dynamic content.

Over the last decade, rich user experiences have become commonplace on the web with the rise of single page applications and many large frameworks. These changes have been driven in large part due to the user experiences consumers have come to expect from many native applications.

Many developers have tried to hack their way to mimicking native application experiences on mobile devices. This has led to some good progress as well as some bad experiences and coding practices.

Most bad experiences are due to a lack of awareness of the available APIs and how to use them. Poor coding techniques have also created more issues than perceived value.

A common mistake I have seen a lot is the application of server-side architecture in the browser. While outside the scope of this book, it is important to note that for a good modern web user experience, you may have to let go of preconceived notions of how to develop websites.

A prime example of misunderstanding how to use the web platform and the capability gap can be demonstrated by an interview in 2012 with Mark Zuckerberg, at a Tech Crunch event. You can check out the following link for the article: http://tcrn.ch/2hwN6HF

Facebook tried to make the web its primary platform, but due to many engineering mistakes and browser/hardware limitations, they failed. At that point, they switched to native apps as a primary focus and have since created a very large, walled off community of data and interactions.

As you will see later in this book, Facebook dominates the mobile native application space. This leaves very little room for anybody else to gain screen time.

This is where PWAs can empower businesses and organizations to engage with consumers at a deeper level. This book is designed to give you the tools and knowledge to create PWAs to reach consumers for less money and effort. The web possesses several superpowers that native applications can't touch. Now, with emerging native APIs, the web surpasses native applications.

 

Real-world PWA examples

Flipkart, the Amazon of the Indian sub-continent, embraced PWA as soon as the term was first mentioned. In many ways, they are the poster child of doing a PWA the right way.

Flipkart's consumer market consists of customers almost entirely on poor mobile connections. Their mobile devices have limited storage and may or may not have a reliable 3G connection. In fact, 63% reach the site via 2G. A client application experience that loads quickly and works even when the network is absent gives Flipkart a business advantage.

The Flipkart PWA (https://developers.google.com/web/showcase/2016/flipkart) was created by a small team of engineers in 42 days, a small investment on their part that has paid huge dividends by increasing conversions by 70%. These are just some of their published key performance indicators:

  • Users time on the site with Flipkart lite vs previous mobile experience, 3.5 minutes vs 70 seconds
  • 3x more time spent on site
  • 40% higher re-engagement rate
  • 70% greater conversion rate among those arriving via the Add to Homescreen feature
  • 3x lower data usage

Over 50% of the Weather Channel's mobile usage comes from the web. Reaching consumers around the world is a priority. The web offers a reliable channel to reach everyone, which often means lower powered devices. Re-engagement and the delivery of timely information, such as storm warnings, was also very important.

The Weather Channel (https://developers.google.com/web/showcase/2016/weather-channel) created a PWA, implementing push notifications to deliver experiences matching their native application. This upgrade enabled their team to reach 178 countries and deliver weather forecasts while improving their load time:

  • This PWA is now available in 62 languages and 178 countries
  • 80% improvement in load time
  • Based on this successful global test, the team will expand the PWA to its U.S site in 2017

Lancôme (https://developers.google.com/web/showcase/2017/lancome) rebuilt their mobile web presence as a PWA and increased conversions by 17%. As they tracked mobile web usage, passing desktop, Lancôme saw their conversions drop. After considering a native application, they decided investing in the web was the right way to go.

They determined customers were not likely to download a native application, nor use it often. They knew a web presence would have to be done right, as doing so could generate more rewards. They decided to rebuild their web presence from the ground up as a PWA.

Overall benefits:

  • 84% decrease in time until the page is interactive
  • 17% increase in conversions
  • 15% decrease in bounce rate
  • 51% increase in mobile sessions

iOS improvements:

  • 53% increase in mobile sessions on iOS
  • 10% decrease in bounce rates on iOS

Push notification benefits:

  • 8% of consumers who tap on a push notification make a purchase
  • 18% open rate from push notifications
  • 12% increase in conversion rates on recovered carts via push notifications

If you are worried about browsers that do not support PWA technology yet, take note of the iOS statistics. Lancôme is not alone; almost every company embracing PWAs have reported similar improvements on iOS. Later, you will see how to polyfill caching and the Add to Homescreen experience in your applications to achieve similar results.

These are just a few samples of major brands that have adopted PWAs and reported benefits. There are many more smaller businesses also improving because they are building web experiences customers want to use. The great thing is you can start enhancing your existing web site today using examples from this chapter.

 

What are PWAs?

Two years ago, a Google Chrome engineer, Alex Russell, published the landmark blog post defining PWA. You can check the post on the following link: http://bit.ly/2n1vQ2r

With this blog post Alex declared that web could now stand toe to toe with native applications. But it goes beyond just native capabilities being added via service workers, and the Add to Homescreen heuristic also matters when it comes to building a website.

Another Google Chrome engineer, Chris Wilson said that Progressive Web Applications are a new level of thinking about the quality of your user experience.

What the Chrome team and other browsers want you to understand is that user experience is the most important part of your website or application. Browsers are providing you with the foundation to build great applications, but it is still up to you to make these experiences come to life.

I tend to think that there is a confidence issue web developers have compared to native application developers. There is still this perception that native rules everything. However, this is not really true. As we'll see later, there are far more accessible web pages than native applications., and there is much more room to grow your website's brand compared to a native application.

Native applications serve a purpose, and that purpose is starting to fade away. The former head of Opera, Bruce Lawson, a very popular browser on mobile devices, stated (http://bit.ly/2e5Cgry) that native apps are a bridging technology.

That's a very bold statement, comparing the web to native applications. But it's something to think about. There are often many bridging technologies that lead to the real consumable product.

For example, Netflix began by shipping DVDs in the mail. I'm sure you could still do that today, but the vast majority of Netflix members simply stream and download video content to watch. The DVDs were a mere bridging technology to get the company started and form a relationship with a very loyal customer base.

The expenses involved in distributing those DVDs became too much for them to make it their primary distribution channel. As technology improved, which led to an increase in broadband, Netflix was able to shed the bridging distribution technology and focus on the original goal of getting videos and movies the living rooms of members all over the world.

In much the same way, mobile was a brand-new platform for building application experiences. And just like desktop computing, it started with native applications, and the web eventually won them over. The web won the desktop just as mobile technology emerged, and it emerged in a big way.

PWA signify a retooling of the web to make it a mobile first platform. Your applications can run faster, work offline, and ask users for permission to be on their homescreen. Never before have we been able to deploy these experiences at this level on the web.

Peak app

Smartphone owners always lookout to download apps they think will be useful. If you are fortunate enough to have a consumer download your application, then odds are that they will delete it after one use if they find it troublesome or difficult to use.

According to a Nielsen study (http://www.nielsen.com/us/en/insights/news/2015/so-many-apps-so-much-more-time-for-entertainment.html) that average adult uses less than 30 apps per month. Over time the lack of using an app leads to the unused apps being purged.

Several studies estimate roughly 10% of apps are used enough times to be retained. This means even if your app is downloaded the odds are it will eventually be removed and probably never used.

Brands are spending between $8-12 in advertising to earn a single application download. This means the true customer acquisition cost is roughly $80-120. Good luck recuperating that expense.

The Apple and Google App Store's boast of 2 million or more applications. Some, dated, research shows nearly 60% of apps are never downloaded.

Apple recently made the barrier to success even higher by enforcing section 4.2.6 of their application guideline requirements. This section gives them the authority to reject and remove apps at their discretion. They have been purging apps in mass they don't consider meet these arbitrary guidelines.

Why have consumers stopped downloading applications? Space, both physical and temporal. Mobile phones and tablets only have so much disk space. Many applications now need 100 MB-1 GB of space. While a few 128 GB iPhones are sold, the typical iPhone size is 32 GB. After personal photos, videos, and music, there is little to no room for applications.

While we have become a society that can never seem to leave our mobile screens, there is still only so much time in a day. Market analysts pay close attention to what we do with our screen time. Kids watch videos and play silly games. Adults live in social media with Facebook and Snapchat owning their phones. Adults also play silly games, such as 2048.

Out of the top five applications one these App Stores, Facebook owns three. The average adult spends over 2 hours a day in the Facebook universe looking at photos and videos. Text messaging is being replaced with Facebook Messenger. Millennials are addicted to Instagram, sharing, liking, and commenting on photos and videos non-stop.

Facebook, Facebook Messenger, and Facebook-owned Instagram are the top three mobile applications. They are followed by YouTube, SnapChat, and Gmail. Two of those are owned by Google. After those applications, the distribution curve drops to nearly zero.

We, mobile consumers, have settled into usage habits and have found that the need for applications has passed.

Installing an application, even if it is free, consists of eight steps, each step losing 20% of the initial interested base. The reason Amazon implemented one click purchasing was to eliminate friction and increase sales.

The web is relatively frictionless. You click a link in an email or maybe search for something, clicking the best perceived result, and within a few seconds you have downloaded or installed the web page you need. Little to no friction and next to no device resources have been used.

In contrast to the distribution of app usage in a given month, the average consumer visits over 100 websites. That is roughly 20 times more variety than their application distribution. This means there is more opportunity to engage customers via the web than native applications.

The web satisfies two important consumer requirements of minimal resource investment. Very little time or disk space is needed. In fact, they do not need to uninstall your website when they clean out their device so that they can make more videos to share on Instagram.

This is where PWA have risen in importance. Companies want their icons on consumer's devices. This symbolizes a relationship and hopefully increases sales or other engagement statistics. When brand engagement is cheap for the customer, they are more likely to take the step to make you part of their daily life.

Browsers are providing the engagement platform, but you still need to meet their requirements. That is what you are going to learn in this book.

PWA features

Don't mistake PWAs as a specific technology. It is more of a marketing term describing the usage of modern platform features to provide a certain quality of experience. Without good user experience, the technology does not matter.

The Chrome team has identified four experience factors a PWA should offer:

  • Fast
  • Reliable
  • Engaging
  • Integrated

Research has shown that 53% of users will abandon a site if it takes longer than 3 seconds to load. Service worker caching makes page load time almost instant, but it cannot make animations faster. This requires knowledge of CSS animations and possibly JavaScript.

Applications that stutter or jump around the screen are said to be janky. If you have ever loaded a web page, for example, almost any news website, and had the content jump up or down just as you start reading, you know what I am talking about. This is a very poor user experience and can easily be avoided with proper coding practices.

Later in this book, you are going to learn about RAIL (Response, Animation, Idle, Load) and the PRPL (Push, Render, Pre-cache, and Lazy- load) patterns. These are coding best practices offered by the Chrome team because they understand how browsers work. They, and the other browsers, want the web to work for everyone.

Browser vendors are offering guidance to help developers create the class of web applications that will earn a place on customer's homescreens. This guidance starts with a mobile performance first approach.

Consumers need to have confidence in an application, and they need to know that the application is reliable. This means it should just work when called upon. To enable this, a web application should load if the device is online, offline, and anything in-between.

Service worker caching provides a proxy layer between the browser and the network. This makes the network a progressive enhancement. It also introduces a new class of programming web developers must master.

Later in this book, you are going to learn about different caching strategies and how to employ them in different scenarios to make websites just work.

Service workers open up a new layer of opportunity where web developers can add valuable features that improve performance, engagement, and data management. Service workers are designed to be extensible so future capabilities can be added. Right now, caching, push notifications, and background sync are supported, but there are many other features being debated in the W3C working groups.

Push notifications give you the ability to connect with a consumer any time you wish, increasing engagement. As shared earlier, both the Weather Channel and Lancôme increased engagement via push notifications.

Background sync is a channel you can now use to let your application run when the network is unavailable. When connectivity is restored, you can seamlessly synchronize with the server without disrupting the user. Their phone may even be in their pocket while your application catches up.

A web application needs to engage users enough that they will want to make it a permanent fixture on their devices. Once your web application has the minimum technical requirements—a web manifest, registered service worker with a fetch event handler, and served via HTTPS—the browser triggers native prompts for the user to add the web application to their homescreen. You will delve more deeply into this experience as this book progresses.

The web manifest, HTTPS, and service worker require different expertise to execute effectively. And in my opinion, they increase in complexity from the latter. That is why embracing PWA is often called a journey. It's something you can, and should, implement in steps.

 

PWA advantages

I teased you with the advantages the web has over native applications, but how do these advantages elevate the web's past native applications?

Let's borrow a demonstration from the Chrome team. An XY graph can show the differences between the web and native applications. The vertical axis represents Capabilities. The x-axis represents Reach. The reach being defined is how easy it is to discover and quickly access the application or website:

For many years, native applications enjoyed a capability advantage. They had tight native platform APIs and hooks that enabled native applications to do things that the web was not designed to do. For example, native push notifications allow brands to send messages to customers without the application being open.

However, apps are gated behind closed App Stores on Apple, Android, and even the Microsoft ecosystem. This makes finding applications very difficult. Many estimates show it takes between $8 and $12 a day to get a single app download.

The web, as I mentioned earlier, simply was not ready for this shift to mobile. There have been several APIs such as geo-location and some web notification capabilities. These APIs are not necessarily on the same level with their native counterparts.

Developers have lacked awareness of many modern APIs. Unfortunately, this lack of knowledge and confidence has caused websites to not take advantage of these capabilities.

Ten years ago, responsive design did not exist. However, today, not only do we have CSS media queries and a vast array of responsive CSS libraries, but we also have responsive images built-in to browsers. Now, websites can offer layouts and download appropriately sized images for all screen sizes without crazy hacks.

Compared to their native counterparts, websites have always been easily discoverable. You can advertise a domain in any media channel and people know how to load it. Search engines are much more sophisticated than App Stores and provide an easy interface to find just about anything. The big advantage search engines have over App Stores is the ability to deeply index web content.

Search engines index pages deep within a website and thousands upon thousands of web pages per site. App stores can only offer a single point of entry to download the app. The only page you have control of is a sales page. In that one page, you need to sell your app without the customer sampling your content and experience. Reach is and has always been the web's greatest superpower:

As the graph visualizes, the web is not only on equal footing with native applications—it exceeds native applications is most cases. Sure, there are still going to be edge cases where a native application is the best choice, but these are shrinking every time a browser adds a new feature.

 

PWA technical requirements

At a minimum, there are three core technical requirements to be a PWA. A website must have a web manifest file, be served using HTTPS, and must register a service worker with a fetch event handler. You will dive deeper into each one of these requirements in future chapters.

The web manifest drives the Add to Homescreen experience. HTTPS provides a layer of security and trust between your application and the browser. The service worker provides the extensible backbone for event-driven functionality to execute on a separate thread from the user interface.

A PWA should also use an application shell or common HTML and CSS. This is the most common application of Chrome, which is used on just about every page on the site. If you have any experience with single page applications, you should understand what an application shell is.

The application shell

A typical application shell typically contains a header, a main content area, and a footer. Of course, this can vary by application and site. The 2048 game differs because there is only one web page:

Application shells are common-place in single page applications because they dynamically render markup and data in the browser. This does not need to be the case with a PWA. The reason single page applications are so popular is their ability to create a more native-like transition experience because there is no request delay when a new page is requested.

Since a PWA can be cached locally, this does not mean you need a true application shell. If the application utilizes a cache first strategy, pages can load in a matter of milliseconds, often less than 100. This is perceived as instant by the human mind.

This does not mean you should not identify an application shell. Server and build rendering engines can use the application shell and an array of layouts to create server hosted markups. You will be exposed to this so that you can work as we build the photo gallery and podcast application.

 

2048

A few years ago, a popular application was a simple game called 2048. The goal is to combine blocks with numbers to ultimately total 2048. Blocks are numbered in multiples of 2. You can combine adjacent blocks with the same value to create a new block with their combined value.

I wasted more time playing this game than I care to admit. It is easy to play and highly addictive. A well-crafted brew of endorphins and gameplay.

Fortunately, there were numerous open source knock-offs available on GitHub. Several were web applications. I would wager that native versions distributed through app stores were websites wrapped in a native shell, a hybrid application.

I chose a popular repository to fork for the book. The 2048 web application is simple and a perfect candidate to demonstrate how to make an exemplary PWA example:

The source code

The original application source code is available on GitHub (https://github.com/gabrielecirulli/2048). You can clone the repository and open it in a browser to play the game. Just be forewarned that it is addictive and could distract you from learning how to create PWAs.

I forked the repository in my GitHub profile (https://github.com/docluv/2048). My version adds the manifest, icons, service workers, and applies some code upgrades to make the application perform better and take advantage of newer APIs and browser features. The original code was written very well, but this was for browser capabilities of 3 years ago.

Feel free to star, clone, and fork my GitHub repository to customize it to your liking. A working version of the final application created in this book is available online (https://2048.love2dev.com/).

The application's code structure

Let's review how the game's source code is structured. I like this project because the code is simple and demonstrates how much can be accomplished with a small amount of code in the browser.

There are three asset folders: js, meta, and style. They contain JavaScript files, images, and style sheets that are needed to render and execute the game.

You will also notice a node_modules folder. I added a local web server using grunt connect, which is a node module. The original game works just fine if you load the index.html file directly in the browser. However, due to security constraints, a service worker does not function without a web server. I will cover this in more detail shortly.

At the root-level, there are only handful of web application files:

  • index.html
  • manifest.json
  • sw.js
  • favicon.ico

The nice thing about the 2048 code is that it only requires a single HTML file. The manifest.json and sw.js files add the PWA functionality we are after. The favicon.ico file is the icon loaded by the browser for the address bar:

Adding node modules to the project

The original repository is a stand-alone game, meaning it does not require a web server to execute, just a browser. You can right-click the index.html file and choose to open it in your favorite browser. You can still do this after registering a service worker and may not notice any differences. But if you open the browser console (F12 Developer Tools), you will most likely see an error.

This error can be attributed to service worker requirements. Service workers, like most new APIs supported by browsers, require HTTPS protocol. This requirement raises the default security level and gives the browsers a minimum level of trust in your site ownership.

The service worker specification relaxes this requirement for localhost addresses. Localhost is a common way to reference your local machine, which is typically a development environment. Because it is unlikely you are going to hack yourself, browsers tend to let you do what you want—except when you open files directly from the file system.

When localhost is used to load an asset, the browser is making a traditional network request, which requires a web server to respond. This means you, the user of the local machine, has gone through the effort of launching a local web server. This is not something the average consumer knows how to do.

A file, opened from the file system, is different. Anyone can send you an index.html file that loads scary code, designed to steal your identity or worse show endless loops of cat videos! By not honoring the direct file system, access browsers are protecting you from registering a malicious service worker script. Trusting a localhost web server makes development easier by avoiding the messy process of registering a localhost SSL certificate.

There are a variety of local web servers you can run. In recent years, my preference is node connect, which I execute as a Grunt task (https://love2dev.com/blog/make-a-local-web-server-with-grunt-connect/). Because connect is a node module, you can launch it directly from the command line or a custom script. There are modules for your favorite task runner, such as Gulp and so on. Besides, node is cross-platform, so everyone can use connect.

If you are familiar with installing node modules, you can skip ahead. If node and connect are new to you, this section will serve as a simple primer to get you up and running to run all the samples applications in this book on your local machine.

The first step to loading a node module is to install them from https://www.npmjs.com/ or one of the emerging package manager sites. You can manage this from the command line if you like, or you can define the modules needed in a package.json file.

You can read more about the package.json format here (https://docs.npmjs.com/files/package.json). For our purposes, grunt and the grunt-contrib-connect module are devDependencies. You could also define a dependencies section if this were a node application.

Grunt is a task runner that gained popularity several years ago and is still my preferred task runner. Task runners, and there seems to be a new one every week, help you organize repeatable tasks into repeatable recipes. I use Grunt and custom node scripts to build and deploy my PWAs. Think about your task runner as a command-line control panel to manage your application:

{
"name": "2048",
"version": "1.0.0",
"description": "2048 Progressive Web App",
"author": "Chris Love",
"private": true,
"devDependencies": {
"grunt": "*",
"grunt-contrib-connect": "*"
}
}

Both Grunt and the Grunt connect module are node packages and must be downloaded in order to execute. The package.json file gives npm a configuration so it can manage your packages. This way, you can quickly set up your project on any machine without having to maintain your node dependencies as part of the source code.

If you have cloned the sample repository, you will note that the node modules were excluded from the source code. That's because they are not part of the application itself. They are a dependency and npm helps you recreate the desired environment.

To install the packages, you need to open a command line and change to your source code's folder. Next, you must execute the following command:

>npm install

This kicks off the npm installation process, which downloads your modules and their dependency chain. When completed, you have everything you need to run or build your application.

Next, you will need to create a gruntfile.js. This is where you tell Grunt what tasks you want to run and how you want them to run. If you want to know the details of using Grunt, visit their website (https://gruntjs.com/):

module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-contrib-connect');
// Project configuration.
grunt.initConfig({
connect: {
localhost: {
options: {
port: 15000,
keepalive: true
}
}
}
});
};

Since we are only using the connect module, the 2048 gruntfile is very simple. You need to tell Grunt to load the connect module, then register the task to run in the initConfig function.

2048 is a very simple application, which keeps our customization to a minimum. I arbitrarily chose port 15000 to serve the application and chose to have keepalive open. There are many options you can define. More details are available on the grunt-contrib-connect npm page (https://www.npmjs.com/package/grunt-contrib-connect).

The only task left to do is start the connect web server. This is done from the command line. If you still have the command line open from when you performed the npm install, you can reuse it. If not, repeat the process of opening a command line and changing to the project's folder:

>grunt connect
Running "connect:localhost" (connect) task
Waiting forever...
Started connect web server on http://localhost:15000

Execute grunt connect and you should see the preceding example output. Note that the command continues to execute. This is because it is a server, listening to requests on port 15000. You cannot execute additional commands at this prompt.

You can now load the 2048 game in your browser by entering http://localhost:15000 in the address bar.

Adding a manifest

Adding a web manifest file should be the first step in upgrading an existing website. You can create your site's manifest file in a matter of minutes. In the tooling chapter, I will review a few online resources that can help automate the process.

Registering a PWA's web manifest requires a special link element in the HTML head element. The following code shows how the 2048 manifest file is registered:

<head>
….
<link rel="manifest" href="manifest.json">
</head>

If you are familiar with referencing a style sheet, this syntax should look familiar. The difference is the rel attribute value being manifest. The href value points to the manifest file. You are free to name it anything, but manifest is the most common name.

The next chapter will go into more manifest file details. You can reference the project's manifest.json file to see how the 2048 game is configured. It contains the application's name, default URL, primary colors, and an array of icon image references.

Adding a service worker

Next, you need to register a service worker. This is done in what I call the client-side code, which is the JavaScript you are accustomed to writing. Service workers execute in a separate thread from the UI. I think about it as a background process. You still need to register the service worker for the site.

For simple registrations, like this example, my preferred method is a script block at the bottom of my site's markup. First, detect if service workers are supported. If they are, then attempt to register the site's service work. If the browser does not support service workers, skip the registration code so no exceptions occur.

Registration is done by calling the navigator.serviceWorker.register function. It accepts a single argument, which is a path to the service worker file. I will review more rules around this in later chapters.

The register function returns a promise. You can add code to log successful registration as follows:

      <script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js').then(function
(registration) { // Registration was successful
console.log('ServiceWorker registration successful with
scope: ', registration.scope);
}).catch(function (err) { // registration failed :(
console.log('ServiceWorker registration failed: ',
err);
});
}
</script>

We will start diving into details about service workers in Chapter 5, The Service Worker Life Cycle. To help you understand the example code, let me introduce some service worker fundamentals. Service workers are completely asynchronous. They enter an idle or sleep state if they are not needed. They wake up or spin up completely in response to the operating system or browser firing and events.

All logic execution is a product of events. You must register event handlers to execute your service worker logic. The 2048 service worker registers event handlers for the install, activate, and fetch events.

The 2048 game service worker pre-caches the entire application in the install event. You will learn more about caching strategies in Chapter 6, Master the Cache API – Manage Web Assets in a Podcast Application. For now, we will cache the application so it is available all the time, without any network chatter:

self.addEventListener("install", function (event) {
console.log("Installing the service worker!");
caches.open("PRECACHE")
.then(function (cache) {
cache.addAll(cacheList);
});
});

The 2048 service worker caches assets in the install event. The application assets are defined in an array in the server worker code. The cache API provides an interface to a special storage designed specifically to persist response objects. I will defer the details to later chapters:

var cacheList = [
"index.html",
"style/main.css",
"js/keyboard_input_manager.js",
"js/html_actuator.js",
"js/grid.js",
"js/tile.js",
"js/local_storage_manager.js",
"js/game_manager.js",
"js/application.js"
];

The service worker also has an activate and a fetch event handler. A fetch event handler must be registered before the add to homescreen feature can be triggered.

The fetch event fires when the browser requests an asset from the network. This could be an image, stylesheet, script, AJAX call, and so on. The event parameter contains the request object and can be used to check your cache to see if the asset is available:

self.addEventListener("fetch", function (event) {
event.respondWith(
caches.match(event.request)
.then(function (response) {
if (response) {
return response;
}
return fetch(event.request);
})
);
});

Without a fetch event handler, your application cannot work offline. There is no requirement that the handler catch any requests, just that it is registered. It is a minimal check for offline capability.

In the example fetch event handler, all caches are interrogated to see if there is an existing match to the request. If so, the locally cached version is returned. If not, the request is passed to the network.

That's it; congratulations! Your website is now a PWA, at least on your local machine:

At this point, loading the 2048 localhost site in Chrome should cause an add to homescreen prompt being displayed. If not, reload the page once or twice and apply focus to the browser tab. If you are still not seeing the prompt, check the console for any error messages and debug them accordingly.

 

Summary

In this chapter, you have learned the basics of PWAs by updating a basic game website. We also reviewed what progressive websites are and why they were created.

In the next chapter, you will learn more details about the homescreen prompt experience and how to make a proper web manifest file.

About the Author
  • Chris Love

    Chris Love is a frontend developer with 25 years of professional experience. He has won the Microsoft MVP award for 12 years and has authored multiple books. He has helped over 1,000 businesses of all sizes and from various industries.

    Chris regularly speaks at user groups, code camps, and developer conferences, and also writes articles and videos to help fellow developers.

    When he's not working on frontend development, you can find him spending time with his step-kids, doing karate, and taking part in Spartan races.

    Browse publications by this author
Latest Reviews (1 reviews total)
Super sencillo de realizar la compra en la tienda! :D
Recommended For You
Progressive Web Application Development by Example
Unlock this book and the full library FREE for 7 days
Start now