🐢11s到⚡1s,性能優化之首屏加載🚀

全文共6511字/詞,閱讀大概須要13分鐘,太長不看黨請直接移步👉「開始優化」部分直接查看優化手段javascript

背景

前段時間公司服務器網絡波動,網站訪問變慢,一些性能問題也隨之暴露了出來。紛紛反饋在這樣的弱網條件下,訪問新項目時,加載了近1分鐘都沒加載出來,而訪問其餘頁面頂多也就30-40s。css

在網絡恢復後,嘗試訪問了下頁面,無緩存首次打開須要等待近11s的時間,最大的資源達到了3.7M...html

在對項目作了一些優化處理後,再次無緩存打開能夠發現網頁幾乎是秒開,平均耗時在1s之內前端

在這裏總結記錄一下,基本上都是一些常規可複製的優化手段,但願能爲一樣想優化網頁性能的你提供思路~vue

優化效果


Network

Slow3G條件下22-25s加載完成java



lighthouse


hiper

關於性能優化

在開始以前,咱們須要明白一個原則:性能優化的最終目的是提高用戶體驗
簡而言之就是讓用戶感受這個網站很「快」(至少不慢hh),這裏的「快」有兩種,一種是「真的快」一種是「以爲快」node

  • 「真的快」:能夠客觀衡量的指標,像網頁訪問時間、交互響應時間、跳轉頁面時間
  • 「以爲快」:用戶主觀感知的性能,經過視覺引導等手段轉移用戶對等待時間的關注

作好這兩方面都能提高用戶對網站的性能評價。webpack

權衡取捨

另外就是軟件工程沒有銀彈,一種優化方案可能適用於大多數項目,可是某些特殊狀況下極可能會起反效果。nginx

舉個🌰,因爲瀏覽器有單域名下併發請求限制,一般咱們會將依賴統一打成一個vendor包(vue-cli默認策略),減小首屏請求數,且依賴不變更的狀況下文件指紋不變,能夠有效利用304緩存。在依賴很少的狀況這麼處理確實有助於提高加載速度,但一旦依賴多起來,vendor就會特別的大,在弱網條件下,會嚴重拖慢頁面顯示。這顯然不是咱們想要的,因此咱們根據狀況會對vendor進行拆分,好比拆分到CDN,或者直接拆分到頁面中git

所以,咱們在作性能優化過程當中,必須根據最終能給用戶體驗帶來的提高權衡後作出適合當前項目的選擇

指標和目標

目標會影響咱們在過程當中的決策
指標則用來度量咱們的目標

目標

首先咱們須要肯定目標,根據場景和項目複雜度不一樣,制定的目標也不一樣,好比但願比競品快20%,或者符合標準的"2-5-10"原則等等

這裏我定下的目標是

  • 正常網速下,2s內加載完成
  • 弱網下,30s內加載完成

指標

關於指標這塊,簡單介紹下常見指標

  • FCP(First Contentful Paint):白屏時間(第一個文本繪製時間)
  • Speed Index:首屏時間
  • TTI(Time To Interactive): 第一次可交互的時間
  • lighthouse score(performance):Chrome瀏覽器審查工具性能評分(也能夠npm install -g lighthouse,編程式調用)

調試工具

經過性能調試工具能夠直觀便捷地獲取這些指標,好比Newwork、k六、hiper、Lighthouse...。具體能夠看我關於性能調試工具的另外一篇文章

瓶頸分析

Network分析


優化前Network

從Network上咱們發現主要問題在3.2M的chunk-vendor.js上

  • 體積太大,下載慢
  • 阻塞了其餘資源下載

Lighthouse分析


優化前Lighthouse

Performance分析

因爲本次不涉及到應用內場景性能優化,Performance分析跳過...

dist目錄分析

  • 總體體積太大,近5M
  • 出現了若干不該出現的靜態資源,好比頁面上沒引用到SVG圖標、應該被內聯的小圖等
  • 部分圖片資源較大,最大的達到僅400KB

