PWA实战:自如互联网研发部官方APP开发历程

tim111g.jpg

 这两天正值谷歌开发者大会在上海召开,(谷歌开发者大会2017官网)。朋友圈中出现了一条大会上关于PWA的状态,恰巧丽姐也我和说到了pwa应该学一学。这就勾起了我对这个pwa到底是啥的好奇心。丽姐说,那就先做一个咱们部门自己的APP呗,一期可以只上个值班表。嗯,起源就是这样。

微信图片_20171214134148.jpg

互联网研发部官方APP(PWA版):ziroom.zkbhj.com
 
那既然要用到这个进行开发,首先需要了解什么是PWA,以及开发还需要学习和熟悉哪些相关的知识技术。
 
一、什么是PWA? 
Progressive Web Apps 是结合了 Web 和 原生应用中最好功能的一种体验。对于首次访问的用户它是非常有利的, 用户可以直接在浏览器中进行访问,不需要安装应用。随着时间的推移当用户渐渐地和应用建立了联系,它将变得越来越强大。它能够快速地加载,即使在比较糟糕的网络环境下,能够推送相关消息, 也可以像原生应用那样添加至主屏,能够有全屏浏览的体验。 
  • 渐进增强 - 能够让每一位用户使用,无论用户使用什么浏览器,因为它是始终以渐进增强为原则。
  • 响应式用户界面 - 适应任何环境:桌面电脑,智能手机,笔记本电脑,或者其他设备。
  • 不依赖网络连接 - 通过 service workers 可以在离线或者网速极差的环境下工作。
  • 类原生应用 - 有像原生应用般的交互和导航给用户原生应用般的体验,因为它是建立在 app shell model 上的。
  • 持续更新 - 受益于 service worker 的更新进程,应用能够始终保持更新。
  • 安全 - 通过 HTTPS 来提供服务来防止网络窥探,保证内容不被篡改。
  • 可发现 - 得益于 W3C manifests 元数据和 service worker 的登记,让搜索引擎能够找到 web 应用。
  • 再次访问 - 通过消息推送等特性让用户再次访问变得容易。
  • 可安装 - 允许用户保留对他们有用的应用在主屏幕上,不需要通过应用商店。
  • 可连接性 - 通过 URL 可以轻松分享应用,不用复杂的安装即可运行。

本次开发实践是根据官方的引导指南一步步完成自己的 Progressive Web App,包括设计时需要考虑的因素,也包括实现细节,以确保应用程序符合 Progressive Web App 的关键原则。官方指南的地址在文末有附加。
 需要注意的是:PWA类型的应用,处于安全考虑,只能允许使用HTTPS协议,如果是非HTTPS加密协议,会报错,虽然能够正常浏览页面,但是核心功能已经失效。
