Vue項目性能優化整理

以下方式基於 @vue/cli 快速搭建的交互式項目腳手架

1. 路由懶加載

當打包構建應用時,JavaScript 包會變得非常大,影響頁面加載。如果我們能把不同路由對應的組件分割成不同的代碼塊,然後當路由被訪問的時候才加載對應組件,這樣就更加高效了。

結合 Vue 的異步組件和 Webpack 的代碼分割功能,輕鬆實現路由組件的懶加載。

 1 import Vue from 'vue'
2 import Router from 'vue-router'
3 import store from './store'
4 import Home from './views/Home.vue'
5
6 Vue.use(Router)
7
8 const router = new Router({
9 routes: [
10 {
11 path: '/',
12 name: 'home',
13 component: Home,
14 },
15 {
16 path: '/make',
17 name: 'make',
18 component: () => import(/* webpackChunkName: "make" */ './views/Make.vue'),
19 }
20 ],
21 })

2. webpack動態導入

將statically import(靜態導入) 改為 dynamic import(動態導入)進行代碼拆分

 1 import(/* webpackChunkName: "html2canvas" */ 'html2canvas').then(
2 ({ default: html2canvas }) => {

3 html2canvas(document.querySelector('.container'), {
4 scale: window.devicePixelRatio,
5 allowTaint: false,
6 useCORS: true,
7 }).then(canvas => {
8 console.log(canvas.toDataURL('image/jpeg', 0.9))
9 })
10 }
11 )

3. 預取/預加載模塊(prefetch/preload module)

在聲明 import 時,使用下面這些內置指令,可以讓 webpack 輸出 "resource hint(資源提示)",來告知瀏覽器:

  prefetch(預取):將來某些導航下可能需要的資源
  preload(預加載):當前導航下可能需要資源

import(/* webpackPrefetch: true */ 'LoginModal');

import(/* webpackPreload: true */ 'ChartingLibrary');

這會生成 <link> 並追加到頁面頭部,指示著瀏覽器在閒置時間預取 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

 1 configureWebpack: config => {
2 const path = require('path')
3 const PrerenderSPAPlugin = require('prerender-spa-plugin')
4 config.plugins.push(
5 new PrerenderSPAPlugin({
6 staticDir: path.join(__dirname, 'dist'),
7 routes: ['/'],
8 minify: {
9 collapseBooleanAttributes: true,
10 collapseWhitespace: true,
11 keepClosingSlash: true,
12 decodeEntities: true,
13 sortAttributes: true,
14 },
15 renderer: new PrerenderSPAPlugin.PuppeteerRenderer({
16 renderAfterDocumentEvent: 'render-event',
17 renderAfterTime: 5000,
18 // headless: false,
19 }),
20 })
21 )
22 }
23
24 new Vue({
25 router,
26 store,
27 render: h => h(App),
28 mounted() {
29 // 預渲染 renderAfterDocumentEvent.
30 document.dispatchEvent(new Event('render-event'))
31 },
32 }).$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

1 configureWebpack: config => {
2 const TerserPlugin = require('terser-webpack-plugin')
3 config.optimization.minimizer.push(
4 new TerserPlugin({
5 extractComments: false,
6 terserOptions: { compress: { drop_console: true } },
7 })
8 )
9 }

7. bundle 分析(webpack-bundle-analyzer)

將 bundle 內容展示為便捷的、交互式、可縮放的樹狀圖形式。

  yarn add -D webpack-bundle-analyzer

1 configureWebpack: config => {
2 const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
3 .BundleAnalyzerPlugin
4 config.plugins.push(new BundleAnalyzerPlugin())
5 }

8. WebP

WebP(發音 weppy),是一種支持有損壓縮和無損壓縮的圖片文件格式,派生自圖像編碼格式 VP8。根據 Google 的測試,無損壓縮後的 WebP 比 PNG 文件少了 45% 的文件大小,即使這些 PNG 文件經過其他壓縮工具壓縮之後,WebP 還是可以減少 28% 的文件大小。

不過WebP目前在IOS上兼容性不好,可以使用JavaScript進行檢測,對支持 WebP 的用戶輸出 WebP 圖片。

 1 created() {
2 const htmlClass = document.documentElement.classList
3 this.checkWebpSupport() ? htmlClass.add('webps') : htmlClass.remove('webps')
4 }
5
6 checkWebpSupport() {
7 try {
8 return (
9 document
10 .createElement('canvas')
11 .toDataURL('image/webp')
12 .indexOf('data:image/webp') === 0
13 )
14 } catch (err) {
15 return false
16 }
17 }

記一次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


分享到:


相關文章: