yuanyuanbyte/Blog

Webpack性能优化系列之 PWA (使用渐进式网络应用程序为我们的项目添加离线体验)

yuanyuanbyte opened this issue · 0 comments

本系列的主题是 Webpack,每期讲解一个技术要点。如果你还不了解各系列内容,文末点击查看全部文章,点我跳转到文末

如果觉得本系列不错,欢迎 Star,你的支持是我创作分享的最大动力。

PWA

渐进式网络应用程序(progressive web application - PWA)可以为我们的项目添加离线体验,使用名为 Workbox 的 Google 项目,帮助我们更简单地为 web app 提供离线支持。

正常情况下,如果停止 server 然后刷新,则网页不再可访问。

比如掘金https://juejin.cn/,有网络时正常访问:

在这里插入图片描述

No throttling改为Offline关闭网络

在这里插入图片描述

再次刷新,网页不可访问:

在这里插入图片描述

淘宝使用了PWA技术,访问淘宝网关闭网络,刷新

在这里插入图片描述

可以看到关闭网络后网页依然可以访问,从network中能看到没有问题的资源基本上都是来自于ServiceWorker,就是来自PWA技术提供的资源

PWA的使用:

添加 workbox-webpack-plugin 插件,然后调整 webpack.config.js 文件:

npm install workbox-webpack-plugin --save-dev

webpack.config.js

  const path = require('path');
  const HtmlWebpackPlugin = require('html-webpack-plugin');
+ const WorkboxPlugin = require('workbox-webpack-plugin');

  module.exports = {
    entry: {
      app: './src/index.js',
      print: './src/print.js',
    },
    plugins: [
      new HtmlWebpackPlugin({
+       title: 'Progressive Web Application',
      }),
+     new WorkboxPlugin.GenerateSW({
+       //1. 帮助serviceworker快速启动
+       //2. 删除旧的 serviceworker

+       //生成一个 serviceworker 配置文件~
+       clientsClaim: true,
+       skipWaiting: true,
+     }),
    ],
    output: {
      filename: '[name].bundle.js',
      path: path.resolve(__dirname, 'dist'),
      clean: true,
    },
  };

完成这些设置,构建项目

...
                  Asset       Size  Chunks                    Chunk Names
          app.bundle.js     545 kB    0, 1  [emitted]  [big]  app
        print.bundle.js    2.74 kB       1  [emitted]         print
             index.html  254 bytes          [emitted]
precache-manifest.b5ca1c555e832d6fbf9462efd29d27eb.js  268 bytes          [emitted]
      service-worker.js       1 kB          [emitted]
...

现在你可以看到,生成了两个额外的文件:service-worker.js 和名称冗长的 precache-manifest.b5ca1c555e832d6fbf9462efd29d27eb.jsservice-worker.jsService Worker 文件,precache-manifest.b5ca1c555e832d6fbf9462efd29d27eb.jsservice-worker.js 引用的文件,所以它也可以运行。你本地生成的文件可能会有所不同;但是应该会有一个 service-worker.js 文件。

我们现在已经创建出一个 Service Worker。

注册 Service Worker

通过在入口文件添加以下注册代码来注册 Service Worker:

index.js

import { mul } from './test';
import '../css/index.css';

function sum(...args) {
  return args.reduce((p, c) => p + c, 0);
}

// eslint-disable-next-line
console.log(mul(2, 3));
// eslint-disable-next-line
console.log(sum(1, 2, 3, 4));

+ /*
+   1. eslint不认识 window、navigator全局变量
+     解决:需要修改package.json中eslintConfig配置
+       "env": {
+         "browser": true // 支持浏览器端全局变量
+       }
+    2. sw代码必须运行在服务器上
+       --> nodejs
+       -->
+         npm i serve -g
+         serve -s build 启动服务器,将build目录下所有资源作为静态资源暴露出去
+ */
+ // 注册serviceWorker
+ // 处理兼容性问题
+ if ('serviceWorker' in navigator) {
+   window.addEventListener('load', () => {
+     navigator.serviceWorker
+       .register('/service-worker.js')
+       .then(() => {
+         console.log('sw注册成功了~');
+       })
+       .catch(() => {
+         console.log('sw注册失败了~');
+       });
+   });
+ }

再次构建项目

现在来进行测试。停止 server 并刷新页面。如果浏览器能够支持 Service Worker,应该可以看到你的应用程序还在正常运行。

在这里插入图片描述

2021/11/19 update

目前来看淘宝已经下线了pwa (简单测试了一下,不严谨),搜了网上以前支持pwa的项目都已经不支持了🙄

2019 年 PWA(Progressive Web App) 凉了吗? - 知乎 (zhihu.com)

来自知乎 作者:张宇昂
确实挺凉的,去年年初给业务加了pwa之后由于各种原因没上本来还以为会掉队,因为那时候pwa已经挺成熟了,结果到现在都没听说有几个应用深度使用pwa。感觉pwa的用处不是很大,网速快的情况那些cache有没有都无所谓。pwa的高级形态还是得像微博的pwa一样可以做成类App的那种体验。然而在历史遗留产物不同页面都是完全不同的应用架构里只能重新编写之前的应用逻辑。在h5只有为app导流的意义下老板并没有意思让你花时间在这种事情上面

参考

查看全部文章

博文系列目录

  • JavaScript 深入系列
  • JavaScript 专题系列
  • JavaScript 基础系列
  • 网络系列
  • 浏览器系列
  • Webpack 系列
  • Vue 系列
  • 性能优化与网络安全系列
  • HTML 应知应会系列
  • CSS 应知应会系列

交流

各系列文章汇总:https://github.com/yuanyuanbyte/Blog

我是圆圆,一名深耕于前端开发的攻城狮。

weixin