乐趣区

关于pwa:天人合一物我相融站点升级渐进式Web应用PWAProgressive-Web-Apps实践

原文转载自「刘悦的技术博客」https://v3u.cn/a_id_216

PWA(Progressive web apps,渐进式 Web 利用)应用古代的 Web API 以及传统的渐进式加强策略来创立跨平台 Web 应用程序,说白了,PWA 能够让咱们的站点以原生 APP 的模式运行,但相比于装置原生 APP 利用,拜访 PWA 显然更加容易和迅速,还能够通过链接来分享 PWA 利用。

有许多出名的网络平台曾经将 PWA 计划落地,比方 Twitter。抉择加强的网站体验而不是原生利用。事实上应用 PWA 也的确从中取得了不言而喻的好处。https://www.pwastats.com 这个网站上分享了许多案例钻研,PWA 相比于传统利用有以下益处:

1、缩小利用装置后的加载工夫,通过 Service Workers 来进行缓存,以此来节俭带宽和工夫。

2、当利用有可用的更新时,能够只更新产生扭转的那局部内容。相比之下,对于一个原生利用而言,即使是最渺小的改变也须要强制用户去进行热更新或者再次下载整个利用。
3、外观和应用感触与原生平台更加融为一体——利用图标被搁置在主屏幕上,利用能够全屏运行等。
凭借零碎告诉和推送音讯与用户放弃连贯,对用户产生更多的吸引力,并且进步转换效率。

诚然,从零开始研发 PWA 利用会有肯定的老本,但如果咱们自身就领有基于 Web 的站点,那么就能够通过减少对应的配置文件和服务进行降级操作,间接领有 PWA 利用。

HTTPS 服务

首先 PWA 要求站点的申请形式为 HTTPS,如果是生产环境,能够通过为 Nginx 服务器配置 SSL 的形式进行适配,然而线下环境测试 PWA 时就有点吃力了,所以通过 openssl 工具为本地域名 localhost 做自签证书:

