天天看點

前端性能優化:前端性能優化該從哪些點入手

前端性能優化,一直以來都是一個老生常談的問題。頁面響應的時間快慢等性能問題,直接決定了使用者體驗的好壞,進而決定了使用者消費的欲望。是以,前端優化勢在必行。那麼,我們就來判斷一下,可以做的前端性能優化有哪些?

1、loading

對,你說的沒錯,這中優化方式确實是很low,但是請問,你在開發中加loading了嗎?沒加,請加上。就這這麼簡單,别問怎麼做。

2、骨架屏

這個聽起來似乎要高大上一點,應該至少要比loading要高大上。

實作骨架屏的方式:

(1)base64圖檔:辛苦設計小姐姐,設計一張base64圖檔,然後初始化的時候,顯示base64圖檔,等待接口響應資料傳回後,将base64圖檔隐藏,其原理和loading一樣。有個不好的地方時,無論你的頁面是什麼結構,顯示的骨架都一樣,這樣也不太好不是。

(2)webpack: vue-skeleton-webpack-plugin是配置,這水解決骨架屏的完美方案。它将插入骨架屏的方式由手動改為自動,原理在建構時使用 Vue 預渲染功能,将骨架屏元件的渲染結果 HTML 片段插入 HTML 頁面模版的挂載點中,将樣式内聯到 head 标簽中。這個插件可以給單頁面的不同路由設定不同的骨架屏,也可以給多頁面設定,同時為了開發時調試友善,會将骨架屏作為路由寫入 router 中,可謂是相當體貼了。

3、webp

webp 是一種新的圖檔格式,它的體積隻有隻有 JPEG 的2/3,将圖檔資源大量換成 webp 格式可以加快請求的速度。圖檔資源大部分都放在阿裡的 OSS 上,并且阿裡提供了接口,可以線上将 png/jpeg 轉為 webp 格式。

注意:webp 格式在浏覽器相容上還有一定的問題,是以需要判斷浏覽器是否支援 webp 格式哦。

以上三種屬于正常簡單的優化,下面我們就來講講比較高大上的優化:

1、網絡優化

(1)service worker

ServiceWorker

 是運作在浏覽器背景程序裡的一段 JS,它可以做許多事情,比如攔截用戶端的請求、向用戶端發送消息、向伺服器發起請求等等,其中最重要的作用之一就是離線資源緩存。

ServiceWorker

  擁有對緩存流程豐富靈活的控制能力,當頁面請求到 

ServiceWorker

 時,

ServiceWorker

 同時請求緩存和網絡,把緩存的内容直接給使用者,而後覆寫緩存。

注意:需要HTTPS才可以使用 ServiceWorker。

(2)http緩存

http緩存一般分為倆中:強緩存(本地緩存)和協商緩存(304緩存),普通重新整理會啟用 協商緩存,忽略 強緩存。隻有在位址欄或收藏夾輸入網址、通過連結引用資源等情況下,浏覽器才會啟用 強緩存。

強緩存:本地緩存是最快速的一種緩存方式,隻要資源還在緩存有效期内,浏覽器就會直接在本地讀取,不會請求服務端。

協商緩存:協商緩存,顧名思義是經過浏覽器與伺服器之間協商過之後,在決定是否讀取本地緩存,如果伺服器通知浏覽器可以讀取本地緩存,會傳回304狀态碼,并且協商過程很簡單,隻會發送頭資訊,不會發送響應體。

緩存的位置:

緩存位置一般分為:Memory Cache(記憶體緩存)和 Disk Cache(硬碟緩存)

記憶體緩存:讀取快、持續時間短、容量小

硬碟緩存:讀取慢、持續時間長、容量大

緩存優先級:Service Worker -> Memory Cache -> Disk Cache -> Push Cache

(3)http2

HTTP2 四個新特性:

  • 多路複用,無需多個TCP連接配接,因為其允許在單一的HTTP2連接配接上發起多重請求,是以可以不用依賴建立多個TCP連接配接。
  • 二進制分幀,将所有要傳輸的消息采用二進制編碼,并且會将資訊分割為更小的消息塊。
  • 頭部壓縮,用HPACK技術壓縮頭部,減小封包大小
  • 服務端推送,服務端可以在用戶端發起請求前發送資料,換句話說,服務端可以對用戶端的一個請求發送多個相應,并且資源可以正常緩存。

注意:使用 http2 的前提是必須是 https。

