5173首頁前端性能優(yōu)化實踐
來源:解決方案 2012-06-07
從制定計劃,到前后端的開發(fā),最后到測試以及上線,歷時4個月,5173首頁前端性能優(yōu)化項目終于順利上線,并達到了預期的性能優(yōu)化目標。這次的項目并不是改版,而是原來首頁的設計和功能不變,只做重構和優(yōu)化。雖然項目名叫前端的性能優(yōu)化,但也并不僅僅是前端單方面的工作,要想徹底的把優(yōu)化做好,就需要前后端的通力配合。
歷史背景
老首頁應該是09年上線的,首頁也是各部門爭奪資源的地方,大家都想在首頁有一席之地,各部門在首頁都有各自的小豆腐塊,如果有新項目的上線,大多是打補丁的方式,并且唯一的規(guī)范就是能保證功能正常運行,至于性能方面,那是很遙遠的事。苦逼的是開發(fā)人員,每次有首頁的修改都是擔驚受怕的,怕改了這個那個又出問題,歷史原因造成的問題越來越多。
最先看不下去的應該是前端人員,因為首頁在不斷的修修補補中,性能已經差到前端人員覺得很沒面子的地步了。但是看不下去也僅僅是看不下去,沒法采取實質性的措施來改善,因為這牽涉到各部門的利益,也如上面說的,優(yōu)化不僅僅在于前端,于是前端人員也只能向上面反映問題。到了今年,終于領導也看不下去了,某領導在海外訪問我司的818.com和5173.com首頁,對比起來前者首頁很快(插播一句,818首頁前端開發(fā)人員也正是我^_^),后者首頁很慢,差別較大。于是在領導重視的推動下,5173首頁的前端性能優(yōu)化項目才經過批準,開發(fā)人員終于可以放手大膽的折騰了。
問題分析
在動手前要制定計劃,制定計劃要從解決實際問題出發(fā),先來看看老首頁的問題,這是我在制定計劃時收集的相關數(shù)據(jù):
1、請求數(shù)過多,其中CSS外鏈數(shù)有12個,JavaScript外鏈數(shù)竟有41個;
2、頁面總體積過大,很多靜態(tài)資源都沒加gzip,動態(tài)站點的JS甚至都沒有壓縮過;
3、資源占用嚴重,在IE6下滾動頁面時CPU占用率高達80%以上,內存泄漏也很嚴重;
4、廣告系統(tǒng),廣告圖片都是以document.write的方式在加載,頁面堵塞的情況很嚴重;
5、頁面有7個iframe;
6、數(shù)據(jù)源接口混亂;
7、頁面加載速度過慢,有白屏現(xiàn)象,首屏完成加載很慢;
上面的數(shù)據(jù)讓你很震驚,這也說明了有很大的優(yōu)化空間。找出了問題所在,接下來才有具體的實施方向?傊,無論是常規(guī)的方法,亦或是奇淫技巧,目標只有三個字,“快,更快”。
具體實施
雖然粗看頁面的內容并不是很多,但是具體到功能模塊,都是很費時費力的。我們老大有一句很經典的話,“通常我會問面試人員一個問題,如果你獨自來做5173首頁的前端工作,多久能完成?如果答案只有一個星期,要么是沒看過頁面,要么就是很不專業(yè)。”我就獨自花了一個多月的時間才完成首頁的前端開發(fā)工作。下面來說說具體的實施吧。
HTML&CSS 的重構
頁面的設計和功能沒有變動,但是HTML頁面還是要做徹底的重構,這里我也嘗試了使用 HTML5 的新標簽來對頁面進行布局。CSS 的重構也是理所當然的,原來有12個外鏈的 CSS,這些都要統(tǒng)統(tǒng)干掉的,有些模塊如果不止首頁有用到,就需要模塊化,該放到公用文件就放到公用文件中,在開發(fā)的時候可以分多個模塊,然后使用 @import到一個文件中,打包發(fā)布的時候再合并成一個文件。這需要把握好一個度,即要合理利用緩存,又要避免單文件過大,同時也要做好模塊化。
老首頁有很多 CSS 選擇器過長的問題,可能一個 CSS 選擇器的組合長達6-7個也是常有的事,CSS 選擇器過長不僅僅是性能方面的影響,同時也因為 CSS 權值的關系,給后期維護帶來了很多的麻煩。應該多使用 class 來定義選擇器,再加上 tag 選擇器的組合,最多3個選擇器的組合就能滿足絕大多數(shù)的需求了,另外在 CSS 的編寫方面禁止使用 id 選擇器和 !important,養(yǎng)成良好的 CSS 編寫習慣很重要。
JavaScript 的重構
JavaScript的重構太迫切了,原來竟有41個 JavaScript 外鏈文件,當然這些外鏈也包括了15個廣告的外鏈,廣告的優(yōu)化我稍后再說,但是還剩下26個外鏈 JavaScript。這些臃腫不堪的 JavaScript文件即是造成頁面加載堵塞的元兇,也是系統(tǒng)資源占用的蛀蟲,這是整個項目的難點之一。
重新梳理了四級聯(lián)動搜索的業(yè)務邏輯,并對四級聯(lián)動搜索的交互功能做優(yōu)化,增強用戶體驗。這個模塊的 ajax 交互功能較多,最大的 JSON 數(shù)據(jù)包竟然有94.4KB,此時合理的利用當前頁面的緩存功能($.fn.data)很重要。體積最大的 JSON 數(shù)據(jù)包在頁面 Dom Ready 后進行加載,然后拼裝第一屏的 HTML 代碼并緩存,當用戶按字母索引選擇游戲的時候再到已加載完的 JSON 數(shù)據(jù)包中尋找相應的數(shù)據(jù)去拼裝 HTML 代碼,然后緩存該索引的 HTML 代碼。如果接下來再選擇區(qū)、服、交易類型時,再到服務器去取相應的 JSON 數(shù)據(jù),拼裝成 HTML 代碼后進行緩存,此時只緩存最后一次的選擇結果。
便民中心也同樣是首頁業(yè)務邏輯很復雜的模塊,涉及到很多的ajax交互以及表單的操作。各個TAB中的表單是根據(jù)請求的JSON數(shù)據(jù)來生成HTML結構的,原來是每次點擊TAB都會請求一次數(shù)據(jù),然后生成HTML結構,每切換一次TAB都要請求,再生成,這真得很二。同樣的數(shù)據(jù)和結構只要請求一次,并生成一次即可,這種重復的操作是赤裸裸的浪費資源。該模塊的JavaScript原來請求的動態(tài)站點的文件,沒有做緩存也沒做過壓縮,每次頁面加載都在這里阻塞一小會。這里的服務端的數(shù)據(jù)源接口也很亂,開發(fā)人員缺乏規(guī)范化數(shù)據(jù)接口的概念。這里的諸多問題,我已無力吐槽了。最后也是重新梳理蛋痛的業(yè)務邏輯,重構代碼。
延遲加載,提升首屏的加載速度
當用戶打開一個很長的網頁時,首屏內容的加載給了最直觀的速度體驗。所以,讓首屏盡快的完成加載也是用戶衡量該頁面是否夠“快”的最主要的因素。5173的首頁,圖片基本都集中在下面的位置,讓下面的這些圖片全部都延遲加載就可以盡可能快的提升首屏的加載速度。常見的圖片延遲加載技術想必大家都不會陌生了,這里就不復述。在 TAB 內容中也同樣有很多圖片,這里也讓它們在觸發(fā) TAB 菜單的時候再進行加載。給圖片在HTML代碼中添加固定的尺寸自然也不再話下。so easy? no!
圖片中不僅僅有業(yè)務配置的圖片,也有來自第三方廣告系統(tǒng)的圖片(包括首屏的輪播大圖也是此類型的)。這些廣告圖片的 URL 是一個 JavaScript 鏈接,其中包含了使用 document.write 的方式來加載廣告圖片的代碼。還有些 TAB 中包含了使用 iframe 嵌入到頁面的合作站點的內容。廣告圖片以及 iframe 都是阻塞頁面加載的元兇。
最初的想法是重新開發(fā)一套廣告系統(tǒng),換一種廣告加載方式,但是開發(fā)成本太高。最后想到了使用 textarea 來延遲加載廣告和 iframe,玉伯提供的這種方法確實挺好用的。textarae 是個好東西,不論是普通的 HTML 代碼亦或是 CSS、JavaScript 代碼,都可以扔到里面去實現(xiàn)延遲加載。廣告圖片的優(yōu)化比較麻煩,我在另一篇文章中有詳細的介紹。有了 textarea,很多內容都可以像實現(xiàn)圖片延遲加載那樣來實行延遲加載,在 TAB 內容中的 iframe 也可以在觸發(fā) TAB 菜單時再去加載 iframe。
正是這些各種延遲加載內容的奇淫技巧在最大限度上提升了網頁首屏的加載速度。但是延遲加載內容帶來的副作用需要說明,對于一些比較重要的內容,需要考慮到對 SEO 的影響。
服務端的優(yōu)化
前端能做得基本都說完了,再來說說服務端的優(yōu)化工作吧。原來服務端提供給前端的數(shù)據(jù)源都是從各個站點過來的,前端需要跟各個部門的開發(fā)人員打交道,并且他們提供的數(shù)據(jù)源在性能上也比較慢。經過協(xié)商決定將各數(shù)據(jù)源匯總到一臺中間服務器上,前端統(tǒng)一從這臺中間服務器中去取數(shù)據(jù),服務器端之間的通訊都加上一定的緩存時間,這樣就解決了數(shù)據(jù)源慢和不統(tǒng)一的問題。
針對頁面總體積過大的問題,代碼的重構確實能減小不少的體積,另外靜態(tài)資源一律都要添加gzip,僅僅是添加gzip,帶來的性能提升也是比較明顯的。
合理的利用瀏覽器端的緩存也是很重要的,除了登錄信息以及 cookie 的這種時效性較高的請求外,所有能添加 cache-control 的請求都加上了 max-age 的過期時間。關于瀏覽器端的緩存添加,這里有一篇比較詳細的文章 Cache them if you can。緩存的添加也會給更新帶來麻煩,所以要有相應的方法來清除緩存,給靜態(tài)資源的請求加上時間戳即可。
另外服務端這次也大膽的采用了 varnish 作為緩存加速服務器,這在國內大型網站中應該還不多見。
優(yōu)化成果
做了這么多工作是時候看看優(yōu)化成果了,先來看一組數(shù)據(jù)對比:
優(yōu)化前后的請求數(shù)對比:
請求數(shù)的大大減少,緩解了服務器的壓力,可以撤掉很多服務器了。
優(yōu)化前后的靜態(tài)資源的文件體積對比,沒有包含ajax數(shù)據(jù)等其他文件體積:
從文件體積的對比來看,優(yōu)化后節(jié)省了494KB的下載量,假若按照日PV(估值,實際值遠大于該值,實際值不便透露)來進行計算,那么每天就可以節(jié)省流量470GB。
優(yōu)化前后的加載時間對比,這是在同樣的網絡環(huán)境下同時測試了淘寶和拍拍來進行對比,測試軟件為基于 IE9 的 webWatch,每次測試都是清除緩存,分多次測試得到的一個平均值:
關于加載速度的分析,淘寶和拍拍的首屏的圖片較多,所以首屏的速度快,但是總加載時間要長很多,當然他們的下載量也要大很多,5173的首屏是DOM數(shù)較多,下載量也小很多,所以總時間和首屏時間相當接近。這里說得總下載量是頁面初次加載完成的總下載量,由于都用到延遲加載技術,向下滾動時又會有圖片加載,這些時間是不計算在內的。
到底應該如何來衡量網頁加載的快慢?此次的優(yōu)化我沒有用 yslow 和 pagespeed 等測試分數(shù)的軟件,而是以實際的加載速度為優(yōu)化的目標,首屏的加載速度提升就是最符合實際的說明。如果一個網站打開半天還是白屏,相信大多數(shù)人都會覺得很慢。這就是實際的體驗,測分軟件是反映不出來的。
文章來源:雨夜帶刀’s Blog
文章編輯: 365webcall網頁客服軟件(www.365webcall.com)
我的評論
登錄賬號: | 密碼: | 快速注冊 | 找回密碼 |