前端性能優(yōu)化綜合分析

一,性能問(wèn)題的簡(jiǎn)單分析、直接表現(xiàn)、根本原因

簡(jiǎn)單分析:

???首先,一個(gè)完整的頁(yè)面主要由兩部分組成,一是UI,二是數(shù)據(jù)。如果按照MVC架構(gòu),或是數(shù)據(jù)與表現(xiàn)分離的思想,還可以細(xì)分成三部分。一是通過(guò)html(結(jié)構(gòu))+css(表現(xiàn))渲染出來(lái)的UI層(view),二是通過(guò)http來(lái)完成的數(shù)據(jù)層(model),三是將數(shù)據(jù)填充到view或者DOM操作的控制層(controller)。

???于是,一次完整的頁(yè)面加載就可以分成三部分工作,一是view渲染(UI),二是數(shù)據(jù)加載(http),三是數(shù)據(jù)填充到view或更改(DOM操作)。其中只要有一個(gè)環(huán)節(jié)出問(wèn)題,都有可能造成性能問(wèn)題。

綜上所述,我們可以總結(jié)出三個(gè)主要可能造成性能問(wèn)題的環(huán)節(jié):UI渲染、http請(qǐng)求、DOM操作。

???總而言之,要優(yōu)化性能問(wèn)題,就需要對(duì)可能造成性能問(wèn)題的環(huán)節(jié)逐個(gè)擊破。

直接表現(xiàn):

1,頁(yè)面加載時(shí)間過(guò)長(zhǎng)

2,卡頓、閃現(xiàn)、頁(yè)面結(jié)構(gòu)錯(cuò)亂等現(xiàn)象

根本原因:

1,DOM結(jié)構(gòu)復(fù)雜

2,過(guò)度或不恰當(dāng)?shù)腄OM操作

3,http請(qǐng)求過(guò)多、請(qǐng)求時(shí)間過(guò)長(zhǎng)、請(qǐng)求異常(中斷、無(wú)響應(yīng)、請(qǐng)求錯(cuò)誤)等情況

下面,針對(duì)以上可能造成性能問(wèn)題的環(huán)節(jié),進(jìn)行逐個(gè)優(yōu)化。

二,性能優(yōu)化之——DOM結(jié)構(gòu)優(yōu)化

1,保證簡(jiǎn)潔、清晰的html結(jié)構(gòu),減少或避免多余的html標(biāo)簽

2,使用HTML5的web語(yǔ)義化標(biāo)簽,保證結(jié)構(gòu)清晰,同時(shí)利于seo

3,避免過(guò)于復(fù)雜的DOM結(jié)構(gòu),避免過(guò)度嵌套

4,采用SPA(單頁(yè)應(yīng)用)模式開(kāi)發(fā),動(dòng)態(tài)按需加載

三,性能優(yōu)化之——DOM操作優(yōu)化

1,理解DOM操作:

為什么DOM操作會(huì)引起性能問(wèn)題?

首先,每次DOM操作,頁(yè)面DOM結(jié)構(gòu)通常都有可能會(huì)被改變,瀏覽器一旦檢測(cè)到DOM結(jié)構(gòu)發(fā)生改變,就會(huì)進(jìn)行全局的重繪,相當(dāng)于每次DOM操作都對(duì)頁(yè)面重新渲染了一遍。

因此DOM操作的過(guò)程其實(shí)是頁(yè)面不斷重復(fù)渲染的過(guò)程,如果這個(gè)過(guò)程很復(fù)雜,或者操作頻繁,或邏輯錯(cuò)誤,就會(huì)造成性能問(wèn)題。

可是,DOM操作是不可避免的,于是我們優(yōu)化的思路是減少DOM操作頻率。

2, 減少DOM操作的方法:

(1) 使用innerHTML屬性替代DOM操作

innerHTML不會(huì)進(jìn)行全局的重繪,而是局部重繪,因此對(duì)性能影響較小。

(2) 使用react、vue等性能較好的框架

這類(lèi)框架都對(duì)DOM操作進(jìn)行過(guò)特殊處理,性能較好。以react為例,react內(nèi)部將虛擬DOM、diff算法、

innerHTML三者結(jié)合起來(lái)處理DOM操作,避免了用戶直接操作DOM。

(3) 避免或減少使用jquery等DOM操作庫(kù)

四,性能優(yōu)化之——http優(yōu)化

http性能優(yōu)化方法:優(yōu)化靜態(tài)資源和api請(qǐng)求。

(一) 理解http請(qǐng)求

1,理解http請(qǐng)求的類(lèi)型

http請(qǐng)求分兩大類(lèi),一類(lèi)是靜態(tài)資源請(qǐng)求,另一類(lèi)就是api請(qǐng)求(請(qǐng)求后臺(tái)接口)。

** (1) 靜態(tài)資源請(qǐng)求 **

