前端性能優(yōu)化總結(jié)

先說總結(jié)筝蚕,前端優(yōu)化核心邏輯就是:
減少請求數(shù)(或同時間請求數(shù))與請求資源大小刃鳄,減少重繪與回流


減少請求數(shù)(或者同一時間請求數(shù))與請求資源大小

  1. 文件壓縮與合并
    html css js文件壓縮合并打包到推,比如gzip壓縮继效,js混淆等(目前多通過webpack構(gòu)建處理)是钥,壓縮打包后減少了資源大小與請求數(shù)量

  2. 圖片壓縮

  • 雪碧圖(又稱精靈圖):多張小圖片合成一張大圖減少請求數(shù)
  • 項目圖片無損壓縮后再使用讥巡, 這里推薦一個壓縮工具https://tinypng.com/
  • 小圖片base64化:一些小圖片(一般不超過5k),可以通過轉(zhuǎn)成base64的方式直接打入資源包芹啥,這樣就減少了請求數(shù)锻离,目前流行的方案是通過webpackurl-loaderloader配置處理,不過圖片轉(zhuǎn)成base64會提高33%大腥鳌(原理是把圖片每3個字節(jié)轉(zhuǎn)成了4個字節(jié))纳账,所以不能轉(zhuǎn)太大的圖片逛薇,會造成資源包過大捺疼。
  1. 加載優(yōu)化(加載優(yōu)化并不減少請求數(shù),主要是利用一些技巧提升用戶體驗)
    服務(wù)端ssr首屏渲染: 多用于優(yōu)化移動端應(yīng)用用戶體驗永罚,提高首屏加載速度啤呼。一些應(yīng)用不想首頁顯示后ajax獲取相關(guān)數(shù)據(jù)造成的閃動或loading卧秘,通過服務(wù)端渲染ssr的方式解決首屏加載問題,缺點對服務(wù)端壓力大(ssr能講的特別多官扣,不展開了翅敌,感興趣可以自己了解)
    預(yù)加載: 資源提前請求,需要是從緩存中加載惕蹄。常見于H5活動頁H5小游戲蚯涮,為了保證整體頁面的流暢度,預(yù)判用戶行為預(yù)先加載資源(例如guagame那樣加載所有圖片資源后開始游戲)
    懶加載: 按需加載也稱延遲加載卖陵,用于減少無效資源的加載遭顶。常見兩種實現(xiàn):

    1. 代理加載:方法是圖片加載時先使用默認loading圖占位,實際圖片加載后替換泪蔫,這樣就可以更快顯示整體頁面布局棒旗,提高用戶體驗
    2. 按需加載(目前主要有2種應(yīng)用實現(xiàn))
      • 監(jiān)聽滾動條事件,當資源(主要是圖片)即將進入視圖區(qū)域時再加載顯示撩荣,核心就是監(jiān)聽滾動高度scrollTop與元素高度clientHeight的比較
      • 監(jiān)聽用戶交互事件(比如點擊)铣揉,一些封裝組件,只有當用戶使用相關(guān)功能的時候加載餐曹,核心邏輯就是響應(yīng)事件后動態(tài)創(chuàng)建script標簽加載資源(目前主流也是通過webpack配置() => import(**/**.js)這樣的語法實現(xiàn))逛拱,最典型的場景就是路由跳轉(zhuǎn)
  2. 緩存優(yōu)化(核心還是盡量復(fù)用本地資源,減少請求數(shù)台猴,減少請求資源大虚偃)

    1. 使用CDN:CDN作為靜態(tài)資源文件的分發(fā)網(wǎng)絡(luò)(名詞解釋就是它能夠能夠?qū)崟r地根據(jù)網(wǎng)絡(luò)流量和各節(jié)點連接、負載狀況以及到用戶的距離和響應(yīng)時間等綜合信息將用戶請求重新導(dǎo)向離用戶最近的服務(wù)節(jié)點上卿吐,以達到用戶就近取得所需的目的)能加快網(wǎng)站的資源加載速度旁舰,有效利用緩存的靜態(tài)資源,下面說幾個關(guān)于cdn的擴展問題:

      • cdn緩存導(dǎo)致用戶拿不到最新文件:通用解決辦法還是通過webpack打包將文件名hash處理嗡官,通過文件名變動讓cdn緩存失效箭窜,每次版本更新,webpack會分析變動衍腥,只改變文件有變動的文件名磺樱,最大化的利用緩存,還要提醒一點婆咸,作為主入口的index.html是不緩存的竹捉,因為現(xiàn)代前端工程里面,index.html都是模板文件非常小尚骄,不需要緩存块差,以防止主入口更新失效,而模板里面的引入的資源文件路徑都是根據(jù)hash動態(tài)生成,根據(jù)文件變動可以及時更新
      • 域名發(fā)散:http1協(xié)議一個網(wǎng)絡(luò)鏈接憨闰,后一個網(wǎng)絡(luò)請求必須等前一個請求結(jié)束才能使用状蜗,而目前主流的游覽器都對同一域名下的最大網(wǎng)絡(luò)鏈接數(shù)有限制,比如chrome是6鹉动,如果頁面里圖片等加載資源過多轧坎,加載邏輯就變成了串行的加載,影響效率泽示,所以將靜態(tài)資源放置在多個子域名下面繞過這個限制缸血,最大化利用游覽器并行加載。(http2沒有這個問題械筛,因為http2協(xié)議使用一種信道復(fù)用的技術(shù)属百,允許同一個網(wǎng)絡(luò)鏈接可以并行的發(fā)送請求,前面的請求不完成并不會堵塞后面的請求)
    2. cookie優(yōu)化:因為cookie一直在游覽器與服務(wù)器中間傳遞变姨,所以cookie優(yōu)化的核心就是減少cookie大小族扰,

      • 去除沒必要的cookie
      • 設(shè)置合適的cookie過期時間(通過max-age字段)
      • 靜態(tài)資源cdn的域名和主站的域名要分開,一些js定欧,css渔呵,圖片資源請求攜帶cookie是多余的,所以請求這些資源不需要發(fā)送cookie(可通過domain字段設(shè)置)
    3. HTTP緩存(主要介紹關(guān)于資源緩存有效時間和資源文件識別相關(guān)的字段):
      Pragma:可設(shè)置no-cache禁用緩存砍鸠,兼容性最好扩氢,優(yōu)先級高于Cache-Control,最高優(yōu)先級
      Expires: 設(shè)置過期時間爷辱,優(yōu)先級低于PragmaCache-Control录豺,此時間是服務(wù)器時間,如果和本地時間不統(tǒng)一會導(dǎo)致問題
      Cache-Control: 解決Expires服務(wù)器時間與本地時間統(tǒng)一問題饭弓,優(yōu)先級高于Expires双饥,此字段請求和響應(yīng)都可以設(shè)置(屬性很多,說些關(guān)鍵的弟断,感興趣可以自行深入了解)

      • no-cache 不緩存
      • max-age=delta-seconds 服務(wù)端(響應(yīng)情況)設(shè)置最大有效時間delta-seconds(有效時間內(nèi)游覽器直接緩存拿數(shù)據(jù)咏花,不請求) 客戶端(請求情況)就是告知服務(wù)端希望接受一個存在時間不超過``delta-seconds`秒的資源
      • s-maxage=delta-seconds 同max-age,區(qū)別是這個delta-seconds是設(shè)置的代理服務(wù)器時間
      • only-if-cached 代理服務(wù)器如果有資源不需要去服務(wù)器請求
      • must-revalidate 資源一定是從服務(wù)器獲取阀趴,而非代理服務(wù)器緩存昏翰,如果失敗返回504
      • last-modified與if-modified-since: 服務(wù)器通過last-modified字段告知客戶端資源修改最后時間,游覽器儲存后通過if-modified-since字段發(fā)送儲存時間刘急,服務(wù)端收到請求后判斷接收到的時間是否與當前一致棚菊,如果一致返回304,不返回資源叔汁,如果不一致统求,返回200检碗,更新新的緩存時間并返回新的資源
      • eTag :效果等同于last-modified,有時候文件時間修改了球订,但是文件內(nèi)容沒有變化,這就導(dǎo)致last-modified不準確瑰钮,所以通過文件hash值確定文件變化,是一種更準備的緩存策略
// Cache-Control可以多段設(shè)置 
Cache-Control: max-age=3600, must-revalidate  // 表示一定從原服務(wù)器獲取資源弛房,獲取后1小時內(nèi)無需再次請求走緩存
/* 
總結(jié):
一個請求害驹,可能有三種狀態(tài):
1. 本地有資源,也沒有過期 這時候返回就是 200(from cache)苟耻,直接走本地資源 最快(Cache-Control)
2. 本地有資源篇恒,但是過期了,去服務(wù)端請求凶杖,服務(wù)端判斷文件沒變化胁艰,返回304,不更新文件資源智蝠,還是走本地資源腾么,一個簡單的網(wǎng)絡(luò)請求,也很快(last-modified與eTag字段)
3. 本地有資源(或者沒資源)杈湾,服務(wù)端判斷文件有變化或者第一次請求解虱,返回200,并發(fā)送文件資源漆撞,網(wǎng)絡(luò)請求加資源下載殴泰,最慢 
*/

減少重繪與回流

回流(reflow): 觸發(fā)頁面重布局的行為(消耗很大),比如盒模型相關(guān)屬性改變浮驳,定位與浮動悍汛,節(jié)點內(nèi)容改變等,當頁面布局和幾何屬性變化就需要回流
重繪(repaint): 不改變文檔流布局至会,只改變樣式(消耗性蹦)的行為,比如字體顏色與背景相關(guān)屬性奋献,visibility等健霹,只影響外觀風(fēng)格不影響布局就是重繪

頻繁觸發(fā)重繪與回流,會導(dǎo)致ui頻繁渲染瓶蚂,最終阻塞js線程糖埋,導(dǎo)致js變慢,而這一方面的優(yōu)化窃这,更多是代碼習(xí)慣的優(yōu)化瞳别,大概講幾個通用的吧

  • 盡量減少會引起回流的操作,限制回流在一個圖層中(圖層, 可以類比ps的圖層祟敛,簡單說疤坝,就是脫離主文檔流,比如一個元素設(shè)置了z-index或者transform: translateZ(0)屬性它就是一個新的圖層馆铁,如果一個dom元素頻繁操作跑揉,應(yīng)該獨立成一個單獨的圖層,重繪回流操作就只限制在這一個圖層埠巨,不要設(shè)置過多圖層历谍,圖層合并計算是非常耗費資源的,所以只有當特別頻繁的操作辣垒,例如動畫望侈,gif圖才考慮獨立圖層出來)
  • css資源放在head里面(css link引入方式會阻塞頁面渲染,將css放在head里面勋桶,加載完成后再渲染脱衙,防止頁面閃動)
  • 使用translate替代top操作(top會觸發(fā)回流,但是translate不會)
  • 使用opacity替代visibility(只考慮可見性的話visibility會觸發(fā)重繪例驹,但opacity不會岂丘,要考慮需求差異,opacity和visibility對點擊事件的結(jié)果不一樣)
  • 不要一條條改變dom樣式眠饮,而是封裝成預(yù)先定義的className整體替換(每次修改都會觸發(fā)回流或重繪奥帘,整體替換只有一次)
  • 復(fù)雜的操作先將dom結(jié)構(gòu)display:none 然后操作后顯示(先把dom設(shè)置none,然后修改幾十次后顯示仪召,也只觸發(fā)2次回流)
  • 除非確實需要真實值寨蹋,不然不要在循環(huán)中去獲取dom的offsetHeight offsetWidth等屬性,而是循環(huán)前就獲取儲存到變量中(因為這些屬性的每一次讀取都會觸發(fā)一次回流)
  • 避免使用table布局(如果是div布局扔茅,修改dom已旧,回流只會在這個dom后面的所有元素發(fā)生,但是table布局即使修改了最后一行一列也會導(dǎo)致整個table的重新布局)
  • 使用GPU硬件加速(當一個元素設(shè)置css屬性transform: translateZ(0)或translate3d(0召娜,0运褪,0)的時候,游覽器就默認啟動)
  • 動畫效果使用requestAnimationFrame代替setInterval操作(requestAnimationFrame會把每一幀中的所有DOM操作集中起來玖瘸,在一次重繪或回流中就完成秸讹,并且重繪或回流的時間間隔緊隨刷新頻率,不因間隔時間過短造成過度繪制雅倒,也不會太長導(dǎo)致不流暢璃诀,且游覽器有特別優(yōu)化,更節(jié)省系統(tǒng)資源蔑匣,提高性能)

其他優(yōu)化

Web Worker: 本質(zhì)就是可以創(chuàng)建一個新的線程劣欢,把非常耗費性能的操作放在worker線程里運行棕诵,不堵塞主線程,要考慮兼容問題

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末凿将,一起剝皮案震驚了整個濱河市校套,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌牧抵,老刑警劉巖笛匙,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異灭忠,居然都是意外死亡膳算,警方通過查閱死者的電腦和手機座硕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進店門弛作,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人华匾,你說我怎么就攤上這事映琳。” “怎么了蜘拉?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵萨西,是天一觀的道長。 經(jīng)常有香客問我旭旭,道長谎脯,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任持寄,我火速辦了婚禮源梭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘稍味。我一直安慰自己废麻,他們只是感情好,可當我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布模庐。 她就那樣靜靜地躺著烛愧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪掂碱。 梳的紋絲不亂的頭發(fā)上怜姿,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天,我揣著相機與錄音疼燥,去河邊找鬼社牲。 笑死,一個胖子當著我的面吹牛悴了,可吹牛的內(nèi)容都是我干的搏恤。 我是一名探鬼主播违寿,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼熟空!你這毒婦竟也來了藤巢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤息罗,失蹤者是張志新(化名)和其女友劉穎掂咒,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體迈喉,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡绍刮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了挨摸。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片孩革。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖得运,靈堂內(nèi)的尸體忽然破棺而出膝蜈,到底是詐尸還是另有隱情,我是刑警寧澤熔掺,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布饱搏,位于F島的核電站,受9級特大地震影響置逻,放射性物質(zhì)發(fā)生泄漏推沸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一券坞、第九天 我趴在偏房一處隱蔽的房頂上張望鬓催。 院中可真熱鬧,春花似錦报慕、人聲如沸深浮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽飞苇。三九已至,卻和暖如春蜗顽,著一層夾襖步出監(jiān)牢的瞬間布卡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工雇盖, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留忿等,地道東北人。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓崔挖,卻偏偏與公主長得像贸街,于是被迫代替她去往敵國和親庵寞。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,728評論 2 351

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