后臺(tái)系統(tǒng)靜態(tài)資源加載優(yōu)化實(shí)踐

前言

因?yàn)檫@系統(tǒng)之前一直在不斷迭代,現(xiàn)在暫時(shí)告一段落了龙宏,我趕緊趁著開(kāi)年工作不多的空余時(shí)間棵逊,把這個(gè)系統(tǒng)優(yōu)化一下伤疙,不然我可能就被優(yōu)化了银酗。

優(yōu)化做啥

說(shuō)到優(yōu)化,網(wǎng)上一查一大堆教你的方法徒像,要說(shuō)的話黍特,人人都能說(shuō)兩句,但是做的話不一定人人都能做好锯蛀。那么我們?cè)撊绾芜\(yùn)用這些知識(shí)呢灭衷?

本系統(tǒng)基本情況:

  • 構(gòu)建工具 vite4
  • 框架 vue3
  • UI組件庫(kù) tdesign
  • 公司內(nèi)部業(yè)務(wù)組件庫(kù) sutpc-charts-utils

要優(yōu)化,我們首先要知道有沒(méi)有問(wèn)題旁涤,問(wèn)題自查的途徑有很多翔曲,我這里用了瀏覽器自帶的lighthouse,得到初步結(jié)果如下

自查結(jié)果1.png
自查結(jié)果2.png

不同的系統(tǒng)優(yōu)化關(guān)注點(diǎn)不一樣迫像,由于我這個(gè)系統(tǒng)是一個(gè)后臺(tái)系統(tǒng),我這里主要關(guān)注性能瞳遍,也就是圖中的Performance的得分51的那部分闻妓,再一看這幾個(gè)指標(biāo) 如 FCP\ TTI \ LCP,一看就知道不太ok了掠械,時(shí)間都4由缆、5秒了,再看看網(wǎng)絡(luò)資源加載方面:


網(wǎng)絡(luò).png

響應(yīng)標(biāo)頭.png

根據(jù)經(jīng)驗(yàn)一看就會(huì)發(fā)現(xiàn)有的js\css存在體積過(guò)大猾蒂,而且都沒(méi)有g(shù)zip壓縮導(dǎo)致加載時(shí)間比較長(zhǎng)的問(wèn)題均唉,同時(shí),lighthouse也有對(duì)應(yīng)的診斷肚菠,以及對(duì)應(yīng)的改善建議

診斷舔箭、改善建議.png

如下圖,點(diǎn)開(kāi)第一條建議蚊逢,果不其然限嫌,是讓你開(kāi)啟資源壓縮,壓縮方法有:gzip,deflate或者brotli时捌,我們用常用的gzip即可怒医,它一般壓縮率在70%左右。


第一條建議.png

然后再看看其他優(yōu)化建議奢讨,包括

  • 減少未使用的JavaScript并延遲加載腳本稚叹,直到需要它們, 來(lái)減少網(wǎng)絡(luò)活動(dòng)消耗的字節(jié)數(shù)
  • 資源正在阻止頁(yè)面的第一次繪制∧弥睿考慮內(nèi)聯(lián)交付關(guān)鍵JS/CSS扒袖,并推遲所有非關(guān)鍵JS/樣式
  • 減少未使用的css
  • 使用http2代替目前的http1.1
  • 使用高效的緩存策略為靜態(tài)資產(chǎn)提供服務(wù)
  • 避免昂貴的dom操作

還有一些其他小建議就不一 一列舉了

由于本系統(tǒng)的資源都在同一個(gè)域名(IP)下,且http協(xié)議是1.1版本, 所以會(huì)有最多6個(gè)TCP連接同時(shí)創(chuàng)建的限制亩码。其實(shí)最好的辦法還是上http2, 但是這又要先上https證書(shū)才行季率,考慮到這系統(tǒng)公司暫時(shí)不可能花錢(qián)搞這個(gè)證書(shū),所以http2的想法就算了描沟。

最后飒泻,根據(jù)現(xiàn)有問(wèn)題、優(yōu)化建議和實(shí)際情況吏廉,我打算做 代碼瘦身泞遗、打包時(shí)的代碼分割、gzip壓縮席覆、設(shè)置合適的緩存策略