(3)資源預加載

簡單說,提前加載資源,當使用者需要檢視時可直接從本地緩存中渲染。

總結:對目前頁面需要的資源,使用 preload 進行預加載,對其它頁面需要的資源進行 prefetch 預加載。

preload

preload

 頁面加載的過程中,在浏覽器開始主體渲染之前加載。

<!-- 對sty1e.cs5和 index.js進行pre1oad預加載 -->
<link rel="preload" href="style.css" target="_blank" rel="external nofollow"  as="style">
<link rel="preload" href="index.js" target="_blank" rel="external nofollow"  as="script">
           

prefetch

prefetch

 頁面加載完成後,利用空閑時間提前加載。

<!--對資源進行 prefetch預加載-->
<link rel="prefetch" href="next.css" target="_blank" rel="external nofollow" >
<link rel="prefetch" href="next.js" target="_blank" rel="external nofollow" >
           

注意:

vue-cli

 預設開啟 

prefetch

 ,可在 

vue.config.js

 中全局禁用 

prefetch

 ,再針對指定子產品開啟。

dns-prefetch

頁面加載完成後,利用空閑時間提前加載。

<link rel="dns-prefetch" href="//example.com" target="_blank" rel="external nofollow" >
           

(4)異步無阻塞加載js

defer

<script src="d.js" defer></script>
<script src="e.js" defer></script>
           
  1. 不阻止解析 document, 并行下載下傳 d.js, e.js
  2. 即使下載下傳完 d.js, e.js 仍繼續解析 document
  3. 按照頁面中出現的順序,在其他同步腳本執行後,DOMContentLoaded 事件前 依次執行 d.js, e.js。

async

<script src="b.js" async></script>
<script src="c.js" async></script>
           
  1. 不阻止解析 document, 并行下載下傳 b.js, c.js
  2. 當腳本下載下傳完後立即執行。(兩者執行順序不确定,執行階段不确定,可能在 DOMContentLoaded 事件前或者後 )

2、建構優化

(1)gzip 壓縮:compression-webpack-plugin

gzip

 壓縮效率非常高,通常可以達到 70% 的壓縮率,也就是說,如果你的網頁有 30K,壓縮之後就變成了 9K 左右。

//npm i -D compression-webpack-plugin
configureWebpack: config => {
  const CompressionPlugin = require('compression-webpack-plugin')
  config.plugins.push(new CompressionPlugin())
}
           

(2)去除console:terser-webpack-plugin

線上項目自然不應該被看到控制台的列印日志,是以我們需要将 

console.log

 都去除掉。

//npm i -D terser-webpack-plugin 
 configureWebpack: config => {
   const TerserPlugin = require('terser-webpack-plugin')
   config.optimization.minimizer.push(
     new TerserPlugin({
       extractComments: false,
       terserOptions: { compress: { drop_console: true } },
     })
   )
 }
           

(3)去除 SourceMap:

由于打包後的檔案經過了壓縮、合并、混淆、babel編譯後的代碼不利于定位分析bug。

module.exports = {
  productionSourceMap: false,
}
           

(4)預渲染:prerender-spa-plugin

簡單說,就是将浏覽器解析 

javascript

  動态渲染頁面的這部分工作,在打包階段就完成了,(隻建構了靜态資料)換個說法在建構過程中,

webpack

 通過使用 

prerender-spa-plugin

 插件生成靜态結構的 

html

// npm i -D prerender-spa-plugin
 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,
       }),
     })
   )
 }
           

注意:路由模式必須為 

history

 ,如果不設定 

history

 模式,也能運作和生成檔案,每個 

index.html

 檔案的内容都會是一樣的。

(5)服務端渲染:vue-ssr-render

為了解決seo和首屏渲染的問題,為們還可以使用服務端渲染的方式。

//webpack.client.js
............
const  VueSSRClientPluguin  = require('vue-server-renderer/client-plugin');
..............
plugins:[
        new VueSSRClientPluguin()
]

//webpack.server.js
const VueSSRServerPlugin = require('vue-server-renderer/server-plugin');
...............
      entry:{
            main:'./entry-server.js'
      },
     output:{
          filename:'server-bundle.js',
          libraryTarget:'commonjs2'
      },
............
      plugins:[
           new  VueSSRServerPlugin ()
      ]
           

當然還有很多其他的優化手段,,,未完待續。。。。 

繼續閱讀