Webpack Bundle分析


優化前Bundle

從webpack bundle能夠看出,問題着實很多

  • 未剔除項目模板用到的冗餘依賴,好比g二、quill、wangEditor、mock等
  • 一些沒用到的Ant-design組件因爲全局註冊也一併打包了進去
  • 項目中只用到幾個Ant-Design/icons,但卻被全量引入
  • moment和moment-timezone重複,且體積較大
  • core-js體積較大
  • 打包策略不合理,致使chunk-vendor太大

開始優化

🛫🛫🛫

體積優化

⚡排查並移除冗餘依賴、靜態資源

內容(點擊展開/收起)
  • 移除項目模板冗餘依賴
  • 將public的靜態資源移入assets。靜態資源應該放在assets下,public只會單純的複製到dist,應該放置不經webpack處理的文件,好比不兼容webpack的庫,須要指定文件名的文件等等

before:4.96M after:4.12M

⚡構建時壓縮圖片

內容(點擊展開/收起)

每次使用在線服務手動壓縮較爲麻煩,能夠直接在構建流程中加入壓縮圖片

使用image-webpack-loader

// install
npm i image-webpack-loader -D
// vue.config.js
chainWebpack: (config) => {
    if (isProd) {
        // 圖片壓縮處理
        const imgRule = config.module.rule('images')
        imgRule
            .test(/\.(png|jpe?g|gif|webp)(\?.*)?$/)
            .use('image-webpack-loader')
            .loader('image-webpack-loader')
            .options({ bypassOnDebug: true })
            .end()
    }
}
複製代碼
  1. install或build時若是出現imagemin庫下載失敗,能夠嘗試 換源、配置github hosts、install時添加--user=root解決
  2. 因爲在圖片下載後已經手動用在線工具壓縮過,這部分提高不大

before:4.12M after:4.00M

⚡使用webP圖片

內容(點擊展開/收起)

webP是谷歌推出的新圖片格式(2010),同等質量下體積拳打png腳踢jpg,目前兼容性還算能夠,就蘋果家的表現不太理想

轉換爲webP圖片

能夠手動,也能夠加入構建自動化生成。

  • 手動,可使用webP-converter、智圖等工具,但建議使用官方webP-converter,除了便捷性,同質量下體積各方面均優於智圖。
./cwebp -q 75 login_plane_2.png -o login_plane_2.webp
複製代碼
  • 自動化生成,可使用image-min-webp或其餘webpack插件

頁面中使用(兼容低版本)

  • HTML中使用,<picture>標籤兼容
<picture>
    <source srcset="hehe.webp" type="image/webp">
    <img src="hehe.png" alt="hehe>
</picture>
複製代碼
  • CSS中使用,須要配合JS作判斷
// main.js
window.addEventListener('DOMContentLoaded', () => {
    const isSupportWebP = document.createElement('canvas')
    .toDataURL('image/webp')
    .indexOf('data:image/webp') === 0
    document.documentElement.classList.add(isSupportWebP ? '' : '.no-support-webp');
})
// css
.support-webp .bg{
    background-image: url("hehe.webp");
}

.no-support-webp .bg {
    background-image: url("hehe.png");
}
複製代碼
  1. 請務必使用原圖進行webp轉換,不然會影響體積
  2. 項目大圖很少,最大400KB的圖片轉換後只有48.9KB

⚡優化SVG圖標

內容(點擊展開/收起)

這一步咱們來優化部分冗餘的舊SVG圖標被打包進去的狀況,通常項目中SVG使用方式都是在iconfont生成JS而後引入。這種作法

  • 不直觀,每次都得去iconfont複製名稱使用
  • 每次增刪改圖標須要從新替換整個JS
  • 不能按需加載,沒使用到的也會一塊兒打包,特別是UI換圖標時通常不會將舊圖標刪除....
  • 添加自定義SVG不友善,必須上傳iconfont添加到一塊兒再下載

