前端的性能優(yōu)化是一個(gè)很寬泛的概念,最終目的都是為了提升用戶體驗(yàn),改善頁(yè)面性能。面試的時(shí)候經(jīng)常會(huì)遇到問(wèn)談?wù)勑阅軆?yōu)化的手段,這個(gè)我分幾大部分來(lái)概述,具體細(xì)節(jié)需要自己再針對(duì)性的去搜索,只是提供一個(gè)索引(太多了寫(xiě)不過(guò)來(lái)+主要是懶得寫(xiě))。這里PC端和移動(dòng)端分開(kāi)說(shuō)了,業(yè)務(wù)場(chǎng)景不同,需要考慮各自的優(yōu)化手段
目前來(lái)看,前端優(yōu)化的策略有很多,主要包括網(wǎng)絡(luò)加載,頁(yè)面渲染,CSS優(yōu)化,JS執(zhí)行優(yōu)化,緩存,圖片,協(xié)議幾大類。這一篇先講PC端的優(yōu)化策略
網(wǎng)絡(luò)加載
1. 減少HTTP請(qǐng)求次數(shù)
建議盡可能的根據(jù)需要去合并靜態(tài)資源圖片、JavaScript代碼和CSS文件,減少頁(yè)面請(qǐng)求數(shù),這樣可以縮短頁(yè)面首次訪問(wèn)的等待時(shí)間,另外也要盡量的避免重復(fù)資源,防止增加多余的請(qǐng)求
2. 減少HTTP請(qǐng)求大小
除了減少請(qǐng)求資源數(shù),也要減少每個(gè)http請(qǐng)求的大小。比如減少?zèng)]必要的圖片,JS,CSS以及HTML等,對(duì)文件進(jìn)行壓縮優(yōu)化,開(kāi)啟GZIP壓縮傳輸內(nèi)容,縮短網(wǎng)絡(luò)傳輸?shù)却舆t
3. 將CSS和JS放到外部文件中,避免使用style和script標(biāo)簽引入
在HTML文件中引入外部的資源可以有效利用瀏覽器的靜態(tài)資源緩存。有時(shí)候在移動(dòng)端對(duì)請(qǐng)求數(shù)比較在意的會(huì)為了減少請(qǐng)求把CSS和JS文件直接寫(xiě)到HTML里邊,具體根據(jù)CSS和JS文件大小和業(yè)務(wù)場(chǎng)景來(lái)分析。如果CSS和JS文件內(nèi)容較多,邏輯比較復(fù)雜,建議放到外部引入
<link rel="stylesheet">
<script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
4. 避免頁(yè)面中空的href和src
當(dāng)link標(biāo)簽的href屬性為空,或者script、img、iframe標(biāo)簽的src屬性為空的時(shí)候,瀏覽器在渲染的過(guò)程中還是會(huì)把href和src的空內(nèi)容進(jìn)行加載,直到加載失敗。這樣就阻塞了頁(yè)面中其他資源的下載進(jìn)程,并且最后加載的內(nèi)容是無(wú)效的,因此要盡量避免。
<!-- 不推薦 -->
<img src="" alt="占位圖"/>
5. 為HTML指定Cache-Control或者Expires
為HTML指定Cache-Control或者Expires可以將HTML內(nèi)容緩存起來(lái),避免頻繁向服務(wù)器發(fā)送請(qǐng)求。在頁(yè)面Cache-Control或Expires頭部又消失,瀏覽器會(huì)直接從緩存讀取內(nèi)容,不向服務(wù)器發(fā)送請(qǐng)求
<meta http-equiv="Cache-Control" content="max-age=7200" />
<meta http-equiv="expires" content="Wed, 20 Jun 2017 22:33:00 GMT">
6. 合理設(shè)置Etag和Last-Modified
對(duì)于未修改的文件,靜態(tài)資源服務(wù)器會(huì)向?yàn)g覽器端返回304,讓瀏覽器從緩存中讀取文件,減少下載的帶寬消耗并能減少服務(wù)器的負(fù)載
<meta http-equiv="last-modified" content="Mon, 03 Jan 2017 17:45:57 GMT">
7. 減少頁(yè)面重定向
一次重定向大概600毫秒的時(shí)間開(kāi)銷,為了保證用戶能盡快看到頁(yè)面內(nèi)容,盡量避免頁(yè)面的重定向
8. 靜態(tài)資源不同域名存放
瀏覽器在同一時(shí)刻向同一個(gè)域名請(qǐng)求文件的并行下載數(shù)是有限的,因此可以理由多個(gè)域名的主機(jī)來(lái)存放不同的靜態(tài)資源,增大頁(yè)面加載時(shí)資源的并行下載數(shù)。
9. 使用靜態(tài)資源CDN來(lái)存儲(chǔ)文件
詳情搜索CDN空間
10. 使用CDN Combo下載傳輸內(nèi)容
CDN的combo技術(shù)能把多個(gè)資源文件合并引用,減少請(qǐng)求次數(shù)。這樣可以減少瀏覽器HTTP請(qǐng)求數(shù),加快資源下載速度。比如淘寶的寫(xiě)法:
<link rel="stylesheet" >
<script type='text/javascript' src='//g.alicdn.com/msui/sm/0.6.2/js/??sm.min.js,sm-extend.min.js' charset='utf-8'></script>
參考: http://www.cnblogs.com/zhengyun_ustc/archive/2012/07/18/combo.html
11. 使用可緩存的AJAX
對(duì)于內(nèi)容相同的請(qǐng)求,有時(shí)候沒(méi)必要每次都從服務(wù)器拉取,合理的使用ajax緩存能加快ajax響應(yīng)速度并減少服務(wù)器的壓力
$.ajax({
url : url,
dataType : "json",
cache: true,
success: function(data){ // to do something... }
});
12. 使用get請(qǐng)求
POST請(qǐng)求會(huì)首先發(fā)送文件頭,然后發(fā)送HTTP正文的數(shù)據(jù)。而使用GET只發(fā)送頭部,所以在拉取數(shù)據(jù)時(shí)使用GET請(qǐng)求效率更高
13. 減少Cookie的大小并進(jìn)行Cookie隔離
HTTP請(qǐng)求默認(rèn)是會(huì)帶上瀏覽器端的Cookie一起發(fā)送給服務(wù)器端的,所以在非必要的情況下要盡量減少Cookie。對(duì)于靜態(tài)的資源,盡量使用不同的域名存放,因?yàn)镃ookie默認(rèn)也是不能跨域的,這就做到了不同域名下靜態(tài)資源請(qǐng)求的Cookie隔離
14. 減少favicon.ico 并緩存
一般一個(gè)web應(yīng)用的favicon.ico是很少改變的,。有利于favicon.ico的重復(fù)加載
15. 異步的加載JavaScript資源
異步的JavaScript資源不會(huì)阻塞文檔解析,所以瀏覽器會(huì)優(yōu)先渲染頁(yè)面,延遲加載腳本執(zhí)行。
<script src="main.js" defer></script>
<script src="main.js" async></script>
16. 消除阻塞頁(yè)面的CSS和JS
對(duì)于頁(yè)面中加載時(shí)間過(guò)長(zhǎng)的CSS或JS文件,需要進(jìn)行合理的拆分或者延后加載,保證關(guān)鍵的資源能快速加載完成
17. 避免使用CSS import 引用加載CSS
18. 使用prefetch來(lái)完成網(wǎng)站預(yù)加載
讓瀏覽器預(yù)先加載用戶訪問(wèn)當(dāng)前頁(yè)后極有可能訪問(wèn)的其他資源(頁(yè)面,圖片,視頻等),從而讓用戶有更好的體驗(yàn)
19. 按需加載
這個(gè)跟第二條差不多,特別做單頁(yè)應(yīng)用的時(shí)候要注意(移動(dòng)端部分會(huì)著重說(shuō)明)
頁(yè)面渲染類
1. 把CSS資源引用放到HTML文件頂部
這樣瀏覽器可以優(yōu)先下載CSS并盡快完成頁(yè)面渲染
2. JavaScript文件引用放到HTML文件底部
可以防止JavaScript的加載和解析執(zhí)行對(duì)頁(yè)面渲染造成阻塞。由于JavaScript資源默認(rèn)是解析阻塞的,除非被標(biāo)記為異步或者通過(guò)其他的方式異步加載,否則會(huì)阻塞HTML DOM解析和CSS渲染過(guò)程
3. 不要在HTML中直接縮放圖片
在HTML中直接縮放圖片會(huì)導(dǎo)致頁(yè)面內(nèi)容的重排重繪,此時(shí)可能會(huì)使頁(yè)面中的其他操作產(chǎn)生卡頓,因此要盡量減少在頁(yè)面中直接進(jìn)行圖片縮放
4. 減少DOM元素?cái)?shù)量和深度
HTML中標(biāo)簽元素約的,標(biāo)簽的層級(jí)越深,瀏覽器解析DOM并繪制到瀏覽器中說(shuō)花的時(shí)間就越長(zhǎng)。
5. 盡量避免使用table、iframe等慢元素
<table>內(nèi)容的渲染是講table的DOM渲染樹(shù)全部生成完并一次性繪制到頁(yè)面上,所以在長(zhǎng)表格渲染時(shí)很耗性能,應(yīng)該盡量避免使用,可以考慮用ul代替。盡量使用異步的方式動(dòng)態(tài)的加載iframe,因?yàn)閕frame內(nèi)資源的下載進(jìn)程會(huì)阻塞父頁(yè)面靜態(tài)資源的下載以及HTML DOM的解析
6. 避免運(yùn)行耗時(shí)的JavaScript
長(zhǎng)時(shí)間運(yùn)行的JavaScript會(huì)阻塞瀏覽器構(gòu)建DOM樹(shù)、DOM渲染樹(shù)、渲染頁(yè)面。所以任何與頁(yè)面初次渲染無(wú)關(guān)的邏輯功能都應(yīng)該延遲加載執(zhí)行,這和JavaScript資源的異步加載思路一致
7. 避免使用CSS表達(dá)式和CSS濾鏡
CSS表達(dá)式和濾鏡的解析渲染速度是很慢的,再有其他解決方案的情況下應(yīng)該盡量避免使用
// 不推薦
.opacity{
filter: progid:DXImageTransform.Microsoft.Blur(PixelRadius=10, MakeShadow=false)
}
至此,PC部分的性能優(yōu)化點(diǎn)介紹完了。有一些沒(méi)有講到的諸如DNS預(yù)解析,離線緩存,HTTP2協(xié)議,GPU加速等,想著移動(dòng)端的優(yōu)化更細(xì),這些內(nèi)容放到移動(dòng)端再講會(huì)好一點(diǎn)。因?yàn)镻C端由于兼容性的問(wèn)題,很多的優(yōu)化策略也不能很好的向下降級(jí)。盡管列舉了很多,但還有少部分遺漏的,歡迎大家補(bǔ)充。前端優(yōu)化不是一件簡(jiǎn)簡(jiǎn)單單的事情,其涉及的內(nèi)容很多,大家可以根據(jù)實(shí)際情況將這些方法應(yīng)用到自己的項(xiàng)目當(dāng)中去。
另外給自己的群打個(gè)小廣告
一個(gè)不怎么正經(jīng)的前端學(xué)習(xí)交流群: 523067423;
目前新手妹子較多,歡迎各位前端or非前端朋友們加入