? ?本文將分享一些前端性能優(yōu)化的常用手段,包括減少請(qǐng)求次數(shù)、減小資源大小、各種緩存、預(yù)處理和長(zhǎng)連接機(jī)制,以及代碼方面的性能優(yōu)化等方面。
? ?base64:尤其是在移動(dòng)端,小圖標(biāo)可以base64(webpack),大圖片慎用(如果加載速度過(guò)于慢的,而且很重要的圖片,可以用base64)
1、減少HTTP的請(qǐng)求次數(shù)和傳輸報(bào)文的大小
CSS Sprite(雪碧圖、圖片精靈)技術(shù)
? 使用字體圖標(biāo)(Icon Font)或者SVG等矢量圖
? +減少HTTP請(qǐng)求次數(shù)或者減少請(qǐng)求內(nèi)容的大小
? +渲染更快:因?yàn)樗鼈兪腔诖a渲染的,而對(duì)于位圖(png/jpg/gif)是需要先把圖片編碼在渲染
? +不容易是幀變形
? +也可以使用webp格式圖片,這種格式要小一些(但是需要服務(wù)器端支持這種格式的請(qǐng)求處理)
圖片懶加載(延遲加載)技術(shù)?
? +第一次加載頁(yè)面的時(shí)候不去請(qǐng)求真實(shí)的圖片,提高第一次渲染頁(yè)面的速度,請(qǐng)求圖片的額外消耗盡可能不要處理
? +當(dāng)頁(yè)面加載完,把出現(xiàn)在用戶(hù)視野區(qū)域中的圖片做真實(shí)加載,沒(méi)有出現(xiàn)的先不加載(節(jié)約流浪,也能減少對(duì)服務(wù)器的請(qǐng)求壓力)
? + 對(duì)于數(shù)據(jù)我們也盡可能分批加載(不要一次請(qǐng)求過(guò)多的數(shù)據(jù),例如分頁(yè)技術(shù))
? 音視頻文件取消預(yù)加載(preload='none'),這樣可以增加第一次渲染頁(yè)面的速度,當(dāng)需要播放的時(shí)候在加載
? 客戶(hù)端和服務(wù)器端的數(shù)據(jù)傳輸盡可能基于JSON格式完成,XML格式比JSON格式要大一些(還可以基于二進(jìn)制編碼或者文件流格式,這種格式比文件傳輸好很多)
把頁(yè)面的css/js等文件進(jìn)行合并壓縮
? 合并:爭(zhēng)取css和js都只導(dǎo)入一個(gè)(webpack可以實(shí)現(xiàn)并合并壓縮哦)
? 壓縮:基于webpack可以壓縮,對(duì)于圖片自己找工具先壓縮,可以使用服務(wù)器的GZIP壓縮
? 圖片BASE64(用BASE64碼代表圖片,減少HTTP,增加瀏覽器渲染速度,所以真是項(xiàng)目中,尤其是移動(dòng)端,如果圖片加載緩慢,BASE64一下就好了,;但是base64會(huì)導(dǎo)致文件中心的代碼超級(jí)惡心,不利于維護(hù)和開(kāi)發(fā),所以減少使用);webpack中科院配置圖片
2、設(shè)置各種緩存、預(yù)處理和長(zhǎng)連接機(jī)制
? 不經(jīng)常更改的靜態(tài)資源做緩存處理(一般做的是304或者ETAG等協(xié)商緩存)
建立Cache-Control 和Expires HTTP的強(qiáng)緩存
? DNS緩存或者預(yù)處理(DNS Prefetch),減少DNS的查找
? 設(shè)置本地的離線存儲(chǔ)(manifest)或者把一些不經(jīng)常更改的數(shù)據(jù)做本地臨時(shí)存儲(chǔ)(webstorage,indexdb)等
? 有錢(qián)就做CDN(地域分布式服務(wù)器),或者加服務(wù)器
建立Connection:keep-alive Tcp長(zhǎng)連接
? 使用HTTP2版本協(xié)議(現(xiàn)在用的一般都是http1.1),可以多條tcp通道共存=>管道化鏈接
? 一個(gè)項(xiàng)目分為不同的域(不同的服務(wù)器),例如:資源web服務(wù)器、數(shù)據(jù)服務(wù)器,圖片服務(wù)器,視頻服務(wù)器等,合理利用服務(wù)器資源,但是導(dǎo)致過(guò)多的DNS解析
? Cache-Control的優(yōu)先級(jí)高于Expires
? 基于本地存儲(chǔ),做數(shù)據(jù)的存儲(chǔ)
3、代碼方面的性能優(yōu)化
? ?減少對(duì)閉包的使用(因?yàn)檫^(guò)多使用閉包會(huì)產(chǎn)生很多不銷(xiāo)毀的內(nèi)存,處理不好的話(huà),會(huì)導(dǎo)致內(nèi)存溢出“棧溢出”),減少閉包的嵌套(減少作用域鏈的查找層級(jí))
? 對(duì)于動(dòng)畫(huà)來(lái)說(shuō):能用css解決的不用js(能夠用transform處理的,不用傳統(tǒng)的css樣式,因?yàn)閠ransform開(kāi)啟硬件加速,不會(huì)引發(fā)回流,或者使用定位的元素也會(huì)好很多,因?yàn)槎ㄎ坏脑孛撾x文檔流,不會(huì)對(duì)其他元素的位置造成影響),能用 requestAnimationFrame解決的不用定時(shí)器
? +用requestAnimationFrame還有一個(gè)好處,當(dāng)頁(yè)面處于休眠無(wú)訪問(wèn)狀態(tài),動(dòng)畫(huà)會(huì)自己暫停,知道回復(fù)訪問(wèn)才開(kāi)始,而定時(shí)器是不論什么狀態(tài),只要頁(yè)面不管,就一直處理
? 避免使用iframe(因?yàn)閕frame會(huì)嵌入其他頁(yè)面,這樣父頁(yè)面渲染的時(shí)候,還要同時(shí)把子頁(yè)面也渲染了,渲染進(jìn)度會(huì)變慢)
? 減少直接對(duì)DOM的操作(原因是減少DOM的回流和重繪...),當(dāng)代項(xiàng)目基本基于mvvm,mvc數(shù)據(jù)驅(qū)動(dòng)視圖渲染的,對(duì)DOM的操作框架本身完成,性能要好很多
? 低耦合高內(nèi)聚(基于封裝的方式:方法封裝,插件,組件,框架,類(lèi)庫(kù)等封裝,減少頁(yè)面中的冗余代碼,提高代碼使用率)
? 盡可能使用事件委托
? 避免出現(xiàn)死循環(huán)或者嵌套循環(huán)(嵌套循環(huán)會(huì)成倍增加循環(huán)的次數(shù))
? 項(xiàng)目中盡可能使用異步編程來(lái)模擬出多線程的效果,避免主線程阻塞(異步操作基于Promise設(shè)計(jì)模式來(lái)管理)
? JS中不要使用with
? 避免使用css表達(dá)式
? 函數(shù)的防抖和節(jié)流
? 減少使用eval(主要原因是防止壓縮代碼的時(shí)候,由于符號(hào)書(shū)寫(xiě)不合規(guī),導(dǎo)致代碼混亂)
? 圖片地圖:對(duì)于多次調(diào)取使用的圖片(尤其是背景圖),盡可能把它提取成為公共的樣式,而不是每一次重新設(shè)置background
? 減少filter濾鏡的使用
? 盡可能減少選擇器的層級(jí)
? 盡可能減少table布局
? 手動(dòng)回收堆棧內(nèi)存(賦值為null)
棧溢出:死遞歸
function func(){
? ? ? ? ?func();
}
func();
解決方案:
function func(){
? ? ? ? ? setTimeout(func,0);
}
func();
? 相互引用:引用類(lèi)型之間的相互調(diào)用,形成嵌套式內(nèi)存
let? ?obj1={
? ? ? ?name:'obj1',
};
let? ?obj2={
? ? ? ?name:'obj2',
? ? ? ?x:obj1
}
obj1.x=obj2;
想持續(xù)了解更多,不妨點(diǎn)贊和關(guān)注唄。
Web前端技術(shù)交流q群:1137068794,
群里可以一起學(xué)習(xí)編程,進(jìn)群能領(lǐng)到學(xué)習(xí)資料以及源代碼