以下方式基于 @vue/cli 快速搭建的交互式项目脚手架
1. 路由懒加载
当打包构建应用时, JavaScript 包会变得非常大, 影响页面加载. 如果我们能把不同路由对应的组件分割成不同的代码块, 然后当路由被访问的时候才加载对应组件, 这样就更加高效了.
结合 Vue 的异步组件和 webpack 的代码分割功能, 轻松实现路由组件的懒加载.
- import Vue from 'vue'
- import Router from 'vue-router'
- import store from './store'
- import Home from './views/Home.vue'
- Vue.use(Router)
- const router = new Router({
- routes: [
- {
- path: '/',
- name: 'home',
- component: Home,
- },
- {
- path: '/make',
- name: 'make',
- component: () => import(/* webpackChunkName: "make" */ './views/Make.vue'),
- }
- ],
- })
2. webpack 动态导入
将 statically import(静态导入) 改为 dynamic import(动态导入) 进行代码拆分
- import(/* webpackChunkName: "html2canvas" */ 'html2canvas').then(
- ({ default: html2canvas }) => {
- html2canvas(document.querySelector('.container'), {
- scale: Windows.devicePixelRatio,
- allowTaint: false,
- useCORS: true,
- }).then(canvas => {
- console.log(canvas.toDataURL('image/jpeg', 0.9))
- })
- }
- )
3. 预取 / 预加载模块 (prefetch/preload module)
在声明 import 时, 使用下面这些内置指令, 可以让 webpack 输出 "resource hint(资源提示)", 来告知浏览器:
prefetch(预取): 将来某些导航下可能需要的资源
preload(预加载): 当前导航下可能需要资源
- import(/* webpackPrefetch: true */ 'LoginModal');
- import(/* webpackPreload: true */ 'ChartingLibrary');
这会生成 <link rel="prefetch" href="login-modal-chunk.js"> 并追加到页面头部, 指示着浏览器在闲置时间预取 login-modal-chunk.JS 文件.
只要父 chunk 完成加载, webpack 就会添加 prefetch hint(预取提示).
与 prefetch 指令相比, preload 指令有许多不同之处:
preload chunk 会在父 chunk 加载时, 以并行方式开始加载. prefetch chunk 会在父 chunk 加载结束后开始加载.
preload chunk 具有中等优先级, 并立即下载. prefetch chunk 在浏览器闲置时下载.
preload chunk 会在父 chunk 中立即请求, 用于当下时刻. prefetch chunk 会用于未来的某个时刻.
浏览器支持程度不同.
vue 默认开启, 可在 vue.config.JS 中全局禁用 prefetch, 再针对指定模块开启.
- chainWebpack: config => {
- config.plugins.delete('prefetch')
- },
4. 添加 Gzip 打包配置 (compression-webpack-plugin)
- yarn add compression-webpack-plugin -D
- configureWebpack: config => {
- const CompressionPlugin = require('compression-webpack-plugin')
- config.plugins.push(new CompressionPlugin())
- }
5. 添加页面预渲染 (prerender-spa-plugin)
在单页应用程序中预呈现静态 HTML, 可以极大的提高网页访问速度, 而且配合一些 meat 插件, 基本可以满足 SEO 需求.
预渲染基本上是在启动无头浏览器, 加载应用程序的路由并将结果保存到静态 HTML 文件中. 然后将其与以前使用的任何静态文件服务解决方案一起使用, 是无需更改代码或添加服务器端渲染的解决方法.
不过, 它仅适用于 HTML5 history, 因为每个预渲染的路由都会生成一个对应的 HTML, 在 hash 模式下使用只会有一个 HTML.
- yarn add prerender-spa-plugin -D
- configureWebpack: config => {
- const path = require('path')
- const PrerenderSPAPlugin = require('prerender-spa-plugin')
- config.plugins.push(
- new PrerenderSPAPlugin({
- staticDir: path.join(__dirname, 'dist'),
- routes: ['/'],
- minify: {
- collapseBooleanAttributes: true,
- collapseWhitespace: true,
- keepClosingSlash: true,
- decodeEntities: true,
- sortAttributes: true,
- },
- renderer: new PrerenderSPAPlugin.PuppeteerRenderer({
- renderAfterDocumentEvent: 'render-event',
- renderAfterTime: 5000,
- // headless: false,
- }),
- })
- )
- }
- new Vue({
- router,
- store,
- render: h => h(App),
- mounted() {
- // 预渲染 renderAfterDocumentEvent.
- document.dispatchEvent(new Event('render-event'))
- },
- }).$mount('#app')
prerender-spa-plugin 利用了 Puppeteer 的爬取页面的功能. Puppeteer 是一个 Chrome 官方出品的 headlessChromenode 库. 它提供了一系列的 API, 可以在无 UI 的情况下调用 Chrome 的功能, 适用于爬虫, 自动化处理等各种场景. 它很强大, 所以很简单就能将运行时的 HTML 打包到文件中. 原理是在 Webpack 构建阶段的最后, 在本地启动一个 Puppeteer 的服务, 访问配置了预渲染的路由, 然后将 Puppeteer 中渲染的页面输出到 HTML 文件中, 并建立路由对应的目录.
6. 压缩 JS, 删除 console(terser-webpack-plugin)
- yarn add terser-webpack-plugin -D
- configureWebpack: config => {
- const TerserPlugin = require('terser-webpack-plugin')
- config.optimization.minimizer.push(
- new TerserPlugin({
- extractComments: false,
- terserOptions: { compress: { drop_console: true } },
- })
- )
- }
7. bundle 分析 (webpack-bundle-analyzer)
将 bundle 内容展示为便捷的, 交互式, 可缩放的树状图形式.
- yarn add -D webpack-bundle-analyzer
- configureWebpack: config => {
- const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
- .BundleAnalyzerPlugin
- config.plugins.push(new BundleAnalyzerPlugin())
- }
- 8. WebP
WebP(发音 weppy), 是一种支持有损压缩和无损压缩的图片文件格式, 派生自图像编码格式 VP8. 根据 Google 的测试, 无损压缩后的 WebP 比 PNG 文件少了 45% 的文件大小, 即使这些 PNG 文件经过其他压缩工具压缩之后, WebP 还是可以减少 28% 的文件大小.
不过 WebP 目前在 iOS 上兼容性不好, 可以使用 JavaScript 进行检测, 对支持 WebP 的用户输出 WebP 图片.
- created() {
- const htmlClass = document.documentElement.classList
- this.checkWebpSupport() ? htmlClass.add('webps') : htmlClass.remove('webps')
- }
- checkWebpSupport() {
- try {
- return (
- document
- .createElement('canvas')
- .toDataURL('image/webp')
- .indexOf('data:image/webp') === 0
- )
- } catch (err) {
- return false
- }
- }
记一次 BUG:
在默认情况下, 页面加载完成执行 this.checkWebpSupport() && document.documentElement.classList.add('webps'), 没有问题.
但使用了 prerender-spa-plugin 进行预渲染后, 因为执行预渲染的浏览器是支持 WebP 的, 所有会直接在页面中加上'webps'类, 所以即使浏览器不支持 WebP, 不执行此方法也会有该类名.
9. 网页性能优化测试 (googlespeed)
进行网页测试, 根据优化建议针对性的修改, 提高网页加载速度.
https://www.googlespeed.cn/
来源: https://www.cnblogs.com/huliang56/p/11887957.html