webpack 快速入门 系列 —— 性能 (7)

注:多个 url 与适配器有关:

> ipconfig 以太网适配器 VMware Network Adapter VMnet1: IPv4 地址 . . . . . . . . . . . . : 192.168.85.1 以太网适配器 VMware Network Adapter VMnet8: IPv4 地址 . . . . . . . . . . . . : 192.168.75.1 无线局域网适配器 WLAN: IPv4 地址 . . . . . . . . . . . . : 192.168.0.103

通过浏览器访问 :8080。如果我们将服务器关闭,再次刷新页面,则不能再访问。

接下来我们要做的事:通过离线技术让网页再服务器关闭时还能访问。

请看示例:

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

> npm i -D workbox-webpack-plugin@6 // webapck.config.js const WorkboxPlugin = require('workbox-webpack-plugin'); module.exports = { plugins: [ new WorkboxPlugin.GenerateSW({ // 这些选项帮助快速启用 ServiceWorkers // 不允许遗留任何“旧的” ServiceWorkers clientsClaim: true, skipWaiting: true, }), ], };

完成这些设置,再次打包,看下会发生什么:

> npm run build Asset Size Chunks Chunk Names 0.main.js 192 bytes 0 [emitted] a 2.main.js 94.6 KiB 2 [emitted] vendors~main index.html 336 bytes [emitted] main.js 2.75 KiB 1 [emitted] main service-worker.js 1.11 KiB [emitted] workbox-15dd0bab.js 13.6 KiB [emitted]

生成了两个额外的文件:service-worker.js 和 workbox-15dd0bab.js。service-worker.js 是 Service Worker 文件。

值得高兴的是,我们现在已经创建出一个 Service Worker。接下来我们注册 Service Worker。

// index.js document.body.onclick = function () { // 动态导入 import(/* webpackChunkName: 'a', webpackPrefetch: true*/'./a').then((aModule) => { console.log(aModule.a); }); }; if ('serviceWorker' in navigator) { window.addEventListener('load', () => { navigator.serviceWorker.register('/service-worker.js').then(registration => { console.log('SW registered: ', registration); }).catch(registrationError => { console.log('SW registration failed: ', registrationError); }); }); }

再次运行 npm run build 来构建包含注册代码版本的应用程序。然后用 npm start 启动服务。访问 :8080/ 并查看 console 控制台。在那里你应该看到:

SW registered

Tip:如果没有看见 SW registered,可以尝试强刷

现在来进行测试。停止 server 并刷新页面。如果浏览器能够支持 Service Worker,应该可以看到你的应用程序还在正常运行。然而,server 已经停止 serve 整个 dist 文件夹,此刻是 Service Worker 在进行 serve。

Tip:更过 pwa 可以参考 "mdn 渐进式应用程序";淘宝(taobao.com)以前有 pwa,现在却没有了。

多进程打包

通过多进程打包,用的好可以加快打包的速度,用得不好甚至会更慢。

这里使用一个名为 thread-loader 包来做多进程打包。每个 worker 是一个单独的 node.js 进程,开销约 600 毫秒,还有一个进程间通信的开销。

注:仅将此加载器用于昂贵的操作!比如 babel

我们演示一下:

未使用多进程打包时间是 3122ms:

// index.js import _ from 'lodash' console.log(_); > npm run build Hash: a4868f457d7ce754335b Version: webpack 4.46.0 Time: 3031ms

加入多线程:

> npm i -D thread-loader@3 // webpack.config.js -> module.exports -> module.rules { test: /\.js$/, exclude: /node_modules/, use: [ 'thread-loader', { loader: 'babel-loader', ... } ] } > npm run build Hash: a4868f457d7ce754335b Version: webpack 4.46.0 Time: 3401ms

构建时间更长。

Tip: 可能是代码中需要 babel 的 js 代码太少,所以导致多线程效果不明显。

外部扩展(externals)

externals 配置选项提供了「从输出的 bundle 中排除依赖」的方法。

externals

防止将某些 import 的包(package)打包到 bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖(external dependencies)。

例如 jQuery 这个库来自 cdn,则不需要将 jQuery 打包。请看示例:

Tip: 为了测试看得更清晰,注释掉 pwa 和 splitChunks。

> npm i jquery@3 // index.js import $ from 'jquery'; console.log($);

打包生成一个 js,其中包含了 jquery:

> npm run build Asset Size Chunks Chunk Names 1.main.js 88 KiB 1 [emitted] vendors~main index.html 336 bytes [emitted] main.js 1.9 KiB 0 [emitted] main

由于开启了 splitChunks,这里 1.main.js 就是 jquery。

使用 external 将 jQuery 排除:

// webpack.config.js module.exports = { externals: { // jQuery 是jquery暴露给window的变量名,这里可以将 jQuery 改为 $,但 jquery 却不行 jquery: 'jQuery' } };

在 index.html 中手动引入 jquery:

// src/index.html <script src="http://cdn.bootcdn.net/ajax/libs/jquery/1.7.2/jquery.min.js"></script>

Tip: 我们使用 bootstrap cdn。

再次打包,则不在包含 jquery:

> npm run build Asset Size Chunks Chunk Names index.html 303 bytes [emitted] main.js 1.35 KiB 0 [emitted] main

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzzjsp.html