具體操作:
1史辙、移除未使用的插件,檢查代碼發(fā)現(xiàn)有一些插件如vue3-lazy vue3-clipboard沒(méi)用到,刪掉
2聊倔、配置代碼分割
vite默認(rèn)node_modules的非公用依賴全給你打到一個(gè)vendor.js里面去晦毙,導(dǎo)致的問(wèn)題就是太大加載慢,所以需要分割耙蔑,方便并行加載结序。方法就是自定義打包策略,如下例子纵潦,把非源碼的依賴單獨(dú)提取出來(lái)徐鹤,再配合強(qiáng)緩存策略。

build: {
      rollupOptions: {
        output: {
          manualChunks: {
            'sutpc-charts-utils': ['sutpc-charts-utils'],
            'vue-vendor': ['vue', 'vue-router', 'pinia'],
            tdesign: ['tdesign-vue-next'],
          }
        }
      }
    },
分割前.png
分割后.png

看出來(lái)邀层,優(yōu)化前后主要變化是一個(gè)3366kb的chunk變成 兩個(gè), 分別是1037kb \ 2464kb , 在依賴不多的情況下返敬,優(yōu)化效果不大,至于其他的小chunk塊變化不大寥院。

3劲赠、配置gzip
讓運(yùn)維幫忙配置一下nginx,開(kāi)啟gzip

    gzip on;
    gzip_disable "msie6";
    gzip_min_length 1024;
    gzip_buffers     4 16k;
    gzip_vary on;
    gzip_comp_level 5;
    gzip_static on;
    gzip_types text/plain text/css   application/json application/javascript

然后測(cè)試一下發(fā)現(xiàn)個(gè)問(wèn)題,如下圖


gzip開(kāi)啟的問(wèn)題.png

好家伙秸谢!資源加載更慢了凛澎!如下圖,隨便點(diǎn)開(kāi)某個(gè)請(qǐng)求一看原來(lái)是服務(wù)器響應(yīng)慢估蹄,可能是啥原因呢塑煎?

耗時(shí).png

是服務(wù)端自己的問(wèn)題,仔細(xì)看了一下nginx配置找到了問(wèn)題 :gzip_comp_level 5

改一下nginx配置, 把 gzip_comp_level 5改成 gzip_comp_level 2臭蚁,因?yàn)閘evel越高越占用cpu資源最铁,現(xiàn)在改低應(yīng)該可以把服務(wù)響應(yīng)耗時(shí)短一點(diǎn)

    gzip_comp_level 2;
gzip_comp_level 2.png

看起來(lái) “請(qǐng)求-響應(yīng)” 時(shí)間確實(shí)從平均1.3s 降低到 700ms左右,約有4垮兑、50%的提升

優(yōu)化完了冷尉,重新從lighthouse測(cè)試看一下成果


優(yōu)化后1.png
優(yōu)化后2.png

從效果上來(lái)看,Performance從51 到 78分系枪,幾個(gè)相關(guān)指標(biāo)時(shí)間也進(jìn)入了2s左右雀哨,感覺(jué)效果還行。

能不能再快點(diǎn)私爷?

從上面的幾個(gè)關(guān)鍵資源加載情況來(lái)看雾棺,基本都要700ms左右,能不能再快點(diǎn)的当犯?其實(shí)是可以的垢村。因?yàn)樯厦娴膎ginx的gzip設(shè)置都是實(shí)時(shí)壓縮的割疾,就是說(shuō)每次請(qǐng)求資源嚎卫,服務(wù)器都要把該文件壓縮完再返回,這里是存在浪費(fèi)時(shí)間的,由于這些靜態(tài)資源每次打包生成之后就不會(huì)變化了拓诸,我們可以直接把它壓縮好侵佃,這樣子請(qǐng)求時(shí)直接把壓縮好的資源返回就行了,省去每次請(qǐng)求都去壓縮的時(shí)間開(kāi)銷奠支,網(wǎng)絡(luò)io就會(huì)更快馋辈!怎么做呢?裝個(gè)壓縮插件即可倍谜。

