Manifest is used to make offline pages, even if the network is disconnected, the page can be opened normally, easy to use, but in practice there are the following problems:

(1) How to automatically cache all page resources? Because manifest cannot cache with * wildcards

(2) If the website resources update, how to let the manifest file automatically update? Otherwise, if the user does not know the cache, they will load the old page even though they are connected

I think a lot of websites don’t use Manifest because of the two reasons mentioned above. Some people have tried it, but it’s a hassle to use, and offline apps don’t seem to be worth much. However, there are many benefits to using Manifest, especially for show-oriented sites such as blogs or online apps, where data changes less frequently and requires less frequent requests to services. In this case, when the user needs to frequently return to the home page or frequently switch between several pages, almost all resources are local, so the load is instantaneous.

1. Use the Manifest

Using Manifest is as simple as adding a Manifest attribute to an HTML tag:

<html manifest="/static/manifest/home.appcache">Copy the code

This property points to a manifest file that specifies which resources on the current page need to be cached offline, such as home.appCache:

CACHE MANIFEST
#9/27/2017, 3:04:25 PM
#html
https://github.com/
#img
https://assets-cdn.github.com/images/modules/site/universe-octoshop.png
https://assets-cdn.github.com/images/modules/site/universe-wordmark.png
#css
https://assets-cdn.github.com/assets/frameworks-bedfc518345231565091.css
#js
https://assets-cdn.github.com/assets/compat-94eba6e3cd1fa18902d9.js
NETWORK:
*

FALLBACK
https://github.com/ /html/manifest/html/home.htmlCopy the code

The first line of this file must start with CACHE MANIFEST, otherwise the browser will report an error. The comment starts with #, followed by the resource that needs to be cached, followed by NETWORK, which indicates which resources need to be loaded from the NETWORK. If you do not write a specific path to the CACHE, you will receive a load failure error if the CACHE is not in CAHCE or NETWORK.

This happens even when you’re connected to a network, so it’s usually written as *.

FALLBACK represents an alternative resource, which can not be loaded instead of loading resources, such as the above file https://github.com can not access using a static HTML access: https://github.com/html/manifest/html/home.html.

Open a website that supports Manifest, such as www.rrfed.com, and observe the Chrome console cache process:

Then refresh the page and you’ll see that almost all of the page’s resources are cached locally, as shown below:

And you take the Internet down, refresh the page, and the page still loads. This is supported in Chrome/Firefox/Safari.

In addition to Manifest, another method of caching is to Cache HTTP headers in the cache-Control field. This can Cache JS/CSS/ image resources, but there is a problem if you Cache HTML as well. If the user does not clear the Cache, even if your page is updated, The user will still load the old page until the cache max-age is set. So Manifest solves this problem.

How does Manifest know that the current page data is updated? Just make a change to your manifest file as shown in home.appcache. The browser loads this file when it opens a page, and the next time it sees a change it reloads all the files in the Cache. The simplest way is to change the time in the comment to the current time:

#9/29/2017, 9:08:49 AMCopy the code

So the contents of the manifest can be changed as the site’s resources change, which can then be updated by web-connected browsers.

When using Manifest, note the following:

(1) Manifest has a size limit, which is also considered local storage. Local storage generally has a limited space per domain. PC Chrome is 5Mb, refer to the following table:

Browser Application Cache (AppCache) Storage Limit
Safari Desktop (Mac & Win) Unlimited
Safari Mobile (iOS) 10 MB
Chrome Desktop (Mac & Win) 5 MB *
Chrome Mobile (Android) Unlimited **
Firefox 4 Beta Unlimited (with user prompt)
IE No idea. It sucks. ***

(2) Manifest files such as home.appcahce cannot cross domains, if cross-domains need to support CORS

(3) Manifest Cache resources cannot be cross-domain. If cross-domain resources need to support CORS, general browsers will automatically handle it

2. Solve the problem of automatic generation and renewal of Manifefst

Manifest doesn’t use wildcards to match resources, so it needs to list the resources to cache one by one, and the content of the site is often updated dynamically, so this can be tricky. For this reason, I wrote a NPM package generate-manifest that automatically generates the manifest. It is very simple to use:

npm install -g generate-manifest
generate-manifest --url=https://github.comCopy the code

It generates a home.appchache Manifest file that contains links to img/js/ CSS resources on the page:

CACHE MANIFEST
#9/27/2017, 3:04:25 PM
#html
https://github.com/
#img
https://assets-cdn.github.com/images/modules/site/universe-octoshop.png
https://assets-cdn.github.com/images/modules/site/universe-wordmark.png
#css
https://assets-cdn.github.com/assets/frameworks-bedfc518345498ab3204d330c1727cde7e733526a09cd7df6867f6a231565091.css
#js
https://assets-cdn.github.com/assets/compat-91f98c37fc84eac24836eec2567e9912742094369a04c4eba6e3cd1fa18902d9.js
NETWORK:
*

FALLBACK
https://github.com/ /html/manifest/html/home.htmlCopy the code

Additional parameter customization is also supported, as described in generate-manifest.

This solves the problem of automatic generation. What about automatic updates?

Since I am a blog site, the main changes of the site content are: 1. 2. Users post comments; 3. The first solution to this problem is to create an interface that generates a new manifest file whenever a blog post is posted:

https://www.rrfed.com/refresh-manifest.php?link=https://www.rrfed.com/2017/09/26/manifest/

Appcache file, which is named according to the last section of the manifest path in the HTML:


      
    $uri = "$_SERVER[REQUEST_URI]";
    $uriArray = explode("/", $uri);
    $uriName = count($uriArray) > 2 ? $uriArray[count($uriArray) - 2] : "home";
? ><! DOCTYPE html> <html
       language_attributes(); ? > manifest=
       echo "/html/manifest/appcache/$uriName.appcache"? >>Copy the code

This corresponds to the generated file name.

Second problem: user comment – automatically call this interface in the callback interface. Note that this interface needs to be anti-script injection, otherwise it is dangerous.

Add a scheduled task with crontab. Run crontab -e to add a scheduled task:

0 3 * * * /home/fed/manifest/update-all.shCopy the code

At 3:00 p.m. each day run the update-all.sh script, which contains all the updates to the page:

generate-manifest --url=https://www.rrfed.com
generate-manifest --url=https://www.rrfed.com/page/2/
generate-manifest --url=https://www.rrfed.com/page/3/
#.. The other...Copy the code

The post mentioned in the first point also adds a line of command to the script.

Since reading is not very important, update it once a day. This allows the user to cache all operations on the same day. Update it if you come back the next day.

So that basically solves the auto-update problem.

Another problem is that the first refresh of the Manifest is still the same page, and only the second refresh is correct, so we want to refresh the Manifest to be the new one, not the cached one, and not have to swipe it twice.

So what to do? The Manifest file has an update event, which is triggered whenever there is an update to the Manifest file, so we can listen for this event and automatically refresh the page to reload it.

function onUpdateReady() {
    window.location.reload(true);
}
window.applicationCache.addEventListener('updateready', onUpdateReady);
if(window.applicationCache.status === window.applicationCache.UPDATEREADY) {
    onUpdateReady();
}Copy the code


In summary, Manifest is a great way to make an offline page application that solves the problem of auto-generation and auto-updating. Even if the user is not offline, the second load of resources is cached locally, so this is fast when the user switches back and forth between several pages, as many people might do between the list of the home page and the content page.

Although Manifest has been deprecated and replaced by the Service Worker, it is still usable because of its ease of use and compatibility.


Related reading:

  1. Why upgrade to HTTPS
  2. How to upgrade to HTTP /2