前端需要性能優(yōu)化么?
性能優(yōu)化一直以來(lái)都是前端工程領(lǐng)域中的一個(gè)重要部分。很多資料表明,網(wǎng)站應用的性能優(yōu)化對于提高用戶(hù)留存、轉化率等都有積極影響??梢岳斫鉃?,提升你的網(wǎng)站性能,就是提升你的業(yè)務(wù)數據(甚至是業(yè)務(wù)收入)。
性能優(yōu)化廣義上包含前端優(yōu)化和后端優(yōu)化。后端優(yōu)化的關(guān)注點(diǎn)更多的時(shí)候是在增加資源利用率、降低資源成本以及提高穩定性上。相較于后端,前端的性能優(yōu)化會(huì )更直接與用戶(hù)的體驗掛鉤。從用戶(hù)體驗側來(lái)說(shuō),前端服務(wù) 5s 的加載時(shí)間優(yōu)化縮減 80%(1s) 與后端服務(wù) 50ms 的響應優(yōu)化縮減 80%(10ms) 相比,用戶(hù)的體驗提升會(huì )更大。因此很多時(shí)候,與體驗相關(guān)的性能的瓶頸會(huì )出現在前端。
我和一些同學(xué)接觸的過(guò)程中,發(fā)現作為前端工程師,大家其實(shí)都具備一定的性能優(yōu)化意識,同時(shí)也有自己的優(yōu)化“武器庫”,例如懶加載、資源合并、避免 reflow 等等。雖然大家對性能優(yōu)化都有自己的思路,不過(guò)大多是分散在某幾個(gè)點(diǎn),較難形成一個(gè)完整的體系。
一、html文檔結構標簽語(yǔ)義化
1、首先什么是語(yǔ)義化呢?
語(yǔ)義化是指用合理HTML標記以及其特有的屬性去格式化文檔內容。機器在需要更少的人類(lèi)干預的情況下能夠研究和收集信息,讓網(wǎng)頁(yè)能夠被機器理解,最終讓人類(lèi)受益。即用正確的標簽做正確的事。
2、語(yǔ)義化的好處或者說(shuō)存在的意義
① 有利于搜索引擎抓取
② 結構清晰的HTML在團隊合作中的作用:代碼可讀、便于維護、提高開(kāi)發(fā)效率、快速達成共識、利于二次開(kāi)發(fā)。
③ 有利于盲人屏幕閱讀器
二、css、js文件數量及大小
優(yōu)化一般對于css、js是建議使用外聯(lián)式來(lái)進(jìn)行導入。我們可以對css、js做相應的規劃也可以減少css、js的個(gè)數以減少http請求。同時(shí)也要注重減少重復代碼,注重代碼重復利用,以達到用最少的代碼干最多的事。同時(shí)當項目要投入上線(xiàn)使用的時(shí)候,可以對css、js文件進(jìn)行壓縮,文件的減小可以加速文件的鏈接導入,以便加速網(wǎng)頁(yè)的加載渲染。
可通過(guò)使用webpack,gulp等工具對Js文件進(jìn)行合并。
三、圖片的數量和大小
多個(gè)服務(wù)器請求會(huì )對站點(diǎn)的性能產(chǎn)生顯著(zhù)的影響。對一張圖片進(jìn)行導入又是一個(gè)http請求,因此我們應該減少圖片的導入數量以便減少http請求。此處,我們必須提到一個(gè)名詞“css精靈spirit”。css精靈是指包含多個(gè)不同的圖標、按鈕或圖形的單個(gè)圖像。因此我們可以把多張背景圖片合并為一張然后對背景圖片進(jìn)行相應的定位。同時(shí)使用PNG8格式的圖片相對于GIF來(lái)說(shuō)比較少。而對于內容圖片,可以對其進(jìn)行適當的壓縮,可以加快文檔內容加載,或者如果是需要用戶(hù)下載的圖片,小的圖片可以加快用戶(hù)下載的速度。
使用較為廣泛的web圖片格式有:JPEG/JPG、PNG、WEBP、Base64、SVG。
1.JPEG/JPG
特點(diǎn)是有損壓縮,體積小,加載快,不支持透明。
使用場(chǎng)景:JPG適合用于呈現熱菜豐富的圖片,在日常的開(kāi)發(fā)中,JPG圖片經(jīng)常作為大的背景圖、輪播圖或是Banner圖。比如兩大電商網(wǎng)站對大圖片的處理,就是對JPG圖片應用場(chǎng)景的最佳寫(xiě)照。用JPG來(lái)呈現大圖片,既可以保留圖片的質(zhì)量,又不會(huì )擔心圖片的體積,是一種比較廣泛使用的方案。
缺點(diǎn):在處理一些矢量圖形和logo等這些線(xiàn)條感很強、顏色對比強烈的圖片時(shí),認為壓縮就導致圖片模糊非常明顯。另外,JPG圖像不支持透明度處理,透明圖片只能用PNG來(lái)呈現了。
2.PNG-8和PNG-24
特點(diǎn)是無(wú)損壓縮、質(zhì)量高、體積大、支持透明
優(yōu)點(diǎn):無(wú)損壓縮的高保真圖片格式。8和24都是二進(jìn)制數的位數,8位的PNG支持256中顏色,24位的PNG可以支持1600萬(wàn)種顏色。在不考慮文件大小只在乎最佳的顯示效果時(shí),推薦使用PNG-24。但是在適合使用PNG時(shí)會(huì )優(yōu)先選擇PNG-8
應用場(chǎng)景:主要用PNG來(lái)呈現小的LOGO、顏色簡(jiǎn)單對比強烈的圖片或是背景。
3.SVG
特點(diǎn)是文本文件,體積小,不失真,兼容性好
優(yōu)點(diǎn):SVG是一種基于XML語(yǔ)法的圖像格式。SVG對圖像的處理不是基于像素,而是基于對圖像的形狀描述。
和JPG、PNG相比較,SVG文件體積更小,可壓縮性更強。SVG作為矢量圖最大的優(yōu)點(diǎn)在于圖片可以無(wú)限放大還不失真,一張SVG圖片可以適配多種分辨率。另外SVG是文本文件,可以像寫(xiě)代碼一樣定義SVG,放在HTML中稱(chēng)為DOM的一部分。也可以把對圖像的描述寫(xiě)入以.svg為后綴的文件中,在img標簽中引入即可。
4.WebP
優(yōu)點(diǎn):WebP是一款比JPG、PNG等在壓縮方面更加優(yōu)越的圖片格式,同時(shí)也不會(huì )影響其圖片質(zhì)量,使用該格式時(shí)最好將同名文件格式化,當檢測瀏覽器不兼容時(shí)自動(dòng)切換jpg格式
缺點(diǎn):是一個(gè)相對較新的技術(shù),所以對于目前市面上的瀏覽器能否完美的兼容,其可用和實(shí)用性就變得很現實(shí)了,再好的東西如果沒(méi)有好的兼容性,也是非常難以普及和被廣泛使用的
5.Base64
優(yōu)點(diǎn):減少請求,加快首屏數據顯示。對于jpg格式的圖片,每一個(gè)圖片相當于一次http請求,圖片多了的話(huà),服務(wù)器耗性能比較嚴重。而將jpg轉化成base64格式的圖片,則極大地減少了請求數,因為Base是文本格式。
缺點(diǎn):base64格式圖片比原圖大,占用更多存儲空間,同時(shí),瀏覽器不會(huì )對該資源緩存。
使用方法:background:url(data:image/png;base64,{img_data})
應用場(chǎng)景:一般對于小于10KB大小的圖片進(jìn)行base64轉碼。
至于動(dòng)態(tài)圖有GIF與APNG:后者APNG這東西是mozilla搞出來(lái)的, 它是24位的,而且也是動(dòng)圖,可以容納1680萬(wàn)種顏色,也是為了取代GIF,但是....也就火狐支持,IE10和chrome,safari全部不行, 如果說(shuō)gif圖片是卡片機的話(huà), APNG就是單反
四、有效性驗證
除了根據語(yǔ)義加標記之外,HTML文檔還需要用有效的代碼來(lái)編寫(xiě),如果代碼是無(wú)效的,瀏覽器會(huì )嘗試解釋標記本身,有時(shí)候會(huì )產(chǎn)生錯誤的結果。更糟的是,如果發(fā)送具有正確的MIME類(lèi)型的XHTML文檔,理解XML的瀏覽器將不顯示無(wú)效的頁(yè)面。因為瀏覽器需要知道要使用什么DTD(文檔類(lèi)型定義)才能正確地處理頁(yè)面,所以對頁(yè)面進(jìn)行有效性驗證要求有DOCTYPE聲明。
有效性驗證工具徑:
① W3C驗證器(bookmarklet),這是一小段可以存儲在瀏覽器的書(shū)簽或收藏夾中的Java。單擊這個(gè)書(shū)簽就會(huì )觸發(fā)Java動(dòng)作。
②可以訪(fǎng)問(wèn)http://validator.w3.org/,通過(guò)輸入自己的URL來(lái)對自己的站點(diǎn)來(lái)進(jìn)行在線(xiàn)驗證。
③使用firefox瀏覽器的可以下載插件Firefox Web Developer Extension
五、雅虎的Web優(yōu)化最佳實(shí)踐
1、內容優(yōu)化
① 盡量減少HTTP請求:常見(jiàn)方法包括合并多個(gè)CSS文件和Java文件,利用CSS Sprites整合圖像,Image map(圖像中不同的區域設置不同的鏈接),內聯(lián)圖象(使用 data: URL scheme 在實(shí)際的頁(yè)面嵌入圖像數據)等。
② 減少DNS查找,一般dns查找需要花費20-120ms,Windows的DNS緩存,可以通過(guò)ipconfig /displaydns 這個(gè)命令來(lái)查看。
③ 避免重定向
④ 使Ajax可緩存
⑤ 延遲加載組件:考慮哪些內容是頁(yè)面呈現時(shí)所必需首先加載的、哪些內容和結構可以稍后再加載,根據這個(gè)優(yōu)先級進(jìn)行設定。
⑥ 預加載組件:預加載是在瀏覽器空閑時(shí)請求將來(lái)可能會(huì )用到的頁(yè)面內容(如圖像、樣式表和腳本)。當用戶(hù)要訪(fǎng)問(wèn)下一個(gè)頁(yè)面時(shí),頁(yè)面中的內容大部分已經(jīng)加載到緩存中了,因此可以大大改善訪(fǎng)問(wèn)速度。
⑦ 減少DOM元素數量:頁(yè)面中存在大量DOM 元素,會(huì )導致Java遍歷DOM的效率變慢。
⑧根據域名劃分頁(yè)面內容:把頁(yè)面內容劃分成若干部分可以使你最大限度地實(shí)現平行下載。但要確保你使用的域名數量在2個(gè)到4個(gè)之間(否則與第2條沖突)。
⑨ 最小化iframe的數量:iframes 提供了一個(gè)簡(jiǎn)單的方式把一個(gè)網(wǎng)站的內容嵌入到另一個(gè)網(wǎng)站中。但其創(chuàng )建速度比其他包括Java和CSS的DOM元素的創(chuàng )建慢了1-2個(gè)數量級。
⑩ 避免404:HTTP請求時(shí)間消耗是很大的,因此使用HTTP請求來(lái)獲得一個(gè)沒(méi)有用處的響應(例如404沒(méi)有找到頁(yè)面)是完全沒(méi)有必要的,它只會(huì )降低用戶(hù)體驗而不會(huì )有一點(diǎn)好處。
2、服務(wù)器優(yōu)化
① 使用內容分發(fā)網(wǎng)絡(luò )(CDN):把你的網(wǎng)站內容分散到多個(gè)、處于不同地域位置的服務(wù)器上可以加快下載速度。
添加Expires或Cache-Control信息頭:對于靜態(tài)內容,可設置文件頭過(guò)期時(shí)間Expires的值為“Never expire(永不過(guò)期)”;對于動(dòng)態(tài)內容,可使用恰當的Cache-Control文件頭來(lái)幫助瀏覽器進(jìn)行有條件的請求。
② Gzip壓縮
③ 設置ETag:ETags(Entity tags,實(shí)體標簽)是web服務(wù)器和瀏覽器用于判斷瀏覽器緩存中的內容和服務(wù)器中的原始內容是否匹配的一種機制。
④ 提前刷新緩沖區:當用戶(hù)請求一個(gè)頁(yè)面時(shí),服務(wù)器會(huì )花費200到500毫秒用于后臺組織HTML文件。在這期間,瀏覽器會(huì )一直空閑等待數據返回。在PHP中,可以使用flush方法,它允許你把已經(jīng)編譯的好的部分HTML響應文件先發(fā)送給瀏覽器,這時(shí)瀏覽器就會(huì )可以下載文件中的內容(腳本等)而后臺同⑤時(shí)處理剩余的HTML頁(yè)面。
⑥ 對Ajax請求使用GET方法:當使用時(shí),瀏覽器中的POST方法會(huì )首先發(fā)送文件頭,然后才發(fā)送數據。因此使用GET最為恰當。
⑦ 避免空的圖像src
3、Cookie優(yōu)化
① 減小cookie大?。喝コ槐匾腸oockie,并使coockie體積盡量小以減少對用戶(hù)響應的影響
② 針對Web組件使用域名無(wú)關(guān)的Cookie:對靜態(tài)組件的Cookie讀取是一種浪費,使用另一個(gè)無(wú)Cookie的域名來(lái)存放靜態(tài)組件是一個(gè)好方法,或者也可以在Cookie中只存放帶www的域名。
4、CSS優(yōu)化
① 將CSS代碼放在HTML頁(yè)面的頂部
② 避免使用CSS表達式:CSS表達式在執行時(shí)候的運算量非常大,會(huì )對頁(yè)面性能產(chǎn)生大的影響
③ 使用來(lái)代替@import
④ 避免使用Filters:IE獨有屬性AlphaImageLoader用于修正IE 7以下版本中PNG圖片的半透明效果,但它的問(wèn)題在于瀏覽器加載圖片時(shí)它會(huì )終止內容的呈現并且凍結瀏覽器。
5、Java優(yōu)化
① 將Java腳本放在頁(yè)面的底部
② 將Java和CSS作為外部文件來(lái)引用:在實(shí)際應用中使用外部文件可以提高頁(yè)面速度,因為Java和CSS文件都能在瀏覽器中產(chǎn)生緩存。
③ 縮小Java和CSS
④ 刪除重復的腳本
⑤ 最小化DOM的訪(fǎng)問(wèn):使用Java訪(fǎng)問(wèn)DOM元素比較慢
⑥ 開(kāi)發(fā)智能的事件處理程序
6、圖像優(yōu)化
① 優(yōu)化圖片大小
② 通過(guò)CSS Sprites優(yōu)化圖片
③ 不要在HTML中使用縮放圖片
④ favicon.ico要小而且可緩存
7、針對移動(dòng)優(yōu)化
① 保持組件大小在25KB以下:主要是因為iPhone不能緩存大于25K的文件(注意這里指的是解壓縮后的大?。?。
② 將組件打包成為一個(gè)復合文檔:把頁(yè)面內容打包成復合文本就如同帶有多附件的Email,它能夠使你在一個(gè)HTTP請求中獲取多個(gè)組件。