openssl req -x509 -out localhost.crt -keyout localhost.key \  
  -newkey rsa:2048 -nodes -sha256 \  
  -days 3650 \  
  -subj '/CN=localhost' -extensions EXT -config <( \  
   printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")

产出:localhost.crt 和 localhost.key 文件,key 是私用密钥 openssl 格局,通常是 rsa 算法。csr 是证书申请文件,用于申请证书,在制作 csr 文件的时,必须应用本人的私钥来签订申,还能够设定一个密钥。

将文件放到我的项目的根目录下,随后在构建我的项目服务的时候配置即可,以 Tornado 为例:

server = httpserver.HTTPServer(app,xheaders=True,ssl_options={  
        "certfile": "./localhost.crt",  
        "keyfile": "./localhost.key",  
    })  
  
# 指定端口  
server.listen(443)

这里通过设置 ssl\_options 参数来导入私钥和证书,同时将端口改为 HTTPS 默认端口号 443。如此,在本地也能够对 PWA 进行测试了,当然了,如果不须要本地操作,也能够跳过这步。

manifest.json 配置文件

为了实现 PWA 利用增加至桌面的性能,除了要求站点反对 HTTPS 之外,还须要筹备 manifest.json 文件去配置利用的图标、名称等信息。

以本站为例,在站点根目录创立 manifest.json 文件:

{  
    "name": "刘悦的技术博客",  
    "short_name": "刘悦的技术博客",  
    "description": "刘悦的技术博客",  
    "icons": [  
        {  
            "src": "https://v3u.cn/v3u/Public/images/pwa192.png",  
            "sizes": "192x192",  
            "type": "image/png"  
        },  
        {  
            "src": "https://v3u.cn/v3u/Public/images/pwa512.png",  
            "sizes": "512x512",  
            "type": "image/png"  
        }  
    ],  
    "background_color": "#FFF",   
    "theme_color": "#FFF",   
    "display": "standalone",   
    "orientation": "portrait",  
    "start_url": "/",   
    "scope": "/"   
}

由上至下,顺次是 PWA 利用的名称、形容、图标文件、banner 色彩、显示方式、开始页面的链接和 PWA 的作用域。为此咱们须要提供两张不同分辨率的站点图标文件:

ServiceWorker 服务

Service Worker 是一个注册在指定源和门路下的事件驱动型 Web Worker。它充当了 Web 应用程序与浏览器之间的代理服务器,进行资源在文件级别下的缓存与操控,拦挡页面申请,实现在不同的状况下对不同申请的响应策略。

Service Worker 实质上就是一个 Web Worker,因而它具备 Web Worker 的特点:无奈操作 DOM、脱离主线程、独立上下文。

Service Worker 还具备这些特点:只能在 Https 下应用、运行在浏览器后盾,不受页面刷新影响、更弱小的离线缓存能力(应用 Cache API)、申请拦挡能力、齐全异步,不能应用同步 API、继续运行,第一次拜访页面后,Service Worker 就会装置激活并继续运行,直到手动销毁。

以本站为例,在站点根目录创立 sw.js 文件,留神 Service Worker 文件地位肯定得在根目录,如果不在根目录也要通过重写或者 url 映射让其能够通过根目录门路进行拜访,如:https://v3u.cn/sw.js,否则浏览器会检测不到 Service Worker 服务:

var CACHE_NAME = 'v3u-cache-v1';  
var urlsToCache = [  
    '/',  
    '/v3u/Public/css/tidy_min.css'  
];  
  
self.addEventListener('install', function (event) {  
    event.waitUntil(caches.open(CACHE_NAME).then(function (cache) {console.log('Open cache');  
            return cache.addAll(urlsToCache);  
        }).then(function () {self.skipWaiting();  
        })  
    );  
}); 

当咱们为页面注册 Service Worker 后,Service Worker 开始进行装置,装置胜利之后,会在 worker 中触发 install 事件;如果装置失败,则进入废除状态。

如果 Service Worker 逻辑文件更新(相干资源文件变动或者外部逻辑更新等),Service Worker 会重新安装,如果这个时候,页面仍然存在激活状态下的 worker(旧的 Service Worker),那么新的 worker 会进入 waiting 状态进行期待,直到咱们被动去操作 worker 强制其更新,或者期待用户敞开所有页面,这个时候新的 worker 才会进入到激活状态。

在 install 事件中,咱们应用 caches.open 办法关上 cache 对象,并通过 cache.addAll 缓存所有咱们列出的文件。如果 Service Worker 存在更新,咱们应用 skipWaiting 跳过期待,间接强制新的 worker 进入激活状态。

随后,增加 fetch 事件:

self.addEventListener('fetch', function(event){if(event.request.method !== 'GET') return;  
        event.respondWith(caches.match(event.request).then(function(response){if(response){console.log('return caches');  
                    return response;  
                }else{return fetch(event.request).catch(function(){if(/\.html$/.test(event.request.url))  
                            return caches.match('/html/neterror.html');  
                    });  
                }  
            })  
        )  
    });

这里只监听了全站的 GET 申请形式,即咱们只心愿管制资源申请。通过 caches.match 查看申请是否命中了缓存,如果命中,则间接返回缓存给用户,避免反复申请,节约资源。如果没有命中,则将应用 fetch 办法申请网络资源并返回给用户。当网络状态异样时(fetch().catch()),返回 404 页面的缓存给用户,告知用户以后处于无网络状态,不能拜访相干页面。指定了一些页面和文件进行缓存,咱们心愿用户在无网络的状况下只能拜访到咱们指定缓存的页面。

当然,还有另外一种状况,咱们指定了一些页面进行缓存(罕用页面),当用户拜访到一些不罕用页面时,再对其进行缓存。这样,咱们能够对资源配置进行优化,不过多的占用用户本地资源去缓存所有页面,因为 PWA 的缓冲自身是存储到客户端的,对于非所有用户的罕用页面,按需缓存:

self.addEventListener('fetch', function(event){if(event.request.method !== 'GET') return;  
        event.respondWith(caches.match(event.request).then(function(response){if(response){console.log('return caches');  
                    return response;  
                }else{return fetch(event.request).then(function(res){var responseToCache = res.clone();  
                        caches.open(CACHE_NAME).then(function(cache){catch.put(event.request, responseToCache);  
                        })  
                        return res;  
                    });  
  
                }  
            })  
        )  
    });

至此,ServiceWorker 服务文件就撰写实现了。

生产环境上线配置:

别离将 manifest.json 和 sw.js 文件别离上传到生产环境之后,在页面的 head 标签中进行申明:

<link rel="manifest" href="manifest.json">

申明后,留神拜访一下是否正确返回:https://v3u.cn/manifest.json

随后在页面中注册 Service Worker 服务:

<script>  
  if ('serviceWorker' in navigator) {window.addEventListener('load', () =>  
        navigator.serviceWorker.register("/sw.js?v0")  
            .catch(() => {}) // ignore  
    );  
}  
</script>

这里首先判断以后浏览器的 navigator 是否反对 serviceWorker,随后应用 navigator.serviceWorker.register 函数来注册 Service Worker。其中,参数为要执行的 worker 逻辑文件门路,留神这个门路是基于 origin 的,而非以后文件。

接着键入组合键,关上 chrome 浏览器的开发者工具:

Mac 零碎上的“⌥+⌘+I”

Win 零碎上的“F12+Ctrl+Shift+I”

在 Chrome 的利用标签下进行查看,看利用清单有没有读出你的 PWA 利用信息配置文件:

随后在 serviceWorker 标签下查看 serviceWorker 是否正确运行:

接着拜访站点,在地址栏即可增加 PWA 利用:

拜访成果:

结语

渐进式加强和响应式设计曾经能够让咱们构建对挪动端十分敌对的站点,而 PWA 则又在咱们的身后轻轻地推了一把,黄河之水源可滥觞,星星之火正在燎原,一年以内,咱们都将感到 PWA 的灼人温度。

原文转载自「刘悦的技术博客」https://v3u.cn/a_id_216

退出移动版