更優的SVG玩法

  • 新增/修改圖標
    • 在iconfont下載UI上傳或者其餘地方找的任意SVG圖標放入icons/svg/下
    • 頁面中使用全局svg組件,傳入複製下SVG的文件名便可
  • 刪除
    • 只須要去掉使用的地方,而後刪除對應圖標便可

要實現上述效果,只須要

  • 引入svg-sprite-loader
// install
npm i svg-sprite-loader -D
// vue.config.js
chainWebpack: (config) => {
    // SVG處理
    config.module
      .rule('svg')
      .exclude.add(resolve('src/icons/svg'))
      .end()
    config.module
      .rule('icons')
      .test(/\.svg$/)
      .include.add(resolve('src/icons/svg'))
      .end()
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'icon-[name]'
      })
      .end()
    
}
複製代碼
  • 建立src/icons/svg並將圖標放進去,並經過webpack的require.context自動導入
// src/icons/index.js
const req = require.context('./svg', false, /\.svg$/)
const requireAll = requireContext => requireContext.keys().map(requireContext)
requireAll(req)

// main.js
import '@/icons'
複製代碼
  • 建立全局組件ca-svg
// src/icons/index.js
import Vue from 'vue'
import CaSVG from '@/components/ca-svg'
Vue.component('ca-svg', CaSVG)

// src/components/ca-svg.vue
<template>
  <svg :class="svgClass" aria-hidden="true" v-on="$listeners" :style="svgStyle">
    <use :xlink:href="iconName" />
  </svg>
</template>
...
// name屬性爲必須字段,其餘size或color能夠自由定製
複製代碼

壓縮優化

SVG一般會有一些冗餘信息致使影響體積,這裏咱們可使用svgo-loader來進一步壓縮

// install
npm i svgo-loader -D

// vue.config.js
// 接上面svg的配置
...
.end()
.use('svgo-loader')
.loader('svgo-loader')
.end()
複製代碼

⚡優化Ant-design-vue體積

內容(點擊展開/收起)

能夠看到這部分在chunk-vendor中佔的比例不小

按需引入

這部分實際上已是作了處理的了,具體操做參考ant-design-vue文檔,按說明作沒啥大坑,效果也符合預期。

快速上手 - Ant Design Vue

刪除冗餘組件

部分組件是不常常用的,但卻使用了Vue.use()全局引入了。這裏去掉不經常使用和沒用到的全局引入,改成頁面內import()引入

⚡優化Ant-design-icon體積

內容(點擊展開/收起)

這一部分,因爲咱們在項目中只使用了幾個Ant內置圖標,不可能有530+KB。根據Ant文檔的描述是因爲其將ICON全量引入的關係致使的,說法是當前用法若是按需加載的話沒法肯定使用者會不會在運行時改變icon,好比配置的ICON。

重定向到本地來控制

這個問題,在React版的Ant-Design是已是作了處理的了(寫法上有所調整),但在Ant-Design-Vue-1.x中仍然沒有官方解決方案。目前瞭解到的有兩種方案

  • 使用webpack-ant-icon-loader (異步加載)
  • 重定向到本地文件來控制 (推薦),使用alia將將@ant-design/icons/lib/dist指向項目中的antd-icon.js,而後在antd-icon中按需導出便可
// alias配置
resolve: {
  alias: {
    '@ant-design/icons/lib/dist$': path.resolve(__dirname, './src/icons/antd-icon.js')
  }
}
// src/icons/antd-icon.js
export { default as LoadingOutline } from '@ant-design/icons/lib/outline/LoadingOutline'
複製代碼
  1. 注意項目中和Ant組件中使用的ICON都要導出
  2. 優化後從530K+到30K+

⚡優化moment、moment-timezone體積

