前端性能優(yōu)化
前端性能優(yōu)化是指用戶從開(kāi)始訪問(wèn)網(wǎng)站開(kāi)始到整個(gè)頁(yè)面完整的展示出來(lái)的過(guò)程中,我們可以通過(guò)各種的優(yōu)化策略和優(yōu)化方法來(lái)加快頁(yè)面的加載,讓用戶的操作響應(yīng)更加及時(shí),從而增強(qiáng)系統(tǒng)的用戶使用感。
1.圖片資源加載
圖片格式
jpeg:一種針對(duì)彩色照片而廣泛使用的有損壓縮圖片格式,是一種柵格圖形,常用文件擴(kuò)展名包括jpg,jpeg,jpe。在互聯(lián)網(wǎng)中常被應(yīng)用于存儲(chǔ)和傳輸圖片。該格式不適合圖形和文字,圖標(biāo)圖形,因?yàn)樗膲嚎s算法不支持這種類(lèi)型的圖形,并且不支持透明度。常用于色彩豐富的照片,彩色圖,大焦點(diǎn)圖以及banner等結(jié)構(gòu)不規(guī)則的圖形。
png:便捷式網(wǎng)絡(luò)圖片,是一種無(wú)損壓縮的位圖圖片格式,支持索引,灰度,RGB三種顏色,以及Alpha通道等特性。適合于純色,透明,線條繪圖,圖標(biāo)以及顏色較少的需要半透明的圖。
gif:位圖圖形文件格式,8位色重現(xiàn)真色彩的圖像,采用LZW壓縮算法進(jìn)行編碼。支持256色,僅支持全透明和半透明,可以支持動(dòng)圖,不過(guò)每個(gè)像素只有8bit,不適合存儲(chǔ)彩色圖片。常用于動(dòng)畫(huà)個(gè)圖標(biāo)。
webp:是一種現(xiàn)代圖像格式,可以提供無(wú)損和有損壓縮,支持透明度。采用8位壓縮算法,無(wú)損壓縮比png小26%,有損壓縮比jpeg小25-34%,比gif有更好的動(dòng)畫(huà),常用于圖形和半透明圖像。
圖片優(yōu)化?
使用壓縮工具進(jìn)行圖片壓縮。
延遲加載圖片
在真實(shí)的圖片加載出來(lái)之前,可以使用一張公共的圖片,把頁(yè)面的整個(gè)布局撐起來(lái),然后再換成真實(shí)的圖片。 lqip工具可以把圖片進(jìn)行虛化,轉(zhuǎn)化成很小的base64編碼。
2. HTML優(yōu)化
精簡(jiǎn)HTML代碼?減少嵌套也就是層級(jí)關(guān)系,也可以減少DOM節(jié)點(diǎn)數(shù),讓瀏覽器渲染的DOM節(jié)點(diǎn)數(shù)最少。
減少一些無(wú)語(yǔ)義的代碼,比如空標(biāo)簽清除浮動(dòng)。
建議連接中刪除http或者h(yuǎn)ttps,因?yàn)橐话沔溄拥膮f(xié)議頭和頁(yè)面的協(xié)議頭都是一致的,所以可以省略。
可以刪除多余的空格,換行符,縮進(jìn)和不必要的注釋?zhuān)话銜?huì)用壓縮工具來(lái)進(jìn)行處理。
文件位置
css文件鏈接盡量放在頁(yè)面頭部,css加載不會(huì)阻塞DOM Tree解析,但是會(huì)阻塞DOM Tree的渲染,也會(huì)阻塞后面js的執(zhí)行,所以在DOM Tree在渲染之前解析css,可以減少瀏覽器重排的次數(shù) ,而且css放在底部會(huì)導(dǎo)致頁(yè)面白屏的時(shí)間變長(zhǎng)。
js文件一般放在頁(yè)面的底部,這是為了防止js的加載和解析阻塞頁(yè)面元素的正常渲染。
3.用戶體驗(yàn)
設(shè)置favicon.icon,如何不設(shè)置控制臺(tái)會(huì)報(bào)錯(cuò) ,而且用戶訪問(wèn)的時(shí)候地址欄是空的,不利于品牌記憶。
增加首屏必要的css和js。一般頁(yè)面需要在等待所有的依賴(lài)加載完成之后才會(huì)展示,這樣就會(huì)導(dǎo)致頁(yè)面存在空白,可以增加背景圖或者loading或者骨架屏。增強(qiáng)用戶的體驗(yàn)。
4.css優(yōu)化細(xì)則
提升css渲染性能
謹(jǐn)慎使用一些expensive的屬性,比如nth-child偽類(lèi)或者position:fixed定位,因?yàn)檫@些比較消耗瀏覽器的渲染性能。
盡量減少一些樣式層級(jí)的級(jí)數(shù),比如div ul li span i{color:red},可以直接給i標(biāo)簽設(shè)置class,直接書(shū)寫(xiě)樣式。
避免使用占過(guò)多cpu和內(nèi)存的屬性,比如text-indent不要設(shè)置太大的值。
盡量避免使用耗電量大的屬性,比較占用cpu,比如transform,opacity,transitions。
合適的使用css選擇器,盡量避免使用通配符,避免使用css表達(dá)式?例如color:expression((new Date()).getHours() % 2 ? "#fff" : "#000")
避免類(lèi)正則的屬性選擇器,*=,|=,^=,$=,使用外鏈的css,可以單獨(dú)形成文件放在cdn,使用緩存形式加載,避免使用import,因?yàn)樗募虞d會(huì)阻塞進(jìn)程,需要加載完畢后才會(huì)向下執(zhí)行。
精簡(jiǎn)css代碼,使用縮進(jìn)的語(yǔ)法,比如margin-top可以整合統(tǒng)一寫(xiě)在margin中,比如如何值為0能刪除就刪除,刪除不必要的單位值,刪除過(guò)多的分號(hào),刪除空格和注釋?zhuān)M量減少樣式表的體積。對(duì)于這些刪除也可以直接使用壓縮工具來(lái)完成。
合理使用web fonts
可以將字體部署到cdn上,從而加快加載速度,也可以直接將字體以base64未的形式保存在css中,并且通過(guò)localStorage進(jìn)行緩存。一些谷歌地址可以使用國(guó)內(nèi)的托管服務(wù),不要直接使用源地址。
css動(dòng)畫(huà)優(yōu)化
避免同時(shí)使用動(dòng)畫(huà),動(dòng)畫(huà)太多會(huì)干擾用戶的正常瀏覽,也會(huì)影響瀏覽器的性能。
5.js優(yōu)化
提升js文件的加載性能
css放在head標(biāo)簽,js放在body結(jié)尾。
變量和函數(shù)
盡量使用id選擇器,因?yàn)閕d選擇器查詢效率快。
避免使用eval,這個(gè)方法比價(jià)消耗性能。
js函數(shù)盡可能保持簡(jiǎn)潔,不要把過(guò)多的內(nèi)容寫(xiě)在一個(gè)函數(shù)中。
js動(dòng)畫(huà)
盡量避免使用大量的js動(dòng)畫(huà),css3動(dòng)畫(huà)和canvas動(dòng)畫(huà)比js動(dòng)畫(huà)性能要好。
使用requestAnimationFrame來(lái)代替setTimeout和setIntervval,因?yàn)閞equestAnimationFrame可以在正確的時(shí)間進(jìn)行渲染,setTimeout和setInterval無(wú)法保證渲染時(shí)機(jī),不要在定時(shí)器里面綁定事件。
使用邏輯緩存
6.減少頁(yè)面的回流和重繪
css
避免過(guò)多的樣式嵌套,最好可以快速進(jìn)行元素的定位。
避免使用css表達(dá)式,css表達(dá)式在css繪制的過(guò)程中都會(huì)執(zhí)行,會(huì)增加重排和回流的次數(shù)。
可以使用絕對(duì)定位讓動(dòng)畫(huà)元素脫離文檔流。
js
為了減少回流發(fā)生次數(shù),避免頻繁的操作DOM,可以合并多次對(duì)DOM統(tǒng)一修改,一次性批量處理。
控制繪制過(guò)程和繪制區(qū)域,繪制過(guò)程開(kāi)銷(xiāo)比較大的屬性設(shè)置應(yīng)該避免。
7. 簡(jiǎn)化DOM操作
對(duì)DOM的操作最好統(tǒng)一處理之后再統(tǒng)一插入到DOM Tree中。
8. 靜態(tài)文件壓縮工具
可以使用壓縮工具對(duì)html,css,js文件進(jìn)行壓縮。
9.瀏覽器渲染過(guò)程
首先瀏覽器會(huì)進(jìn)行一系列的解析,生成DOM Tree和Css Tree,最后合并成Render Tree。
根據(jù)生成的渲染樹(shù)進(jìn)行回流,以計(jì)算每個(gè)節(jié)點(diǎn)的幾何信息,報(bào)錯(cuò)位置,大小,樣式等,然后根據(jù)渲染樹(shù)和回流得到的幾何信息,得到每個(gè)節(jié)點(diǎn)上的結(jié)對(duì)像素。
最后進(jìn)行頁(yè)面展示。
10.懶加載,預(yù)加載,預(yù)渲染
懶加載指長(zhǎng)頁(yè)面中延遲加載特定的元素,從而減少當(dāng)前屏無(wú)效資源的加載。
預(yù)加載是讓瀏覽器預(yù)先加載某些資源。
預(yù)渲染是進(jìn)行資源的提前渲染。
11.接口服務(wù)調(diào)用優(yōu)化
接口合并,指一個(gè)頁(yè)面的眾多業(yè)務(wù)接口和依賴(lài)的第三方接口統(tǒng)一使用一個(gè)部署在集群的接口統(tǒng)一調(diào)用,以減少頁(yè)面接口請(qǐng)求數(shù)。
接口放在cdn,主要是基于性能考慮,可以把不需要實(shí)時(shí)更新的接口同步到cdn,接口內(nèi)容變更自動(dòng)同步cdn。