所謂靜態(tài)資源請(qǐng)求,就是頁(yè)面加載時(shí)從服務(wù)器下載html、css、js、圖片等靜態(tài)資源文件。

靜態(tài)資源請(qǐng)求,如下圖:

靜態(tài)資源請(qǐng)求.png

** (2) api請(qǐng)求 **

所謂api請(qǐng)求,就是請(qǐng)求后臺(tái)的接口所發(fā)出的http請(qǐng)求。如下圖:

api請(qǐng)求.png

簡(jiǎn)而言之,http性能優(yōu)化,其實(shí)是對(duì)靜態(tài)資源(html、css、js、圖片)和api請(qǐng)求的優(yōu)化。

2,理解http請(qǐng)求帶來(lái)的性能問(wèn)題:

如果你理解http工作原理,那應(yīng)該知道每次http請(qǐng)求過(guò)程的復(fù)雜性,代價(jià)是很高的。
因此,如果出現(xiàn)http請(qǐng)求過(guò)多、請(qǐng)求時(shí)間過(guò)長(zhǎng)、請(qǐng)求異常(中斷、無(wú)響應(yīng)、請(qǐng)求錯(cuò)誤)等都有可能會(huì)對(duì)性能造成影響。

下面就針對(duì)http請(qǐng)求的優(yōu)化方案展開(kāi)講解。

(二) 靜態(tài)資源優(yōu)化

靜態(tài)資源有html、css、js、圖片等類(lèi)型。因此要對(duì)它們進(jìn)行分門(mén)別類(lèi)地優(yōu)化。

如果請(qǐng)求的靜態(tài)資源過(guò)多、過(guò)大、或不存在等,都可能會(huì)造成性能問(wèn)題。

靜態(tài)資源優(yōu)化的辦法,就是對(duì)靜態(tài)資源進(jìn)行切割、合并、壓縮等處理,以達(dá)到縮小靜態(tài)資源體積、減少靜態(tài)資源請(qǐng)求次數(shù)等目標(biāo),以實(shí)現(xiàn)快速完成http請(qǐng)求的過(guò)程。

下面對(duì)靜態(tài)資源優(yōu)化,分門(mén)別類(lèi)來(lái)講解。

1,html結(jié)構(gòu)優(yōu)化

(1) 保證簡(jiǎn)潔、清晰的html結(jié)構(gòu),減少或避免多余的html標(biāo)簽

(2)     使用HTML5的web語(yǔ)義化標(biāo)簽,結(jié)構(gòu)清晰且利于seo
    
(3) css文件在head中引入,js文件放在body底部引入,這樣做可以防止阻塞。另外如果有需要提前加

    載的js,請(qǐng)?jiān)趙indow.onload方法中處理。
    
 解釋?zhuān)?瀏覽器加載js文件時(shí)其他一切渲染活動(dòng)都會(huì)停止,直到j(luò)s文件下載完成, 如果把js文件放頭部
 
       加載,就會(huì)造成阻塞,也就是加載js時(shí)會(huì)阻止頁(yè)面渲染。 因此通常js文件需要放body底部加
       
       載,等頁(yè)面渲染完成后再加載js文件。

2,css優(yōu)化

(1) 使用gulp、webpack等構(gòu)建工具,對(duì)css進(jìn)行合并、壓縮等處理,以縮小css文件體積

(2) 如果你的應(yīng)用css樣式很龐大,可拆分成多個(gè)css文件,并做壓縮處理,避免單個(gè)css文件過(guò)大

(3) 如果使用webpack,推薦使用extract-text-webpack-plugin之類(lèi)的插件將css樣式抽離出來(lái),防止其隨js一起打包

(4) 如果使用react、vue等框架,推薦使用css-modules、css in js等css模塊化解決方案。

(5) 使用sass/less等預(yù)編譯處理方案(后期不推薦使用,推薦使用css模塊化方案)
       
(6) 盡量減少或避免使用內(nèi)聯(lián)樣式

(7) 對(duì)于一些需要復(fù)雜計(jì)算的樣式,比如box-shadow、import等,減少使用。

(8) 使用css3動(dòng)畫(huà)時(shí),請(qǐng)開(kāi)啟GPU硬件加速。

3,js優(yōu)化

(1) 使用gulp、webpack等構(gòu)建工具進(jìn)行合并、壓縮處理,以縮小js文件體積和數(shù)量

(2) 使用webpack構(gòu)建時(shí),推薦拆分成2-3個(gè)js文件進(jìn)行打包,并開(kāi)啟壓縮,防止單個(gè)js文件過(guò)大

(3) 使用webpack構(gòu)建時(shí),推薦使用tree-shaking、prepack插件優(yōu)化js代碼構(gòu)建,縮小體積

(4) 使用innerHTML替代DOM操作,防止頁(yè)面不斷重復(fù)地全局渲染

(5) 使用react、vue等高性能UI構(gòu)建框架,避免直接操作DOM。