內容(點擊展開/收起)

這兩個包300K + 160K,加起來有460K,也是佔的比較多的一項

不打包moment時區文件

這裏使用內置的IgnorePlugin便可作到

// webpack plugins
plugins: [
  // Ignore all locale files of moment.js
  new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
],
複製代碼

移除moment-timezone

moment-timezone包含了moment,項目中只有一處地方使用到,用來獲取東八區的當前時間,moment是能夠作到的,不須要額外引入moment-timezone

// old
moment.tz('Asia/Shanghai').format('YYYYMMDDHHmmss')
// new
moment.utcOffset(480).format('YYYYMMDDHHmmss')
複製代碼

使用dayjs替代moment

dayjs實現了moment的大多數功能,Api基本一致,壓縮後體積卻不到2k,是優秀的替代方案,且多數狀況下,dayjs能夠完美的替代moment(按需引入插件)

可是這裏遇到了使用Ant-Design的第二個坑,Ant-Design實現Date-Picker時使用了moment,因此在項目中不使用moment也無論用,同樣會打包進來....

這個問題,在React版的Ant-Design又已是作了處理的了,容許用戶選擇dayjs或moment。一樣的,Ant-Design-Vue仍沒有跟進...

所幸,dayjs做者提供了一個插件,能夠將Ant-Design-Vue的moment替換成dayjs👍 雖然文檔中只說Ant-Design-React能夠用,但實際上在issue能夠看到它也適用於antdV,不過須要調整一些配置

使用antd-dayjs-webpack-plugin

// vue.config.js
const AntdDayjsWebpackPlugin = require('antd-dayjs-webpack-plugin')
configureWebpack: {
    ...
    plugins: [
      new AntdDayjsWebpackPlugin({ preset: 'antdv3', replaceMoment: true })
    ],
}
複製代碼

replaceMoment參數是用webpack alias來重定向moment到dayjs,因爲項目中多處使用moment,這樣作能夠繼續使用moment實際上調用的dayjs,實現無感知替換👍

  1. 替換成dayjs後,一些功能須要經過引入插件來保持一致,好比utc、updateLocale
  2. 替換成dayjs後,一些針對moment的優化須要改爲dayjs或去掉

⚡優化core-js體積

內容(點擊展開/收起)

core-js實際上就是瀏覽器新API的polyfill,項目是PC端,因此主要是爲了兼容IE...

調整.browserslistrc

  • 指定項目須要兼容的版本,讓babel和auto-prefix少作點兼容性工做,好比移動端不用兼容IE、iOS6.0如下等等

調整useBuiltIns

項目中默認是useBuiltIns: 'entry'將全部polyfill都引入了,致使包比較大。咱們可使用useBuiltIns: 'entry'調整下策略,按需引入,項目中沒使用到的API就不作polyfill處理了

// babel.config.js
module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset',
    [
      '@babel/preset-env',
      {
        'useBuiltIns': 'usage', // entry,usage
        'corejs': 3
      }
    ]
  ],
  plugins
}
複製代碼

btw,這裏更優的作法應該是使用動態polyfill,讓服務器根據UA判斷是否要返回polyfill

before:4.96M after:2.96M


傳輸優化

⚡優化分包策略

內容(點擊展開/收起)

vue-cli3的默認優化是將全部npm依賴都打進chunk-vendor,但這種作法在依賴多的狀況下致使chunk-vendor過大

