Skip to content
This repository has been archived by the owner on Jan 20, 2019. It is now read-only.

Add a Service Worker with minimal asset caching to a default Ember CLI application #117

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions active/0000-service-workers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
- Start Date: 2018-03-13
- RFC PR: (leave this empty)

# Add a Service Worker with minimal asset caching to a default Ember CLI application
## Summary
This RFC introduces a Service Worker to the default app blueprint. It will only cache the most essential assets, such as `index.html`, and the vendor and app specific JS and CSS files, it will only respond with those assets if getting the asset over the network fails.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would this work for apps that do not use the index.html file that was output in the /dist folder in production, and instead just point to the assets from a server rendered page? Would the asset cache list be configurable by environment?


## Motivation
A Service Worker allows you to cache assets and other resources in a way that loading a page becomes reliable and fast, independent of what the network conditions are.

Not all Ember applications are destined to become a Progressive Web App, but that doesn't mean that applications shouldn't leverage a simple Service Worker script to somewhat improve the reliability of loading it.

## Detailed design
### Registration
A Service Worker script named `sw.js` should be compiled and placed at the root level of the build result. The Service Worker script should be registered with a registration script that is inlined in `index.html`. The registered Service Worker should have the `rootURL` that is configured in `config/environment.js` as scope.

### Caching
The default Service Worker configuration should only cache the following files:

* `index.html`

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How will this default set be handled for non-standard apps? For example, if you are using prember, and not using SW, then this default gets turned on, it will troll you because what you want for prember is caching all the individual index.html files, and if it does the root one, you get it always trying to load the root page of your app.

* `assets/vendor.js`
* `assets/<app-name>.js`
* `assets/vendor.css`
* `assets/<app-name>.css`

These files are to be returned from the cache when loading them over the network fails.

The cached `index.html` file should be served by the Service Worker whenever a `fetch` event happens that has the request mode of `navigation` and the `accept` header of the request has `text/html` as value.

### Service Worker invalidation
By default each build should include a random sequence of text in the compiled output of `sw.js`, this way the Service Worker gets invalidated after every build.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This random sequence is needed in production or only in development?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also in production. You need this because your index.html file isn't fingerprinted.
An alternative would be for the script to contain a fingerprint of index.html.

Copy link

@sdhull sdhull Apr 28, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@martndemus I attended your PWA training recently at EmberConf. The end of the training focused on cache settings at the CDN/webserver level because sw.js can't be fingerprinted and if it gets cached, users could end up getting stale assets for 24 hours after a deploy.

Does this somehow get around that limitation or would ember devs need to be careful about what gets cached in production?


### Development mode
In development mode the Service Worker script must verify if the current running server is the server of the project it belongs, if its not it should deregister itself.

If the Service Worker cannot reach the development server, because it is not running, a warning should be displayed.

## How we teach this
The Ember CLI documentation should be updated with a notice that a default Ember CLI application registers a Service Worker and explain the functionality of said Service Worker.

It should also include a warning that, when not developing on `http://localhost`, a Service Worker must be served over HTTPS and served from the same origin to function correctly.

It might also be worth to add a few pointers on how to set up developer tools to improve the development experience with an active Service Worker.

## Drawbacks
The Service Worker adds a complex layer of caching that might trip up some developers that don't have a lot of experience with Service Workers. However, in our opinion, the upside of having a Service Worker that improves page loading experience significantly outweighs the cons.

## Alternatives
Instead of adding it by default, it could be added by a generator supplied by Ember CLI.