Uncaught (in promise) DOMException: Only secure origins are allowed (see: https@//goo.gl/Y0ZkNV). 

 那么本次开发实践,我们将要学会以下几点:
  1. 如何使用 "app shell" 的方法来设计和构建应用程序。
  2. 如何让你的应用程序能够离线工作。
  3. 如何存储数据以在离线时使用。

 
在我们正式开始我们的开发之前,需要熟知以下几个概念:
 
什么是应用外壳(App Shell)

App Shell是应用的用户界面所需的最基本的 HTML、CSS 和 JavaScript,也是一个用来确保应用有好多性能的组件。它的首次加载将会非常快,加载后立刻被缓存下来。这意味着应用的外壳不需要每次使用时都被下载,而是只加载需要的数据。

应用外壳的结构分为应用的核心基础组件和承载数据的 UI。所有的 UI 和基础组件都使用一个 service worker 缓存在本地,因此在后续的加载中 Progressive Web App 仅需要加载需要的数据,而不是加载所有的内容。换句话说,应用的壳相当于那些发布到应用商店的原生应用中打包的代码。它是让你的应用能够运行的核心组件,只是没有包含数据。
 为什么使用基于应用外壳的结构?

使用基于应用外壳的结构允许你专注于速度,给你的 Progressive Web App 和原生应用相似的属性:快速的加载和灵活的更新,所有这些都不需要用到应用商店

如何设计应用的外壳?

第一步是设计核心组件
 
首先我们要问问自己:
  1. 需要立刻显示什么在屏幕上?
  2. 我们的应用需要那些关键的 UI 组件?
  3. 应用外壳需要那些资源?比如图片,JavaScript,样式表等等。

 
我们将要创建一个部门给大家用的一个 Progressive Web App 。可能包含的功能比如可以展示我们部门人员的信息,值班表信息,项目列表信息等,基于需求,那么这个APP的核心组件包括:

一个基础的UI架构,菜单,页面中会要用到的基本元素,以及这些相关依赖的js文件、css样式表和图片等。
 
当然这个UI框架有很多种选择,官方推荐的是Web Starter Kit。 ,GIT地址为:https://github.com/google/web-starter-kit
由于我们的目的并不是要做一个功能多复杂的APP,我们的目的是要通过这个简单APP的开发了解和学会PWA的相关知识。
 
 
开发正式开始,首先,我们需要创建一个index.html文件,把我们设计的核心组件的代码都填进去。当然还有相关依赖的js文件、css样式表和图片等。
到这里我们的外壳已经有了,接下来,就是要把他启动起来!
 
在启动代码中,我们将包括(你可以在(js/app.js)的文件夹中找到)。看完了代码结构,我们要认识一个比较牛逼的东西!
 
使用 Service Workers 来预缓存应用外壳

Progressive Web Apps 是快速且可安装的,这意味着它能在在线、离线、断断续续或者缓慢的网络环境下使用。为了实现这个目标,我们需要使用一个 service worker 来缓存应用外壳,以保证它能始终迅速可用且可靠。详细了解Service Worker是什么,可以访问这篇文章来详细了解:https://developers.google.com/web/fundamentals/getting-started/primers/service-workers
 
service workers 提供的是一种应该被理解为渐进增强的特性,这些特性仅仅作用于支持service workers 的浏览器。比如,使用 service workers 你可以缓存应用外壳和你的应用所需的数据,所以这些数据在离线的环境下依然可以获得。如果浏览器不支持 service workers ,支持离线的 代码没有工作,用户也能得到一个基本的用户体验。使用特性检测来渐渐增强有一些小的开销,它不会在老旧的不支持 service workers 的浏览器中产生破坏性影响。

注册 service worker

为了让应用离线工作,要做的第一件事是注册一个 service worker,一段允许在后台运行的脚本,不需要 用户打开 web 页面,也不需要其他交互。

这只需要简单两步:
  1. 创建一个 JavaScript 文件作为 service worker
  2. 告诉浏览器注册这个 JavaScript 文件为 service worker


第一步,在你的应用根目录下创建一个空文件叫做 serviceworker.js 。这个 serviceworker.js 文件必须放在跟目录,因为 service workers 的作用范围是根据其在目录结构中的位置决定的。

接下来,我们需要检查浏览器是否支持 service workers,如果支持,就注册 service worker,将下面代码添加至 app.js中。
//首先判断浏览器是否支持,如果支持,就注册serviceWorker
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register('./serviceworker.js')
.then(function() { console.log('Service Worker Registered'); });
}
缓存站点的资源

当 service worker 被注册以后,当用户首次访问页面的时候一个 install 事件会被触发。在这个事件的回调函数中,我们能够缓存所有的应用需要再次用到的资源。
//定义缓存名称
//缓存名允许我们给缓存的文件添加版本,或者将数据分开,以至于我们能够轻松地升级数据而不影响其他的缓存
var cacheName = 'pwa-ziroom-php-v4';

//设置需要缓存的文件
var filesToCache = [
'./',
'./css/style.css',
*
];