optimization: isProd ? {
  splitChunks: {
    chunks: 'all',
    maxInitialRequests: Infinity, // 默認爲3,調整爲容許無限入口資源
    minSize: 20000, // 20K如下的依賴不作拆分
    cacheGroups: {
      vendors: {
        // 拆分依賴,避免單文件過大拖慢頁面展現
        // 得益於HTTP2多路複用,不用太擔憂資源請求太多的問題
        name(module) {
          // 拆包
          const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1]
          // 進一步將Ant組件拆分出來,請根據狀況來
          // const packageName = module.context.match(/[\\/]node_modules[\\/](?:ant-design-vue[\\/]es[\\/])?(.*?)([\\/]|$)/)[1]
          return `npm.${packageName.replace('@', '')}` // 部分服務器不容許URL帶@
        },
        test: /[\\/]node_modules[\\/]/,
        priority: -10,
        chunks: 'initial'
      }
    }
  },
  runtimeChunk: { name: entrypoint => `runtime-${entrypoint.name}` }
} : {}
複製代碼
  1. Tips: vue inspect > output.js --mode production 能夠查看最終配置
  2. 分包這塊須要根據實際狀況作對應處理,才能取得比較好的效果,總之多看文檔多試就對了

⚡優化路由懶加載

內容(點擊展開/收起)

SPA中一個很重要的提速手段就是路由懶加載,當打開頁面時纔去加載對應文件,咱們利用Vue的異步組件和webpack的代碼分割(import())就能夠輕鬆實現懶加載了。

但當路由過多時,請合理地用webpack的魔法註釋對路由進行分組,太多的chunk會影響構建時的速度

{
    path: 'register',
    name: 'register',
    component: () => import(/* webpackChunkName: "user" */ '@/views/user/register'),
}
複製代碼

請只在生產時懶加載,不然路由多起來後,開發時的構建速度感人

⚡開啓HTTP2

內容(點擊展開/收起)

HTTP2是HTTP協議的第二個版本,相較於HTTP1 速度更快、延遲更低,功能更多。 目前來看兼容性方面也算過得去,在國內有超過50%的覆蓋率。

一般瀏覽器在傳輸時併發請求數是有限制的,超過限制的請求須要排隊,以往咱們經過域名分片、資源合併來避開這一限制,而使用HTTP2協議後,其能夠在一個TCP鏈接分幀處理多個請求(多路複用),不受此限制。(其他的頭部壓縮等等也帶來了必定性能提高)

若是網站支持HTTPS,請一併開啓HTTP2,成本低收益高,對於請求多的頁面提高很大,尤爲是在網速不佳時

Nginx開啓HTTP2(>V1.95)

  • 調整Nginx配置
// nginx.conf
listen 443 http2;
複製代碼
  • 重啓Nginx
nginx -s stop && nginx
複製代碼
  • 驗證效果

HTTP2開啓後

多路複用避開了資源併發限制,但資源太多的狀況,也會形成瀏覽器性能損失(Chrome進程間通訊與資源數量相關)

⚡Gzip壓縮傳輸

內容(點擊展開/收起)

Gzip壓縮是一種強力壓縮手段,針對文本文件時一般能減小2/3的體積。

HTTP協議中用頭部字段Accept-EncodingContent-Encoding對「採用何種編碼格式傳輸正文」進行了協定,請求頭的Accept-Encoding會列出客戶端支持的編碼格式。當響應頭的 Content-Encoding指定了gzip時,瀏覽器則會進行對應解壓

通常瀏覽器都支持gzip,因此Accept-Encoding也會自動帶上gzip,因此咱們須要讓資源服務器在Content-Encoding指定gzip,並返回gzip文件

Nginx配置Gzip

#開啓和關閉gzip模式
gzip on;
#gizp壓縮起點,文件大於1k才進行壓縮
gzip_min_length 1k;
# gzip 壓縮級別,1-9,數字越大壓縮的越好,也越佔用CPU時間
gzip_comp_level 6;
# 進行壓縮的文件類型。
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript ;
# nginx對於靜態文件的處理模塊,開啓後會尋找以.gz結尾的文件,直接返回,不會佔用cpu進行壓縮,若是找不到則不進行壓縮
gzip_static on
# 是否在http header中添加Vary: Accept-Encoding,建議開啓
gzip_vary on;
# 設置gzip壓縮針對的HTTP協議版本
gzip_http_version 1.1;
複製代碼