pnpm i vite-plugin-compression2 -D

vite.config.js配置

import { compression } from 'vite-plugin-compression2'

    plugins: [
       ...其他插件
      compression({
        threshold: 1024,
        include: [/\.css$/, /\.js$/]
      })
    ],

上面配置對(duì)只對(duì)打包后大于1k的css迈螟、 js壓縮,發(fā)現(xiàn)會(huì)多了一份后綴名是.gz的文件尔崔,然后把dist目錄部署到服務(wù)上答毫,nginx響應(yīng)這些資源請(qǐng)求時(shí)會(huì)直接把對(duì)應(yīng).gz的文件返回。


壓縮.png
gzip壓縮后.png
指標(biāo)得分.png

重新部署查看網(wǎng)絡(luò)瀑布流季春,發(fā)現(xiàn)從請(qǐng)求耗時(shí)從700ms降低到100ms左右洗搂,提速明顯,但是lighthouse重新測(cè)試發(fā)現(xiàn) FCP \ LCP \ SI 指標(biāo)得分并沒(méi)有提升多少载弄,Performance總得分也還是70多耘拇,這就奇怪了,從官方的建議來(lái)看宇攻,現(xiàn)在應(yīng)該是GOOD階段范圍了

LCP scope.png

點(diǎn)擊LCP指標(biāo)下方的“查看原始追蹤記錄”按鈕惫叛,進(jìn)去查看:

原始追蹤記錄.png

從圖中可以看到LCP也就在1.2s左右的位置,哪里是lighthouse寫(xiě)的2.2s ? 不知道它是怎么算的逞刷,你知道嗎挣棕?歡迎留言討論。

4亲桥、 靜態(tài)資源設(shè)置強(qiáng)緩存洛心、協(xié)商緩存
在我另外一篇文章《徹底弄懂強(qiáng)緩存與協(xié)商緩存》說(shuō)過(guò)緩存的原理,這里直接用上結(jié)論:index.html設(shè)置協(xié)商緩存题篷,其他的設(shè)置強(qiáng)緩存词身。由于我這環(huán)境的nginx默認(rèn)是有協(xié)商緩存的,所以我只配置需要強(qiáng)緩存的資源番枚,如下法严,js|css|png|jpg 等資源強(qiáng)緩存30天,即2628000秒

location ~.*\.(js|css|png|jpg)$ {
    add_header Cache-Control "max-age=2628000, private";
}

設(shè)置這些緩存只是對(duì)二次打開(kāi)頁(yè)面有用葫笼,對(duì)第一次打開(kāi)測(cè)試效果沒(méi)意義深啤。截止目前來(lái)看最大的問(wèn)題還是代碼問(wèn)題,如下最新的測(cè)試結(jié)果路星,查看優(yōu)化建議如下圖所示只剩下 3條建議

  1. 減少未使用的js\css
  2. 考慮內(nèi)聯(lián)腳本樣式
  3. 推遲所有非關(guān)鍵js\css


    剩下建議.png

    5溯街、增大代碼覆蓋率
    其實(shí)要減少未使用的代碼,我們得先了解一個(gè)概念:代碼有個(gè)指標(biāo)是代碼覆蓋率;代碼覆蓋率 = 使用的部分 / 全部呈昔;代碼覆蓋率越大說(shuō)明你的代碼用到的刀刃上的越多挥等,而不是下載一大堆,只用一小部分功能堤尾。比如你引入了整個(gè)loadsh,只用到了深拷貝功能肝劲,其他沒(méi)用到的功能代碼也被打包部署,導(dǎo)致用戶請(qǐng)求資源時(shí)浪費(fèi)帶寬郭宝,浪費(fèi)時(shí)間辞槐,阻塞渲染。


    view Treemap.png

    代碼覆蓋率.png

根據(jù)上圖的代碼覆蓋率來(lái)看粘室,圖中底部的表格中Coverage列里面的柱子催蝗,其中紅色的部分表示是未使用的,所以我這里還是需要繼續(xù)代碼瘦身育特,把不用到的部分剔除丙号。而且大頭是前面兩個(gè)js,體積大缰冤,而未使用部分又占比大犬缨。根據(jù)上文列舉的剩下的3條優(yōu)化建議,內(nèi)聯(lián)腳本樣式不太現(xiàn)實(shí)棉浸,所以按照建議去

  1. 減少未使用的js\css
  2. 推遲所有非關(guān)鍵js\css