self.addEventListener('install', function(event) {

console.log('Service Worker: Installing....');

event.waitUntil(

//打开缓存
caches.open(cacheName).then(function(cache) {
console.log('Service Worker: Caching App Shell at the moment......');

return cache.addAll(filesToCache);
})
);
});
首先,我们需要提供一个缓存的名字并利用 caches.open()打开 cache 对象。提供的缓存名允许我们给 缓存的文件添加版本,或者将数据分开,以至于我们能够轻松地升级数据而不影响其他的缓存。

一旦缓存被打开,我们可以调用 cache.addAll() 并传入一个 url 列表,然后加载这些资源并将响应添加至缓存。不幸的是 cache.addAll() 是原子操作,如果某个文件缓存失败了,那么整个缓存就会失败!
 
ok,到现在我们已经将要缓存的文件缓存到本地了,但是我们的应用目前还不能离线工作。我们缓存了 app shell 的组件,但是我们仍然需要从本地缓存中加载它们。

从缓存中加载 app sheel

Service workers 可以截获 Progressive Web App 发起的请求并从缓存中返回响应。这意味着我们能够 决定如何来处理这些请求,以及决定哪些网络响应能够成为我们的缓存。
 
self.addEventListener('fetch', function(event) {

console.log('Service Worker: Fetch', event.request.url);

console.log("Url", event.request.url);

event.respondWith(
caches.match(event.request).then(function(response) {
return response || fetch(event.request);
})
);
});
从内至外,caches.match() 从网络请求触发的 fetch 事件中得到请求内容,并判断请求的资源是 否存在于缓存中。然后以缓存中的内容作为响应,或者使用 fetch 函数来加载资源(如果缓存中没有该资源)。 response 最后通过 e.respondWith() 返回给 Web 页面。
 
使用 manifest.json 文件来声明一个应用程序清单
 
Web 应用程序清单是一个简单的 JSON 文件,它给你了控制你的应用如何出现在用户期待出现的地方(比如用户手机主屏幕),这直接影响到用户能启动什么,以及更重要的,用户如何启动它。

使用 web 应用程序清单,你的应用可以: 
  • 能够真实存在于用户主屏幕上
  • 在 Android 上能够全屏启动,不显示地址栏
  • 控制屏幕方向已获得最佳效果
  • 定义启动画面,为你的站点定义主题
  • 追踪你的应用是从主屏幕还是 URL 启动的

告诉浏览器你的程序清单文件
将这段代码添加至你的 index.html 的 <head> 部分:
<link rel="manifest" href="./manifest.json">
一些最佳实践
  1. 将程序清单的链接添加至你站点的所有页面上,这样在用户第一次访问的时候它能够被 Chrome 正确检索到,且不管用户从哪个页面访问的。
  2. 如果同时提供了 name 和 short_name,short_name 是 Chrome 的首选。
  3. 为不同分辨率的屏幕提供不同的 icon。Chrome 会尝试使用最接近 48dp 的图标,比如在 2x 屏上使用 96px 的,在 3x屏上使用 144px 的。
  4. 记得要包含一个适合在启动画面上显示的图标,另外别忘了设置 background_color。

 iOS Safari 的添加至主屏幕元素
<!-- Add to home screen for Safari on iOS -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="ZiPHP">
<link rel="apple-touch-icon" href="./images/icon/168x168.png">

Windows 上的贴片图标
 
<!-- Add to home screen for start menu on Windows -->
<meta name="msapplication-TileImage" content="./images/icon/168x168.png">
<meta name="msapplication-TileColor" content="#6f6f6f">

至此,APP开发完成,你可以把他发布到服务器上进行验证啦!
 
地址:https://zr.zkbhj.com/
 
【援引】 
https://developers.google.com/web/fundamentals/getting-started/codelabs/your-first-pwapp/
https://www.w3cplus.com/pwa/your-first-pwapp.html
 

0 个评论

要回复文章请先登录注册