構建時生成gzip文件

雖然上面配置後Nginx已經會在響應請求時進行壓縮並返回Gzip了,可是壓縮操做自己是會佔用服務器的CPU和時間的,壓縮等級越高開銷越大,因此咱們一般會一併上傳gzip文件,讓服務器直接返回壓縮後文件

// vue.config.js
const CompressionPlugin = require('compression-webpack-plugin')
// gzip壓縮處理
chainWebpack: (config) => {
    if(isProd) {
        config.plugin('compression-webpack-plugin')
            .use(new CompressionPlugin({
                test: /\.js$|\.html$|\.css$/, // 匹配文件名
                threshold: 10240, // 對超過10k的數據壓縮
                deleteOriginalAssets: false // 不刪除源文件
            }))
    }
}
複製代碼
  1. 插件的默認壓縮等級是9,最高級的壓縮
  2. 圖片文件不建議使用gzip壓縮,效果較差

⚡Prefetch、Preload

內容(點擊展開/收起)

<link>標籤的rel屬性的兩個可選值。
Prefetch,預請求,是爲了提示瀏覽器,用戶將來的瀏覽有可能須要加載目標資源,因此瀏覽器有可能經過事先獲取和緩存對應資源,優化用戶體驗。
Preload,預加載,表示用戶十分有可能須要在當前瀏覽中加載目標資源,因此瀏覽器必須預先獲取和緩存對應資源。

Prefetch、Preload能夠在某些場景下能夠有效優化用戶體驗。 舉些場景

  • 首屏字體、大圖加載,CSS中引入字體須要等CSS解析後纔會加載,這以前瀏覽器會使用默認字體,當加載後會替換爲自定義字體,致使字體樣式閃動,而咱們使用Preload提早加載字體後這種狀況就好不少了,大圖也是如此
  • 優惠券的背景圖加載,一樣CSS中url引用在DOM沒掛載以前是不會加載圖片的,進入卡包頁/收銀臺時能夠提早使用Prefetch加載,這樣用戶在進行優惠券頁就能夠立馬看到加載完成的圖片了

Vue-Cli3默認會使用preload-webpack-plugin對chunk資源作preload、prefetch處理,入口文件preload,路由chunk則是prefetch。

通常來講不須要作特別處理,若是判斷不須要或者須要調整在vue.config.js中配置便可

  1. 理論上prefetch不會影響加載速度,但實際測試中,是有輕微影響的,不過這個見仁見智,我認爲整體體驗上仍是有所提高的,
  2. 相似字體文件這種隱藏在腳本、樣式中的首屏關鍵資源,建議使用preload
  3. 移動端流量訪問時慎用

⚡託管至OSS + CDN加速

內容(點擊展開/收起)

當應對一些弱網地區時,OSS + CDN無疑是很強力的提速手段。

OSS,對象存儲

海量,安全,低成本,高可靠的雲存儲服務。能夠經過簡單的REST接口,在任什麼時候間、任何地點上傳和下載數據,也可使用WEB頁面對數據進行管理。

OSS的特色:

  • 穩定,服務可用性高,多重備份保障數據安全
  • 安全,多層次安全防禦,防DDoS
  • 大規模,高性能,從容應對高併發

另外,OSS還提供一些方便的服務

  • 圖片處理,支持壓縮、裁剪、水印、格式轉換等
  • 傳輸加速,優化傳輸鏈路和協議策略實現高速傳輸

這裏推薦直接購買阿里家的OSS,OSS雖然也有傳輸加速服務,但對於靜態熱點文件的下載加速場景仍是須要CDN加速

CDN,內容分發網絡

CDN加速原理是把提供的域名做爲源站,將源內容緩存到邊緣節點。當客戶讀取數據時,會從最適合的節點(通常來講就近獲取)獲取緩存文件,以提高下載速度。

