In the previous article we made some basic introductions to progressive Web applications (PWA).
Progressive web App (PWA) Getting Started tutorial (top)
In this section, we'll show you what the principle of PWA is and how it began to work.
First step: Use HTTPS
An incremental Web application requires an HTTPS connection. While using HTTPS can make your server more expensive, using HTTPS will make your site more secure, and HTTPS sites will be ranked more forward on Google.
Since Chrome will default to localhost and 127.x.x.x addresses as test addresses, you do not need to turn on HTTPS in this example. In addition, for debugging purposes, you can use the following parameters to turn off the Web site HTTPS check when you start the Chrome browser:
- --user-data-dir
- --unsafety-treat-insecure-origin-as-secure
Step Two: Create an application manifest (Manifest)
The application manifest provides information about the current progressive Web application, such as:
- Application Name
- Describe
- All images (including home screen icons, splash screen pages and images used or images used on the web)
Essentially, a program manifest is metadata for resources such as icons and themes used on the page.
The
Program manifest is a JSON file that is located in your app's root directory. When the JSON file returns, you must add content-type:application/manifest+json
or content-type:application/ JSON
HTTP header information. The file name of the program manifest is not limited to Manifest.json
in the sample code for this article:
{"name": "PWA Website", "short_name": "PWA", "Descrip tion ":" An example PWA website "," Start_url ":"/"," Display ":" standalone "," orientation " : "Any", "Background_color": "#ACE", "Theme_color": "#ACE", "Icons": [{"src": "/image S/logo/logo072.png "," Sizes ":" 72x72 "," type ":" Image/png "}, {" src ": "/images/logo/logo152.png", "Sizes": "152x152", "type": "Image/png"}, {"src" : "/images/logo/logo192.png", "Sizes": "192x192", "type": "Image/png"}, { "src": "/images/logo/logo256.png", "Sizes": "256x256", "type": "Image/png"}, {"src": "/images/logo/logo512.png", "Sizes": "512x512", "type": "Image/png " } ]}
After the program manifest file is established, you need to reference the file on each page:
<link rel= "manifest" href= "/manifest.json" >
The following properties are frequently used in the program manifest and are described below:
- Name : app names that the user sees
- short_name: apply short name. This name is used when there is not enough space to display the app name.
- Description: application description.
- Start_url: Apply start path, relative path, default =/.
- Scope: The URL range. For example: If you set "/app/" to a URL range, the app will always be in this directory.
- Background_color: Welcome page background color and browser background color (optional)
- Theme_color: The applied theme color, usually the same as the background color. This setting determines how the app is displayed.
- Orientation: Priority rotation direction, selectable values are: Any, natural, landscape, landscape-primary, Landscape-secondary, Portrait, Portrait-primary, and Portrait-secondary
- Display : show Mode--fullscreen (no chrome), standalone (same as native app), Minimal-ui (minimal set of UI controls) or browser (oldest using browser tag display)
- icons: An array containing all the pictures. Each element in the array contains the URL, size, and type of the picture.
Step three: Create a Service Worker
A Service Worker is a programmable server proxy that can intercept or respond to network requests. A Service Worker is a single JavaScript file located at the root of the application.
You need to register the Serviceworker in the JavaScript file that corresponds to the page:
if (' Serviceworker ' in navigator) { //Register service worker Navigator.serviceWorker.register ('/ Service-worker.js ');}
If you don't need offline features, you can create just one /service-worker.js
file so that users can install your web app directly!
The concept of Service worker may be difficult to understand, it is actually a standard worker working in other threads, it can not access the DOM elements on the page, there is no API on the page, but can intercept all the Web requests on the page, including page navigation, request resources, AJAX requests.
Above is the main reason to use the whole station HTTPS. Assuming you're not using HTTPS in your site, a third-party script can inject his own serviceworker from another domain name, and then tamper with all of the requests – which is certainly dangerous.
A Service Worker responds to three events: Install,activate and Fetch.
Install Event
The event is triggered after the app installation is complete. We typically use the cache API here to buffer some of the necessary files.
First, we need to provide the following configuration
- Cache name (cached) and version. An app can have multiple cache stores, but only one of the cache stores is used when it is used. The new version number is assigned to the cache store whenever there is a change in the cache storage. The new cache store will be stored as the current cache, and the previous cache storage will be invalidated.
- An offline page address (offlineurl): The page will be displayed when the user accesses an address that has not been previously visited.
- An array that contains all the necessary files, including CSS and JavaScript that guarantee the normal function of the page. In this example, I've also added a home page and logo. When you have different URLs pointing to the same resource, you can also write these URLs into the array. OfflineURL will be added to this array.
- We can also put some non-essential cache files (installfilesdesirable). These files will be downloaded during the installation process, but will not trigger an installation failure if the download fails.
Config file const Version = ' 1.0.0 ', CACHE = version + '::P wasite ', offlineurl = '/offline/', installfilesessential = [ '/', '/manifest.json ', '/css/styles.css ', '/js/main.js ', '/js/ Offlinepage.js ', '/images/logo/logo152.png ' ].concat (offlineurl), installfilesdesirable = [ '/favicon.ico ', '/images/logo/logo016.png ', '/images/hero/power-pv.jpg ', '/images/hero/ Power-lo.jpg ', '/images/hero/power-hi.jpg ' ];
installStaticFiles()
The Promise method uses the cache API to store files in the cache using a file-based approach.
Install the static resource function Installstaticfiles () { return Caches.open (Cache ). Then (cache = { //buffer optional files Cache.addall (installfilesdesirable); Cache must file return Cache.addall (installfilesessential); }); }
Finally, we add an install
event listener. waitUntil
method ensures that the service worker is not installed until its associated code is executed. Here it executes installStaticFiles()
the method and then self.skipWaiting()
methods to activate the service worker:
Application installation Self.addeventlistener (' Install ', event = = { console.log (' service Worker:install '); Caches primary file Event.waituntil ( installstaticfiles () . then (() = Self.skipwaiting ()));
Activate Events
This event occurs when the service worker is activated. You may not need this event, but in the example code, we clean up the old cache when the event occurs:
Clear Old Cachesfunction clearoldcaches () { return Caches.keys () . Then (keylist + = { return Promise.all ( keylist . Filter (key = key!== CACHE) . Map (key = Caches.delete (key)) ; }); Application Activatedself.addeventlistener (' activate ', event = { console.log (' service worker:activate '); Delete old caches Event.waituntil ( clearoldcaches ()-Then (() = Self.clients.claim () ));
Note that the self.clients.claim()
current service worker will be used as the active worker at execution time.
Fetch event This event will be initiated when the network starts a request. In this event handler, we can use the respondWith()
method to hijack the GET request for HTTP and then return:
- Resource files that are taken from the cache
- If the first step fails, the resource file is fetched from the network using the Fetch API (regardless of the fetch event in the service worker). The retrieved resources will be added to the cache.
- If both the first and second steps fail, the correct resource file is returned from the cache.
Application Fetch network Dataself.addeventlistener (' fetch ', event = { //Abandon Non-get requests if (Eve Nt.request.method!== ' GET ') return; Let url = event.request.url; Event.respondwith ( caches.open (Cache) . Then (cache = { return Cache.match (event.request) . Then (response = { if (response) { //return cached file console.log (' Cache fetch: ' + URL); return response; } Make network request return Fetch (event.request) and then (newreq = { console.log (' Network fetch: ' + URL); if (Newreq.ok) cache.put (Event.request, Newreq.clone ()); return newreq; }) App is offline . catch (() = Offlineasset (URL));});) ; });
offlineAsset(url)
Method uses some helper methods to return the correct data:
Is it a picture address? Let Iext = [' png ', ' jpg ', ' jpeg ', ' gif ', ' webp ', ' BMP '].map (f = = ') ' + f '); function isimage (URL) { return Iext.reduce (ret, ext) = RET | | url.endswith (EXT), false); } //Return returns the offline resource function Offlineasset (URL) { if (isimage (URL)) { //returns the picture return new Response ( ' <svg role= "img" viewbox= "0 0" xmlns= "http://www.w3.org/2000/svg" ><title>offline</title> <path d= "M0 0h400v300h0z" fill= "#eee"/><text x= "$" y= "all" text-anchor= "middle" dominant-baseline= "middle" Font-family= "Sans-serif" font-size= "fill=" #ccc ">offline</text></svg>", {headers: { ' Content-type ': ' Image/svg+xml ', ' cache-control ': ' No-store '} } ); else { //return page return Caches.match (OfflineURL);} }
offlineAsset()
Method checks whether the request is a picture, and then returns an SVG file with "offline" text. Other requests will return to the OfflineURL page.
The Serviceworker section in the Chrome Developer tools provides information about the worker on the current page. It displays the errors that occur in the worker, can also force a refresh, or allows the browser to go offline mode.
The cache Storage section cites all currently cached resources. You can click the Refresh button when the cache needs to be updated.
Fourth step: Create an available offline page
Offline pages can be static HTML, which is commonly used to remind users that the currently requested page is temporarily unavailable. However, we can provide links to pages that can be read.
The Cache API can be used in main.js. However, the API uses promise and will fail in browsers that do not support promise, and all JavaScript execution will be affected. To avoid this, we added a piece of code to check whether the current is in an offline environment when we visited/js/offlinepage.js:
/js/offlinepage.js
The most recent cache is saved in the name of the version number, gets all the URLs, deletes the URLs that are not pages, sorts the URLs, and then displays all the cached URLs on the page:
Cache Nameconst cache = '::P wasite ', OfflineURL = '/offline/', list = document.getElementById (' cachedpagelist '); Fetch all Cacheswindow.caches.keys (). Then (Cachelist = {//find caches by and order by most recent Cacheli St = cachelist. Filter (CName = Cname.includes (CACHE)). Sort ((A, B) + A-a); Open first Cache Caches.open (Cachelist[0]). Then (cache = {//Fetch cached pages Cache.keys ( ). Then (reqlist = = Frag = Document.createdocumentfragment (); Reqlist. Map (req = req.url). Filter (req = (Req.endswith ('/') | | req.endswith ('. html ')) & amp;&!req.endswith (OfflineURL)). Sort (). ForEach (req = = {Let Li = document.createelement (' li '), a = Li.appendchild (Document.createelement (' a ')); A.setattribute (' href ', req); A.textcontent = A.patHname; Frag.appendchild (LI); }); if (list) list.appendchild (Frag); }); }) });
Developer Tools
Chrome offers a range of tools to help you debug service workers, and logs are displayed directly on the console.
You might want to use anonymous mode for development work, which eliminates the cache's interference with development.
Finally, Chrome's Lighthouse extension can also provide some improvements to your progressive web app.
The essentials of Progressive Web applications
Progressive Web applications are a new technology, so be careful when you use them. In other words, progressive web apps can improve your site in a matter of hours, and it won't affect the display of your site in browsers that don't support progressive web apps.
However, we need to consider the following points:
URL hiding
When your app is a single-URL application (like a game), I recommend that you hide the address bar. In addition, I do not recommend that you hide the address bar. In manifest, display: minimal-ui
or in display: browser
most cases enough.
Cache too large
You can't cache all of the content in your site. Caching everything for smaller sites is not a problem, but what if a site contains thousands of pages? Obviously not everyone is interested in all the content on the site. Storage is limited, and if you cache all the pages you have visited, the cache size will grow quickly.
You can develop your caching strategy as follows:
- Only important pages, such as the home page, the contact page, and the most recently viewed article page, are cached.
- Do not cache any pictures, videos and large files
- Regular cleanup of old caches
- Provides an "offline reading" button so that the user can choose which content to cache.
Cache refresh
In the sample code, the cache is queried before the request is initiated. This is good when the user is offline, but if the user is online, he will only be browsing to older pages.
A variety of resources are not changed than slices and videos, so these static resources are generally set to a long-term cache. These resources can be cached directly for one year (31,536,000 seconds). In the HTTP header, it is:
cache-control:max-age=31536000
Pages, CSS and script files may change a bit more frequently, so you can set a relatively small cache timeout (24 hours) and make sure to request from the server again when the user network connection is restored:
Cache-control:must-revalidate, max-age=86400
You can also force the browser to re-request resources each time the site is published by renaming it.
Summary
At this point, I believe you can quickly turn your web app into PWA if you follow the steps in this article. After turning to PWA, if you have the need to use a front-end control that satisfies the PWA model, you can try the pure front-end Table control Spreadjs, and table controls for platforms such as. NET, Java, and mobile will not disappoint you.
Original link: https://www.sitepoint.com/retrofit-your-website-as-a-progressive-web-app/
Progressive Web application (PWA) Getting Started tutorial (bottom)