介绍
PWA(Progressive Web App) 是结合了网络和应用程序体验的产物。不需要安装,本身是Web网页。在手机系统上,还能添加到主屏幕,快速加载,全屏展示,达到接近原生应用的体验。
特点
- 渐进式 - 不会存在兼容性的问题,在不支持的浏览器下会按照正常网页的加载方式
- 响应式 - 可以适配任何屏幕,因为本身就是浏览器打开网页,所以…
- 网络独立 - 没有网或者网络质量低的情况下也能使用
- 自动更新 - 依赖于
Service Workers
的功能
- 可安装 - 可以添加到主屏幕(Android IOS)
- 可链接 - 通过一个URL就可以很容易的分享App
工作方式

依赖于 Service Workers
的功能,可以控制指定的资源请求,通过本地来存储。下次再请求时就不用访问网络了。
笔记应用Demo
- 第一次打开网页,会去服务器下载静态资源(JS,CSS,图片等),然后浏览器渲染,资源存到本地
- 再次打开网页,静态资源都会从本地加载
- 当静态资源更新之后,后台运行的 Service Workers 会下载最新的资源存到本地
网页整体结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Notes</title> <link rel="stylesheet" type="text/css" href="styles/inline.css"> <link rel="manifest" href="/manifest.json"> </head> <body> <main class="main"> <div class="main__inner"> <h1 class="title">Notes</h1> <form class="note__form" id="note-form"> <input id="note-input" class="note__input" name="note-item" placeholder="Input you want note"> </form> <ul id="note-list" class="note__list"></ul> </div> </main> <script src='scripts/app.js' async></script> </body> </html>
|
app.js
- 实现笔记的增加获取
- 绑定 ServiceWorker
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| (function () { 'use strict';
var app = { isLoading: true, noteList: document.getElementById('note-list'), noteCount: 0 };
document.getElementById('note-form').addEventListener('submit', function (e) { app.sumbitNote(); e.preventDefault(); });
app.saveNote = function (noteId, value) { localStorage.setItem('task-' + noteId, value); };
app.getNote = function (noteId) { return localStorage.getItem(noteId); };
app.sumbitNote = function () { var noteNode = document.getElementById("note-input"); console.log('[Note App] sumbit note'); var value = noteNode.value; if (value === '' || value === null) { return } app.saveNote(app.noteCount, value); noteNode.value = ''; app.noteCount++; app.loadNotes(); };
app.loadNotes = function () { app.noteList.innerHTML = ''; for (app.noteCount = 0; app.noteCount < localStorage.length; app.noteCount++) { var nodeId = 'task-' + app.noteCount; var ele = document.createElement('li'); ele.className = 'note__item'; ele.id = nodeId; ele.innerHTML = app.getNote(nodeId); app.noteList.appendChild(ele); } };
app.bindServiceWorker = function () { if ('serviceWorker' in navigator) { navigator.serviceWorker .register('./service-worker.js') .then(function () { console.log('Service Worker Registered'); }); } };
app.bindServiceWorker(); app.loadNotes(); })();
|
service-worker.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| importScripts('scripts/cache-polyfill.js');
var cacheName = 'note-pwa-v1';
var filesToCache = [ '/', '/index.html', 'scripts/app.js', 'styles/inline.css', 'manifest.json', 'imgs/icons/icon-128.png', 'imgs/icons/icon-144.png', 'imgs/icons/icon-152.png', 'imgs/icons/icon-256.png' ];
self.addEventListener('install', function (e) { console.log('[ServiceWorker] Install'); e.waitUntil( caches.open(cacheName).then(function (cache) { return cache.addAll(filesToCache); }) ); });
self.addEventListener('activate', function (e) { e.waitUntil( caches.keys().then(function (keyList) { return Promise.all(keyList.map(function (key) { if (key !== cacheName) { return caches.delete(key); } })); }) ); return self.clients.claim(); });
self.addEventListener('fetch', function (e) { e.respondWith( caches.match(e.request).then(function (response) { return response || fetch(e.request); }) ); });
|
manifest.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| { "short_name": "简记", "name": "最简笔记", "start_url": "/index.html", "background_color": "#eeeeee", "orientation": "portrait", "display": "standalone", "theme_color": "#ffffff", "icons": [ { "src": "imgs/icons/icon-128.png", "sizes": "128x128", "type": "image/png" }, { "src": "imgs/icons/icon-144.png", "sizes": "144x144", "type": "image/png" }, { "src": "imgs/icons/icon-152.png", "sizes": "152x152", "type": "image/png" }, { "src": "imgs/icons/icon-192.png", "sizes": "192x192", "type": "image/png" }, { "src": "imgs/icons/icon-256.png", "sizes": "256x256", "type": "image/png" } ] }
|
Repo
https://github.com/jiyangg/Progressive-Web-Notes