我的具體做法就是 把在main.ts全量引入sutpc-charts-utils這個(gè)組件庫(kù)的代碼刪掉怀薛,改成在局部頁(yè)面去按需引入具體的組件、配合defineAsyncComponent異步組件實(shí)現(xiàn)按需加載迷郑,也就實(shí)現(xiàn)了“減少未使用的js\css枝恋、推遲所有非關(guān)鍵js\css”

main.ts變化.png

局部頁(yè)面異步方式按需引入MatrixEditor組件的例子

const MatrixEditor = defineAsyncComponent(() => import('sutpc-charts-utils/dist/matrix-editor').then(({MatrixEditor}) => MatrixEditor))
import 'sutpc-charts-utils/dist/matrix-editor/style.css';

export default defineComponent({
  render(){
    return <div>
      <MatrixEditor />
    </div>
  }
})

再次打包嗡害,發(fā)現(xiàn)原來(lái)最大的chunk: sutpc-charts-utils-[hash].js沒(méi)了, 多了幾個(gè)幾百k的js焚碌,因?yàn)檫@些獨(dú)立組件本來(lái)就比較大。至于tdesign-[hash].js暫時(shí)不變霸妹,沒(méi)改按需引入十电。

按需引入后打包.png

最后再部署測(cè)試一次 , Performance 90+分,F(xiàn)CP \ SI \ LCP \ TTI 幾乎進(jìn)入秒級(jí)叹螟!
最后測(cè)試結(jié)果.png

總結(jié)

本次優(yōu)化主要是通過(guò)移除未使用的代碼鹃骂、代碼分割、gzip壓縮設(shè)置罢绽、按需引入等手段畏线,降低了首屏資源請(qǐng)求時(shí)的“請(qǐng)求-響應(yīng)”時(shí)間,從而達(dá)到資源加載優(yōu)化的目的良价。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末寝殴,一起剝皮案震驚了整個(gè)濱河市蒿叠,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌杯矩,老刑警劉巖栈虚,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件袖外,死亡現(xiàn)場(chǎng)離奇詭異史隆,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)曼验,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)泌射,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人鬓照,你說(shuō)我怎么就攤上這事熔酷。” “怎么了豺裆?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵拒秘,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我臭猜,道長(zhǎng)躺酒,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任蔑歌,我火速辦了婚禮羹应,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘次屠。我一直安慰自己园匹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布劫灶。 她就那樣靜靜地躺著裸违,像睡著了一般。 火紅的嫁衣襯著肌膚如雪本昏。 梳的紋絲不亂的頭發(fā)上累颂,一...
    開(kāi)封第一講書(shū)人閱讀 51,679評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音凛俱,去河邊找鬼紊馏。 笑死,一個(gè)胖子當(dāng)著我的面吹牛蒲犬,可吹牛的內(nèi)容都是我干的朱监。 我是一名探鬼主播,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼原叮,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼赫编!你這毒婦竟也來(lái)了巡蘸?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤擂送,失蹤者是張志新(化名)和其女友劉穎悦荒,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體嘹吨,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡搬味,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蟀拷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碰纬。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖问芬,靈堂內(nèi)的尸體忽然破棺而出悦析,到底是詐尸還是另有隱情,我是刑警寧澤此衅,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布强戴,位于F島的核電站,受9級(jí)特大地震影響挡鞍,放射性物質(zhì)發(fā)生泄漏骑歹。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一匕累、第九天 我趴在偏房一處隱蔽的房頂上張望陵刹。 院中可真熱鬧,春花似錦欢嘿、人聲如沸衰琐。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)羡宙。三九已至,卻和暖如春掐隐,著一層夾襖步出監(jiān)牢的瞬間狗热,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工虑省, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留匿刮,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓探颈,卻偏偏與公主長(zhǎng)得像熟丸,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子伪节,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容