前端性能優(yōu)化這一塊一直在項(xiàng)目中多多少少的在使用,但是知識(shí)點(diǎn)都太碎了富弦,加上面試的出現(xiàn)率炒雞高沟娱,所以來(lái)一波整理。
前端優(yōu)化的話主要分為頁(yè)面渲染腕柜,css優(yōu)化济似,js優(yōu)化,圖片盏缤,網(wǎng)絡(luò)請(qǐng)求幾類(lèi)砰蠢。 這篇就對(duì)除了網(wǎng)絡(luò)請(qǐng)求之外的優(yōu)化分析一波。
頁(yè)面渲染
1. 把CSS資源引用放在HTML文件頂部
這樣瀏覽器可以?xún)?yōu)先加載css唉铜,但是里面又可以細(xì)節(jié)的分化一下台舱,包括之前的mvc開(kāi)發(fā)經(jīng)常會(huì)吧所有的css放到一個(gè)模板里面直接加載,或者前端的書(shū)寫(xiě)習(xí)慣也喜歡link這邊直接復(fù)制粘貼一把梭潭流。都會(huì)導(dǎo)致一些無(wú)用資源優(yōu)先加載而導(dǎo)致頁(yè)面的渲染時(shí)間增長(zhǎng)竞惋。可以通過(guò)以下代碼的應(yīng)用實(shí)現(xiàn)css的異步加載幻枉,或者通過(guò)js的動(dòng)態(tài)添加link元素也是可以的碰声。
//兩種都可以實(shí)現(xiàn)
<link rel="stylesheet" href="css.css" media="none" onload="if(media!='all')media='all'">
<link rel="preload" href="global.min.css" as="style" onload="this.rel='stylesheet'">
//考慮兼容
<noscript><link rel="stylesheet" href="css.css"></noscript>
2. 把JavaScript文件引用放在HTML文件底部
因?yàn)閖avascript默認(rèn)是同步加載,會(huì)導(dǎo)致阻塞頁(yè)面渲染熬甫。也可以使用動(dòng)態(tài)添加或者使用HTML5新增的屬性胰挑, defer和anysc
//會(huì)在加載完畢之后就隨之執(zhí)行。
<scrtpt src='js.js' defer></script>
//加載完畢之后不會(huì)執(zhí)行椿肩,是在onload之前執(zhí)行
<scrtpt src='js.js' async></script>
3. 避免各種情況導(dǎo)致的重排(reflow)重繪(redraw)
頁(yè)面的重排重繪很消耗性能瞻颂,所以一定盡可能減少頁(yè)面的重排重繪。
重繪
當(dāng)盒子的位置郑象、大小以及其他屬性贡这,例如顏色、字體大小等都確定下來(lái)之后厂榛,瀏覽器便把這些原色都按照各自的特性繪制一遍盖矫,將內(nèi)容呈現(xiàn)在頁(yè)面上。
重繪是指一個(gè)元素外觀的改變所觸發(fā)的瀏覽器行為击奶,瀏覽器會(huì)根據(jù)元素的新屬性重新繪制辈双,使元素呈現(xiàn)新的外觀。
觸發(fā)重繪的條件:改變?cè)赝庥^屬性柜砾。如:color湃望,background-color等。
重排
當(dāng)渲染樹(shù)中的一部分(或全部)因?yàn)樵氐囊?guī)模尺寸,布局证芭,隱藏等改變而需要重新構(gòu)建, 這就稱(chēng)為回流(reflow)瞳浦。每個(gè)頁(yè)面至少需要一次回流,就是在頁(yè)面第一次加載的時(shí)候废士。
觸發(fā)重排的條件:任何頁(yè)面布局和幾何屬性的改變都會(huì)觸發(fā)重排叫潦,比如:
1、頁(yè)面渲染初始化官硝;(無(wú)法避免)
2诅挑、添加或刪除可見(jiàn)的DOM元素;
3泛源、元素位置的改變,或者使用動(dòng)畫(huà)忿危;
4达箍、元素尺寸的改變——大小,外邊距铺厨,邊框缎玫;
5、瀏覽器窗口尺寸的變化(resize事件發(fā)生時(shí)解滓;
6赃磨、填充內(nèi)容的改變,比如文本的改變或圖片大小改變而引起的計(jì)算值寬度和高度的改變洼裤;
7邻辉、讀取某些元素屬性:(offsetLeft/Top/Height/Width, clientTop/Left/Width/Height, scrollTop/Left/Width/Height, width/height, getComputedStyle(), currentStyle(IE))
重繪和重排的關(guān)系:在回流的時(shí)候,瀏覽器會(huì)使渲染樹(shù)中受到影響的部分失效腮鞍,并重新構(gòu)造這部分渲染樹(shù)值骇,完成回流后,瀏覽器會(huì)重新繪制受影響的部分到屏幕中移国,該過(guò)程稱(chēng)為重繪吱瘩。
所以,重排必定會(huì)引發(fā)重繪迹缀,但重繪不一定會(huì)引發(fā)重排使碾。
優(yōu)化點(diǎn)
1.瀏覽器自己的優(yōu)化:瀏覽器會(huì)自己維護(hù)一個(gè)隊(duì)列,把所有引起重排祝懂,重繪的操作放在這個(gè)隊(duì)列票摇,等隊(duì)列中的操作到了一定數(shù)量或者一定時(shí)間,就會(huì)進(jìn)行一個(gè)批處理嫂易。把多次的重繪重排變成一次重繪重排兄朋。
2.操作的優(yōu)化:
(1)直接修改元素的className
(2)先設(shè)置元素為display:none,然后對(duì)布局進(jìn)行操作。設(shè)置完之后再將元素設(shè)置為display:block颅和。
(3)將需要多次重排的元素傅事,position設(shè)置為absolute,元素脫離了文檔流峡扩,變化不會(huì)影響到其他元素蹭越。
(4)多個(gè)DOM節(jié)點(diǎn)創(chuàng)建,簡(jiǎn)化成一次創(chuàng)建教届。原生的話就是DocumentFragment响鹃,jq就是字符串多次拼接之后直接append()或者h(yuǎn)tml()。
4.減少DOM元素的數(shù)量和深度
HTML中標(biāo)簽元素越多案训,標(biāo)簽的層級(jí)越深买置,瀏覽器解析DOM并繪制到瀏覽器中花的時(shí)間就越長(zhǎng)
5.盡量避免使用table、iframe等慢元素
table及其內(nèi)部元素可能需要多次計(jì)算才能確定好其在渲染樹(shù)中節(jié)點(diǎn)的屬性值强霎,比同等元素要多花兩倍時(shí)間
iframe內(nèi)資源的下載進(jìn)程會(huì)阻塞父頁(yè)面靜態(tài)資源的下載以及HTML DOM的解析
6. 壓縮html
將HTML代碼壓縮忿项,將注釋、空格和新行從生產(chǎn)文件中刪除城舞。
將link和script中的type屬性刪除掉轩触,因?yàn)閔tml5把text/css、text/javascript作為默認(rèn)值家夺。
CSS優(yōu)化
1.壓縮和合并
使用gulp脱柱,或者webpack進(jìn)行壓縮,從生產(chǎn)文件中刪除注釋?zhuān)崭窈涂招欣觥:喜⒅罂梢詼p少http請(qǐng)求榨为。
2.className的長(zhǎng)度 和 深度
盡量去減少className的長(zhǎng)度和深度 可以提高加載速度。
JS優(yōu)化
1.壓縮
2.盡量的使用ID選擇器
選擇頁(yè)面DOM元素時(shí)盡量使用id選擇器煌茴,因?yàn)閕d選擇器速度最快
3.合理的緩存dom對(duì)象
對(duì)于要重復(fù)使用的dom對(duì)象柠逞,要優(yōu)先設(shè)置緩存變量,避免每次使用時(shí)都要從整個(gè)dom樹(shù)重新查找景馁。
4.頁(yè)面元素盡量使用事件代理板壮,避免事件直接綁定
使用事件代理可以避免對(duì)每個(gè)元素都進(jìn)行綁定,并且可以避免出現(xiàn)內(nèi)存泄漏以及需要?jiǎng)討B(tài)添加元素的事件綁定問(wèn)題
圖片優(yōu)化
1.壓縮
在壓縮后的圖片符合產(chǎn)品要求下將圖像進(jìn)行優(yōu)化合住。