PWA(Progressive Web App)
的概念相信很多人都不陌生,但真正去应用 PWA
的网站确是少之又少,而应用了 PWA
并不等于就是离线WebApp,很多网站虽然用了PWA,但也仅仅是为了加快网站打开速度,并没有完整的实现一个离线WebApp
离线WebApp,顾名思义,即使断网也能够正常使用的网页,会有点难以想象,可以亲自体验一下:https://geek4.wuchen.org ,打开过一次之后(iOS的webview暂不支持离线,需要使用safari打开),再次打开不需要网络,使用上也不会有阻碍。上述网站只是一个demo,这是合合信息第四届极客大赛题目,做一个支出管理的App,可以扫描票据自动录入信息。
如何做一个离线WebApp?
这个问题有点太大,没办法用一句话来回答,我们做一下拆分。
- 如何离线document请求?
- 如何离线css、js、图片、字体等资源请求?
- 如何使用浏览器本地存储?
- 如何设置App的名字和logo?
- 如何实现消息推送?
通常打开一个网页,浏览器会先从服务器下载一个document文档,然后下载对应的js和css资源,可能还会有图片或者字体等资源,最后会发出ajax请求获取数据来展示页面。如果要做离线WebApp,ajax请求则可以放弃,通常使用浏览器来存储用户数据,这有点像是在开发单机游戏。
如何离线document请求?
第一印象可能是 Http Cache
,采用max-age等强制缓存,但之前文章也说过,这种存储方式一般只能设置30天的最长时间,超过30天会变成永久缓存,你的网页可能会永远失去控制。采用强制缓存的缺陷是,无法实时更新,只能等缓存到期之后才能从服务器获取新版本。
我们需要引入 service worker
的概念。service worker
是 web worker
的一个变种,web worker
是主线程之外的另一个线程,可以用来执行一些复杂且耗时的操作,service worker
也是一个线程,但它可以让开发者控制主线程的所有网络请求,类似于 nginx
的反向代理。利用 service worker
,我们可以将document请求缓存下来,下次请求,则从缓存中读取,而且它自带更新机制。
如何离线资源请求?
同样的,service worker
也可以帮我们缓存资源文件,而且可控性比 Http Cache
强制缓存要更好。
<html>
<head>
<title>找到</title>
</head>
<body>
<script src="app.12345.js"></script>
</body>
</html>
上面这个document,依赖一个12345版本的app.js,只要document不更新,那相应的依赖的资源也不会变化。所以资源一般是跟随document一起缓存的,这样整个站点都被缓存下来,也就实现了离线WebApp的基础框架。
如何使用浏览器本地存储?
浏览器本地存储有以下几种:
cookie
: 这个一般是与服务器交互的时候会用到,每一个请求都会携带cookie信息localStorage
: 本地存储一些简单key-value的信息,但容量有限,一般为2M上限sessionStorage
: 同上,唯一区别是,localStorage
是永久缓存,而sessionStorage
是本tab才有效IndexDB
: 浏览器端的数据库,属于NoSQL类型,非关系型数据库,与MongoDB类似,可以存储大量数据,只要硬盘够用Cache Storage
: 专门为service worker
提供的本地存储,常用于请求的缓存,get与post都能缓存
离线WebApp,除了cookie,基本都会用到。
如何设置App的名字和logo?
我们会用到一个 manifest.json
的配置文件,在原生应用开发中,清单配置文件很常见,在web上也有这么一套规范,可以让开发者给自己网站设定名字、logo、启动路径等信息。
如何实现消息推送?
消息推送在国内暂时无法实施,因为依赖浏览器推送服务。国产浏览器基本不支持 Web Push
机制,chrome支持,但却依赖google,因GFW的问题,我们无法使用google服务。
总结
本文只是离线WebApp这个系列的一个开始,后面将围绕着这几个问题进行展开,最终实现开头给的demo网站。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。