(6) 使用jslint等js語(yǔ)法檢查工具,優(yōu)化js代碼

4,圖片資源優(yōu)化

(1) 圖片合并——對(duì)小圖進(jìn)行sprite(雪碧圖)處理

(2) 圖片壓縮——縮小圖片體積

(3) 圖片大小——做圖時(shí)避免單個(gè)圖片過(guò)大,最好能控制在500k以內(nèi)

靜態(tài)資源優(yōu)化推薦的工具:gulp、webpack、fis3

(三) api請(qǐng)求優(yōu)化

api請(qǐng)求,也就是請(qǐng)求后端工程師編寫(xiě)的后臺(tái)接口,如果請(qǐng)求過(guò)程中出現(xiàn)中斷、掛起(無(wú)響應(yīng))、響應(yīng)超時(shí)、響應(yīng)時(shí)間過(guò)長(zhǎng)等問(wèn)題,使得客戶端長(zhǎng)時(shí)間獲取不到數(shù)據(jù),頁(yè)面得不到數(shù)據(jù)填充,也會(huì)造成性能影響。

api請(qǐng)求優(yōu)化主要從兩方面入手,一是客戶端做http請(qǐng)求異常處理,二是后端接口優(yōu)化。

1,http請(qǐng)求異常處理

(1) 請(qǐng)求超時(shí)處理——timeout

   當(dāng)http請(qǐng)求超過(guò)限定的時(shí)間后中斷請(qǐng)求,給予用戶相應(yīng)的提示。
   
(2) 錯(cuò)誤處理

   根據(jù)不同的響應(yīng)錯(cuò)誤給予用戶相應(yīng)的提示。

2,后端接口優(yōu)化

(1) 避免無(wú)響應(yīng)的情況發(fā)生

(2) 避免過(guò)度操作復(fù)雜的邏輯

(3) 避免過(guò)度的嵌套查詢

(4) 與前端約定好一套響應(yīng)規(guī)則,包括響應(yīng)狀態(tài)碼、數(shù)據(jù)格式、消息提示等等

(5) 服務(wù)器開(kāi)啟gzip壓縮、以及服務(wù)器緩存

四,其他優(yōu)化

  1,服務(wù)器緩存
  
    善用緩存,只加載初始化或有更新?tīng)顟B(tài)的資源,對(duì)無(wú)更新?tīng)顟B(tài)的資源則返回已緩存的結(jié)果。
    
    這樣可實(shí)現(xiàn)快速響應(yīng)請(qǐng)求、減少服務(wù)器帶寬占用和資源浪費(fèi)。
    
    對(duì)于資源的更新,可對(duì)資源添加時(shí)間戳或隨機(jī)字符串的形式來(lái)處理,可參考gulp、webpack版本控制實(shí)現(xiàn)
    
  2,客戶端緩存——cookie、WebStorage
  
    客戶端可對(duì)http請(qǐng)求的結(jié)果進(jìn)行緩存,在數(shù)據(jù)無(wú)更新的狀態(tài)下,可直接使用已緩存的結(jié)果,而不用再次發(fā)出多余的http請(qǐng)求。這對(duì)于一些不變或更新頻率較低的數(shù)據(jù)尤為實(shí)用。
    
    客戶端緩存的方案主要有cookie、WebStorage、Application Cache。善用它們可提高你的應(yīng)用的性能。

  3,使用cdn存儲(chǔ)靜態(tài)資源     

    使用cdn服務(wù)器存儲(chǔ)圖片、文件、音頻/視頻等靜態(tài)資源文件,這樣可避免過(guò)多占用服務(wù)器帶寬和服務(wù)器磁盤(pán)空間。

    若配置有不同地域多節(jié)點(diǎn)cdn服務(wù)器,可實(shí)現(xiàn)就近節(jié)點(diǎn)傳輸,加快http請(qǐng)求速度。   
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,324評(píng)論 25 708
  • 圍繞前端的性能多如牛毛,涉及到方方面面,以我我們將圍繞PC瀏覽器和移動(dòng)端瀏覽器的優(yōu)化策略進(jìn)行羅列注意,是羅列不是展...
    流動(dòng)碼文閱讀 750評(píng)論 0 0
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,695評(píng)論 19 139
  • AJax 優(yōu)化 緩存 Ajax 請(qǐng)求盡量使用GET, 僅取決于cookie數(shù)量 Cookie 優(yōu)化 減少Cooki...
    KeKeMars閱讀 9,477評(píng)論 5 89
  • 他再一次面對(duì)著鏡子確認(rèn)著自己的著裝打扮是否有不妥當(dāng)?shù)牡胤?,手指搓上一點(diǎn)發(fā)膠試圖想讓劉海前那一縷不安分的頭發(fā)變得服帖...
    月刊少年喵帕斯閱讀 396評(píng)論 0 2

友情鏈接更多精彩內(nèi)容