<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          記一次前端性能優(yōu)化——性能得分從56到96

          共 11196字,需瀏覽 23分鐘

           ·

          2023-10-07 12:16

          點擊上方 前端Q,關注公眾號

          回復加群,加入前端Q技術交流群

          前言

          最近看了一篇前端性能優(yōu)化的文章,之前也沒搞過性能優(yōu)化,就學習了一下。要想搞性能優(yōu)化,得知道都有哪些和性能相關的指標,得知道有什么工具可以量化地評估網(wǎng)站的性能表現(xiàn),還得知道怎么進行優(yōu)化、優(yōu)化的思路都有啥。學了一波,決定用Lighthouse這款性能測試工具來評估一下自己開發(fā)的網(wǎng)站的性能,優(yōu)化前得分56,優(yōu)化后得分96,怎么做的呢?閱讀本文一起學習吧~

          1. Lighthouse的使用

          Lighthouse 是由Google 開發(fā)并開源的Web 性能測試工具,通過監(jiān)控和檢測網(wǎng)站應用的各方面性能表現(xiàn),為開發(fā)這提供優(yōu)化用戶體驗和網(wǎng)站性能提供指導建議。

          下面介紹兩種使用Lighthouse的方式:通過Chrome插件使用和通過Node CLI使用。

          1.1 通過Chrome插件使用

          首先現(xiàn)在Lighthouse插件(Lighthouse谷歌瀏覽器插件下載地址:Lighthouse[1])。

          然后打開Chrome開發(fā)者工具,點擊右上角的【三個點】,點擊【更多工具】,再點擊【性能監(jiān)視器】:

          然后點擊【Lighthouse】選項卡,點擊【分析網(wǎng)頁加載情況】按鈕:

          如下為正在夾斷網(wǎng)頁得分:

          幾秒后,Lighthouse性能分析報錯生成:

          可見性能分數(shù)比較低,具體指標得分如下:

          點擊【展開視圖】可以了解每一指標的含義,可以點擊連接了解每一指標的詳情以及具體優(yōu)化策略:

          再往下可以查看優(yōu)化建議:

          再往下可以看診斷結果:

          1.2 通過Node CLI使用

          目前Lighthouse已經(jīng)發(fā)布了npm包,可以在項目中集成:npm i lighthouse

          如下為腳本代碼:

          javascript
          復制代碼
          const run = async () => {
            const browser = await puppeteer.launch({
              headless: "new",
              args: ["--no-sandbox""--disable-setuid-sandbox"],
            });
            const page = await browser.newPage();
            const url = "你的網(wǎng)頁url";
            await page.goto(url);
            const { port } = new URL(browser.wsEndpoint());
            const { report } = await lighthouse(url, {
              port,
              output: "html",
            });
            await writeFile("report.html", report);
            await browser.close();
          };
          run();

          運行腳本即可得到Lighthouse生成的分析報告:

          分析報告和瀏覽器插件方式得到在內(nèi)容上是的一樣,只不過是英文的形式。后續(xù)可以利用在此基礎上進行改善和豐富,可以優(yōu)化前端工程的部署流程。

          有了性能分析報告,我們可以根據(jù)各性能指標得分,優(yōu)化建議和診斷結果對項目進行優(yōu)化,下面具體學習一下這些性能優(yōu)化指標。

          2. 性能優(yōu)化的指標

          2.1 FCP ( First Contentful Paint)首次內(nèi)容繪制

          2.1.1 定義

          首次內(nèi)容繪制時間,測量頁面從開始加載到頁面內(nèi)容的任何部分在屏幕上完成渲染的時間。

          2.1.2 對定義的理解

          所述頁面內(nèi)容必須是文本、圖片(包含背景圖),非白色的canvas或SVG。

          這是用戶第一次看到頁面的內(nèi)容,注意是部分內(nèi)容,并非所有內(nèi)容。

          如下圖所示,F(xiàn)CP 發(fā)生在第二幀,因為那是首批文本和圖像元素在屏幕上完成渲染的時間點:

          如上圖所示,雖然部分內(nèi)容已完成渲染,但并非所有內(nèi)容都已經(jīng)完成渲染。這是首次內(nèi)容繪制時間 (FCP) 與*最大內(nèi)容繪制時間 (LCP,Largest Contentful Paint)之間的重要區(qū)別。

          2.1.3 評價標準

          FCP時間在0-1.8秒, 表示良好,顏色為綠色,F(xiàn)CP評分將在75~100分;

          FCP時間在1.9-3.0秒, 表示需要改進,顏色為橙色,F(xiàn)CP評分將在50~74分;

          FCP時間在3.1秒以上, 表示較差進,顏色為紅色,F(xiàn)CP評分將在0~49分。

          2.1.4 縮短FCP時間的方法

          指導方案可參照:如何改進 FCP [2],本文如何做的見下文。

          2.1.5 注意事項

          此指標對于沒有使用ssr技術的web項目意義并不大,因為第一繪制發(fā)生的時間通常JS還沒加載完畢。

          2.2 LCP(Largest Contentful Pain)最大內(nèi)容繪制

          2.2.1 定義

          最大內(nèi)容繪制時間,根據(jù)頁面首次開始加載的時間點來計算可視區(qū)域內(nèi)可見的最大圖像或者文本塊完成渲染的相對時間。

          2.2.2 對定義的理解

          LCP要考慮的元素包括:img元素以及內(nèi)嵌在svg元素內(nèi)的img元素,video元素,通過url()加載的背景圖像元素,包含文本節(jié)點或者其他內(nèi)聯(lián)級文本元素的塊級元素。

          如下圖所示,最大元素隨內(nèi)容加載而變化,隨著新內(nèi)容被添加進 DOM,并因此使最大元素發(fā)生了改變:

          2.2.3 評價標準

          LCP時間在0-2.5秒, 表示良好,顏色為綠色;

          LCP時間在2.6-4.0秒, 表示需要改進,顏色為橙色;

          LCP時間在4.1秒以上, 表示較差進,顏色為紅色。

          2.2.4 縮短LCP時間的方法

          指導方案可參考:如何改進 LCP[3],本文如何做的見下文。

          2.2.5 注意事項

          在某些情況下,頁面上最重要的元素(或多個元素)并不是最大元素,而開發(fā)者可能更有興趣測量前者的渲染時間(使用元素計時API[4])。

          2.3 TBT (Total Blocking Time)總阻塞時間

          2.3.1 定義

          總阻塞時間 (TBT) 指標測量First Contentful Paint 首次內(nèi)容繪制 (FCP)與Time to Interactive 可交互時間 (TTI)之間的總時間。

          2.3.2 對定義的理解

          由定義可知:TBT涉及到了FCP和TTI這兩個概念, 對于FCP上文已經(jīng)介紹過,這里補充一下TTI(可交互時間的定義):TTI 指標測量頁面從開始加載到主要子資源完成渲染,并能夠快速、可靠地響應用戶輸入所需的時間。

          2.3.3 評價標準

          評價標準參加下表:

          TBT得分標準[5]

          為了提供良好的用戶體驗,網(wǎng)站在普通移動硬件上進行測試時,應當努力使TBT控制在300毫秒以內(nèi)。

          2.3.4 縮短TBT的方法

          指導方案可參考:如何改進TBT[6],本文如何做的見下文。

          2.4 CLS(Cumulative Layout Shift)累積布局偏移

          2.4.1 定義

          CLS 測量整個頁面生命周期內(nèi)發(fā)生的所有意外布局偏移中最大一連串的布局偏移分數(shù)。

          2.4.2 對定義的理解

          累積布局偏移 (CLS) 是測量視覺穩(wěn)定性的一個以用戶為中心的重要指標,因為該項指標有助于量化用戶經(jīng)歷意外布局偏移的頻率,較低的 CLS 有助于確保一個頁面是令人愉悅的。

          2.4.3 評價標準

          2.4.4 縮短CLS的方法

          指導方案可參照:如何改進CLS[7],本文不涉及。

          2.5 SI(Speed Index)速度指標

          2.5.1 定義

          SI是一個表示頁面可視區(qū)域中內(nèi)容的填充速度的指標。

          2.5.2 對定義的理解

          該指標捕獲的是頁面出現(xiàn)像素點的時間。

          2.5.3 評價標準

          評價標準參加下表:

          2.5.5 縮短SI的方法

          指導方案可參照:如何改進SI[8],本文如何做的見下文。

          3. 具體的性能優(yōu)化的方法

          文檔快速加載[9]總結了一些提升網(wǎng)站性能的技術,列出一下常用的方法:

          1.消除阻塞渲染的資源: 例如對于引入三方的script標簽加上async或者defer。

          2.縮小CSS、移除未使用的CSS: 例如使用壓縮器壓縮CSS。

          3.預連接到所需要的資源:例如使用<link rel="preconnect">通知瀏覽器,頁面打算與另一個源建立連接,而且希望該過程盡快開始。

          4.減少服務器的響應時間:例如使用HTTP2。

          5.使用緩存:例如使用HTTP緩存。

          6.優(yōu)化圖片:例如壓縮圖片,使用CDN, 延遲加載等。

          7.刪除未使用代碼:例如刪除未使用的庫,刪除不需要的庫,刪除無用代碼,按需引入組件庫。

          8.減少JS負載:例如動態(tài)導入和代碼拆分。

          下面結合筆者的項目介紹一下筆者使用的方法:

          3.1 使用vite-compression-plugin

          可以使用 vite-compression-plugin[10] 來對代碼進行gizp壓縮,使用方法如下:

          vite.config.ts:

          javascript
          復制代碼
          import viteCompression from 'vite-plugin-compression'
          export default defineConfig({
            plugins:[
              viteCompression({
                ext: ".gz",
                algorithm: "gzip",
                deleteOriginFile: false
              })
            ]
          })

          關于插件的具體配置可以查看插件的文檔,選擇合適的壓縮算法。

          3.2 開啟ngnix的gizp壓縮

          筆者的前端項目下有一個.devops目錄,下面有一個ngnix.conf文件可以單獨配置此前端工程的ngnix:

          配置方法為在server下面增加如下配置:

          ngnix
          復制代碼
          server {
            gzip on;
            gzip_buffers 32 4K;
            gzip_comp_level 6;
            gzip_min_length 100;
            gzip_types application/javascript text/plain text/css text/xml application/json application/xml application/xml+rss;
            gzip_vary on;
            listen       80;
            location / {            
              # 此處省略location相關配置
            }
          }

          具體配置項含義以及取值,可以查詢相關文檔。

          3.3 按需自動引入element-plus

          筆者項目原來是完整引入element-plus的, main.ts文件內(nèi)容:

          Typescript
          復制代碼
          import ElementPlus from 'element-plus'
          import 'element-plus/dist/index.css'
          import App from './App.vue'

          const app = createApp(App)

          app.use(ElementPlus)
          app.mount('#app')

          這樣會導致首頁加載時被打包后的和element-plus相關的全部js和css資源被引入,但是按需引入時則不會一次性引入全部的css和js。

          按需引入element-plus的方法為:

          第一步:安裝unplugin-auto-import和unplugin-vue-components:pnpm install unplugin-auto-import unplugin-vue-components。

          第二步:vite.config.ts插件配置:

          Typescript
          復制代碼
          import AutoImport from "unplugin-auto-import/vite";
          import Components from "unplugin-vue-components/vite";
          import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
          export default defineConfig({
            plugins:[
              AutoImport({
                resolvers: [ElementPlusResolver()]
              }),
              Components({
                resolvers: [ElementPlusResolver()]
              }),
            ]
          })

          第三步:特殊插件的處理。對于對于命令式方式使用的組件,例如ElNotification, 如果不單獨引入,則會導致其樣式失效,所以需要對項目中使用到的這類組件單獨全局引入一下就OK啦:

          Typescript
          復制代碼
          import { ElInput, ElSelect, ElDatePicker, ElTimePicker } from "element-plus";
          app.use(ElInput).use(ElSelect).use(ElDatePicker).use(ElTimePicker).use(directives).use(router).use(pinia).mount("#app");

          3.4 修改百度地圖的引入方式

          原來的引入方式是在html文件中增加script標簽:

          html
          復制代碼
          <!DOCTYPE html>
          <html lang="en">
            <body >
              <div id="app">
              <script type="module" src="/src/main.ts"></script>
              <script charset="utf-8" src="https://api.map.baidu.com/api?v=1.0&&type=webgl&ak=***"></script>
            </body>
          </html>

          原來的使用方法如下:

          Typescript
          復制代碼
          const BMapGL: any = (window as any).BMapGL;
           const map = new BMapGL.Map("container");

          改成使用時異步引用:

          Typescript
          復制代碼
          const LoadBaiduMapScript = () => {
            //console.log("初始化百度地圖腳本...");
            const AK = "***";
            const BMap_URL = "https://api.map.baidu.com/api?v=1.0&&type=webgl&ak=" + AK + "&s=1&callback=onBMapCallback";
            return new Promise(resolve => {
              // 如果已加載直接返回
              if (typeof (window as any).BMapGL !== "undefined") {
                resolve((window as any).BMapGL);
                return true;
              }
              // 百度地圖異步加載回調(diào)處理
              (window as any).onBMapCallback =  () => {
                console.log("百度地圖腳本初始化成功...");
                BMapGL = (window as any).BMapGL;
                resolve((window as any).BMapGL);
              };
              // 插入script腳本
              let scriptNode = document.createElement("script");
              scriptNode.setAttribute("type""text/javascript");
              scriptNode.setAttribute("src", BMap_URL);
              document.body.appendChild(scriptNode);
            });
          };

          3.5 對圖片進行壓縮

          這里推薦一個好用的壓縮工具,熊貓壓縮——tinypng[11] 。

          用它把UI給的切圖、背景圖等壓縮一下,那必然也起到一定的作用。

          筆者就通過如上五種優(yōu)化方法對項目優(yōu)化了一下,性能得分就得到了很大的改觀,是不是覺得性能優(yōu)化也不難,哈哈哈~

          作者:NewName
          鏈接:https://juejin.cn/post/7273072756156235834
          來源:稀土掘金


          往期推薦


          代碼變更風險可視化系統(tǒng)建設與實踐
          解析Node.js鏡像原理,輕松構建高效CI/CD流程
          圍觀!華為云低代碼引擎TinyEngine正式發(fā)布

          最后


          • 歡迎加我微信,拉你進技術群,長期交流學習...

          • 歡迎關注「前端Q」,認真學前端,做個專業(yè)的技術人...

          點個在看支持我吧

          瀏覽 1645
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  一区二区三区四区欧美精品 | 一区二区三区国产视频 | 在线午夜黄色电影 | 亚洲视频中文 | 麻豆三及片 |