前言
其實沒想過寫前端優化這篇文章來的,因為我自知現在水平達不到這個高度!
但是,你知道面試官很煩的,他每次面試非要問你瀏覽器兼容與前端優化......,所以我又不得不在這兩個上面做一定研究。
上面幾個問題,沒一定功力的前端不可能答得好的。對於優化這塊東西,我也很多正在摸索,實在覺得現在拿不出手啊!但是時間不等人。
比如這段時間參加的一個面試,面試官就非要將我做的頁面想象得很卡,而且指定就是前端卡,讓我優化,還問我平時會不會注意一些優化的東西。
說實話,平時寫代碼時候,我驚奇的發現一個事實:
1 我會不自主的將css寫成一排:
#tabs { border-bottom: 1px solid #1C87D5; padding: 5px 5px 0; }
2 我寫js時,兩個等號一定要空格:
var con = document.getElementById('content'); //不用編輯器我寫出來的代碼排版也不會差
3 在寫頁面時候我會花10分鍾糾結我這里是不是多了一個div
......
通過以上事實,我覺得我已經養成一種規范的“強迫症了”,這里不是要說自己編碼多好,而是想說明:
很多優化在平時在意或者不在意之間就已經做了,到后面你就不自主認為他不是優化而是必須了,比如:
for(var i = 0, len = args.length; i < len; i++) {}
但是,我能做的也就是以上的水准罷了,要在往下深入便真的需要具體的項目歷練了,所以一旦真正要說到優化,我強烈感覺自己不夠格!
不夠格不是不研究的理由,不夠格我們可以看夠格的文章,所以小弟今日就來學習一番,此篇文章參考了以下資料:
於是讓我們開始吧!!!在這里我提出一個優化總綱:零流量,無請求!
基本的優化
1 css放在頂部 有時候我們還會將他直接放到頁面里面,原因是防止頁面裸奔 2 js文件外部引用,放到尾部 script標簽沒出現一次便會讓頁面等待期解釋執行(這樣是有道理的),js邏輯結束后才能繼續渲染頁面
3 語義化標簽
該優化我都差點忽略了,做這個時候還需要注意seo
4 減少請求文件體積:圖片合並/外部文件壓縮
5 緩存ajax請求
6 注意控制cookie大小和污染
因為cookie是本地文件,每次瀏覽器都會去讀取響應的cookie
7 萬萬不要使用css表達式
......
現在我們來補充點重要知識:瀏覽器的重繪與重排
瀏覽器的重繪與重排
在前端交互中,很多特效會引起瀏覽器的重繪(redraw)和重排(reflow),需要付出高昂的性能代價(對於不熟悉的我,會有怎樣的弊端小的還不得而知呢)。
瀏覽器從下載文檔到顯示頁面的過程便包含了重繪和重排,通常在文檔初步加載時,瀏覽器引擎將會解析html文檔來構建DOM樹,之后根據DOM元素的幾何屬性構建一棵用於渲染的樹。
渲染樹的每個節點都有大小和邊距等屬性,類似於盒模型(由於隱藏元素不需要顯示,渲染樹中並不包含DOM樹中的隱藏元素)。
當渲染樹構建完畢后,瀏覽器就可以將元素放置到正確的位置了,再根據渲染樹節點的樣式屬性繪制出頁面。
由於瀏覽器的流式布局,對渲染樹的計算通常只需要遍歷一次,但table元素需要花上三倍的時間來確定其在渲染樹中節點的屬性,這也是為什么我們要避免使用table布局的一個原因。
重繪是一個元素外觀的改變所觸發的瀏覽器行為,例如改變visibility、outline、背景色等屬性,
瀏覽器會根據元素新屬性重新繪制,使元素呈現新的外觀,重繪不會帶來重新布局,不一定引發重排
重排是比較明顯的一種改變,可以理解為渲染樹需要重新計算,以下常見操作會觸發重排: 1 dom元素的集合屬性變化;當dom元素的幾何屬性變化時,渲染樹中的相關節點就會失效,瀏覽器會根據dom元素的變化重新構建渲染樹中失效的節點。
之后會根據新的渲染樹重新繪制這部分頁面,而且一個元素的重排可能引起連鎖反應,如:
容器節點渲染樹發送變化時,會導致子節點重新計算,也會觸發后續兄弟節點重排,最后每個元素都要重排,性能代價很高。
2 dom樹的結構變化;當dom樹結構發送變化時(節點增加移動),會觸發重排,
瀏覽器引擎布局過程類似於樹結構的前序遍歷,當前元素不會影響前面已經遍歷過的元素。
所以在在body最后插入元素對頁面影響很小,以后少往前面插入元素了。
3 js獲取某些屬性時也會引起重排;每獲取一次便會重排一次,所以獲取以下屬性后最好緩存:
offset相關屬性;scroll相關屬性、client相關屬性。
另外瀏覽器大小改變、元素樣式改變也會引起重排
1 對元素樣式的多次改變可以變為一次:比如幾次操作style屬性的話,就可以給他賦予一個css
2 將需要多次重排的元素設為絕對定位(position或者fixed),元素脫離文檔流便不會影響其他元素
3 由於display: none的元素不在渲染樹中,對隱藏元素的操作不會引發其他元素的重排,若是要對一個元素進行復雜操作可以先隱藏之,操作結束后在顯示。
4 在在內存中多次操作節點,完成后再添加到文檔,例如獲取后台數據后,可以先在內存構造完整的html片段,再一次加到文檔中去,切記一行行添加
5 使用會引起緩存的屬性時,緩存之!
6 為包含圖片的元素設定固定高度,以免圖片加載結束引起頁面下沉而整個重排!任何可能導致頁面抖動、位移的因素都應該扼殺,比如頁面比較長的話,一開始就讓滾動條出現吧,你會發現頁面抖動過多你筆記本的風扇會很興奮的!
7 對於首屏不加載的內容可以使用異步加載方式存儲html字符串,按需加載,降低首頁渲染時間。
寫到這里,我突然發現我曾經十分的戳。。。。很多沒注意
靜態資源
1 我們的頁面會出現許多小圖標,但很多小圖標完全可以用css實現,比如三角形,在css3規模化使用后,更加應該利用他減少外部圖片的引用。
2 資源復用,比如我們一個圖片按鈕就應該用於各種尺寸。
3 避免404錯誤
js/html相關
1 ajax數據緩存,情況允許使用本地存儲
2 圖片/廣告位使用滾動顯示加載(原因不明)
3 下拉菜單/彈出層中的隱藏內容可以使用<textarea>隱藏,需要才真正顯示(這招高)
4 無關緊要數據延遲加載(iframe)
5 事件延遲加載,比如鼠標移到某個文字上需要加載數據並且顯示,但是鼠標可能無意義移上去,這種情況下便應該取消事件(又如鼠標按下1秒才可拖動層)
6 避免dom操作,減少事件綁定,減少請求數,遍歷數據而非遍歷dom
7 若是一個層可拖動的話,不要鼠標每移動1px就改變元素位置,而是其累計5px以上才移動
8 js模塊化,若是引起閉包的話,要有意識的清理沒用的變量
總結
優化這個命題對我來說還是太大了,我們應該在工作過程中有意識的注意身邊的每一個有意思有創意的功能點,看看自己會如何實現的,
我相信長此以往,我有一天也可以對前端優化侃侃而談,變成真正的高手。
針對前端若是您有好的建議,請一定提出來哦!