因爲沒申請到資源,項目並無上OSS+CDN。但若是有條件仍是建議上,提高很大


感知性能優化

😎白屏時的loading動畫

內容(點擊展開/收起)

首屏優化,在JS沒解析執行前,讓用戶能看到Loading動畫,減輕等待焦慮。一般會在index.html上寫簡單的CSS動畫,直到Vue掛載後替換掛載節點的內容,但這種作法實測也會出現短暫的白屏,建議手動控制CSS動畫關閉

😎首屏骨架加載

內容(點擊展開/收起)

首屏優化,APP內常見的加載時各部分灰色色塊。針對骨架屏頁的自動化生成,業界已有很多解決方案。


感知優化的一些補充

首屏之外的一些場景優化,更多相關內容好比圖片懶加載、組件懶加載等 後續文章會作介紹

😎漸進加載圖片

內容(點擊展開/收起)

通常來講,圖片加載有兩種方式,一種是自上而下掃描,一種則是原圖的模糊展現,而後逐漸/加載完清晰。前者在網速差的時候用戶體驗較差,後者的漸進/交錯式加載則能減輕用戶的等待焦慮,帶來更好的體驗

漸進/交錯格式圖片

瀏覽器自己支持這種圖片的模糊到清晰的掃描加載方式,只須要將處理好資源便可

  • UI生成,PS導出選擇「連續」,Sketch導出選擇「漸進/交錯」
  • 轉換,使用第三方庫處理

漸進加載圖片

先加載小圖,模糊化渲染,圖片加載完成後替換爲原圖,最典型的例子就是Medium,模糊化能夠用filter或者canvas處理

加載佔位圖

先加載全局通用loading圖或者用CSS填充色塊,圖片加載完成後替換爲原圖。簡單粗暴,在弱網條件下頗有用

  1. 幾種方式能夠同時搭配使用
  2. 漸進/交錯格式圖片會佔用必定CPU和內存,酌情使用

😎路由跳轉Loading動畫

內容(點擊展開/收起)

弱網優化手段,用了懶加載後用戶若是在弱網條件下點擊下一個頁面在下個頁面加載完成前頁面內容不可用,用戶會理解爲卡頓。 在VueRouter的路由守衛中處理便可

結尾

本文只介紹了首屏加載場景下的性能優化,實際上性能優化遠不止這些內容,SPA的加載性能指標採集光靠Lighthouse、slow 3G模擬真的可信嗎?除了加載場景外的其餘方面呢?構建速度、操做流暢性...

業務

性能優化影響的,不只是用戶體驗,還影響了轉化率、搜索引擎排名,這些因素都會對最終的流量、銷量等收入形成影響

來自Google的數據代表,一個有10條數據0.4秒能加載完的頁面,變成30條數據0.9秒加載完以後,流量和廣告收入降低90%。

Google Map 首頁文件大小從100KB減少到70-80KB後,流量在第一週漲了10%,接下來的三週漲了25%。

亞馬遜的數據代表:加載時間增長100毫秒,銷量就降低1%。

立場不一樣,看問題角度也會變化,好比對老闆來講最終目的實際上是搞錢hh,用戶體驗這些花裏胡哨的,別人不必定懂。


用戶體驗 × money √

因此若是必要,請在過程先後作好性能收益的數據監控和分析,在性能優化和產品指標之間創建正向聯繫,方便自上而下的推進技術方案的執行。這纔是你說服上司或領導投入成本到性能優化上的重要依據

我的提高

性能優化算是老生常談的話題了,但部分人在面對怎麼作性能優化的問題時,僅僅只是羅列出各類常見優化手段,更有深度的答案應該是遇到什麼性能問題,針對這個問題圍繞某些性能指標採起了什麼手段,手段是否帶來了其餘問題,怎麼權衡,最終達到了什麼樣的效果。

參考

相關文章
相關標籤/搜索