Web前端性能優(yōu)化進(jìn)階路
Web前端性能優(yōu)化WPO,相信大多數(shù)前端同學(xué)都不會(huì)陌生,在各自所負(fù)責(zé)的站點(diǎn)頁(yè)面中,也都會(huì)或多或少的有過(guò)一定的技術(shù)實(shí)踐。可以說(shuō),這個(gè)領(lǐng)域并不缺乏成熟技術(shù)理論和技術(shù)牛人:例如Yahoo的web站點(diǎn)性能優(yōu)化黃金法則,以及大名鼎鼎的優(yōu)化大師Steve Souders。本文并非一篇討論性能優(yōu)化技術(shù)方法的文章,而更多的是對(duì)中文站搜索List頁(yè)面持續(xù)兩年多的前端性能優(yōu)化實(shí)踐的思路總結(jié)。希望對(duì)正在從事這個(gè)領(lǐng)域研究的前端同學(xué)能有所幫助。
簡(jiǎn)單的說(shuō),我們的性能優(yōu)化實(shí)踐分為三個(gè)階段:初探期、立規(guī)期、創(chuàng)新期, 每個(gè)階段大概持續(xù)半年左右,有足夠的時(shí)間形成一些優(yōu)化思路的沉淀。
一:初探期
2010年底我們開始接手搜索List頁(yè)面,這是中文站歷史最為悠久的頁(yè)面之一,當(dāng)時(shí)它的生命體征正如它的年齡一樣,非常虛弱:當(dāng)時(shí)的基調(diào)網(wǎng)絡(luò)監(jiān)控顯示,頁(yè)面的完全加載的時(shí)間是16秒!作為以“快”為核心業(yè)務(wù)指標(biāo)的搜索頁(yè)面,這個(gè)狀態(tài)顯然已是無(wú)法承擔(dān)重任了。
性能是一定要優(yōu)化的,但我們也面臨著大多數(shù)前端同學(xué)所面臨的共性問題 — 業(yè)務(wù)需求緊張,況且我們是剛剛接手這個(gè)業(yè)務(wù),非常不熟悉,別說(shuō)是優(yōu)化了,就是做個(gè)小需求也都經(jīng)常出現(xiàn)線上故障。就是在這樣的情況下,我們開始了搜索頁(yè)面的性能優(yōu)化之路,并且給自己定下了當(dāng)時(shí)看起來(lái)非常難以實(shí)現(xiàn)的目標(biāo):在2011年年中前把全頁(yè)面加載時(shí)間降低到7秒以下。
我們很快成立了一個(gè)性能優(yōu)化小組,3-4個(gè)前端同學(xué)參與其中,一個(gè)人的力量畢竟有限,尤其是應(yīng)對(duì)這樣一個(gè)歷史業(yè)務(wù)繁多的頁(yè)面。參與的同學(xué)多些,技術(shù)氛圍也相對(duì)濃烈,大家很全面的分解了目前頁(yè)面上出現(xiàn)的性能瓶頸,并分別領(lǐng)取了自己的優(yōu)化任務(wù)。
在這個(gè)階段里,我們基本是照葫蘆畫瓢,把雅虎性能優(yōu)化的那些法則與我們的頁(yè)面一一對(duì)照,完成了許多優(yōu)化點(diǎn),例如:
●小圖片的合并,形成CSS Sprite,并優(yōu)化圖片
●模塊的異步加載
●圖片的懶加載
●CSS文件引用放在頁(yè)面頂部,JS文件引用放在頁(yè)面底部,并對(duì)代碼壓縮
●縮小cookie體積
●…
前人的技術(shù)理論果然是靠譜,經(jīng)過(guò)我們半年時(shí)間加班加點(diǎn)的性能優(yōu)化后,我們奇跡般的達(dá)成了優(yōu)化目標(biāo)?。ǜ叫阅芮€圖)
眾多優(yōu)化點(diǎn)中,對(duì)優(yōu)化效果貢獻(xiàn)***的就是對(duì)圖片的處理,包括了CSS sprite的合并及圖片的懶加載,說(shuō)白了就是雅虎性能優(yōu)化法則的***條:要盡量地減少HTTP請(qǐng)求。說(shuō)實(shí)話,CSS sprite合并這塊的體力活較多,但前端同學(xué)一定要引起重視,對(duì)頁(yè)面性能影響確實(shí)很大。
初探期優(yōu)化經(jīng)驗(yàn)所得:
1、優(yōu)化前,廣泛地獲取該領(lǐng)域的各種優(yōu)化思路。有條件的同學(xué)可以參加下WPO領(lǐng)域的一些會(huì)議,比較推薦Velocity性能優(yōu)化大會(huì)。
2、成立性能優(yōu)化組織,明確性能優(yōu)化目標(biāo)。
這一點(diǎn)非常重要:可量化的目標(biāo)以及可持續(xù)跟蹤的優(yōu)化數(shù)據(jù)是性能優(yōu)化工作得以持續(xù)進(jìn)行的保障,同時(shí)也是源動(dòng)力!大家能持續(xù)這么長(zhǎng)時(shí)間迭代的進(jìn)行優(yōu)化工作,正是因?yàn)槊總€(gè)階段我們都有相應(yīng)的性能優(yōu)化目標(biāo)作為指引,并有志同道合的同學(xué)一起努力。
3、持續(xù)追蹤性能數(shù)據(jù),要選擇合適的頁(yè)面性能測(cè)量工具,一旦選定后,不再更換,以保證歷史數(shù)據(jù)的可參照性。
我們一直在使用基調(diào)網(wǎng)絡(luò),不得不說(shuō)還是非常專業(yè)的,不過(guò)是收費(fèi)工具。 給自家的測(cè)試工具也打個(gè)廣告吧,免費(fèi)的測(cè)量工具–阿里測(cè)。國(guó)外的測(cè)量工具也挺多的,不過(guò)受網(wǎng)絡(luò)因素影響太大,數(shù)據(jù)抖動(dòng)大,不是很推薦使用。
4、性能優(yōu)化不僅僅是可以直接的提升用戶體驗(yàn),對(duì)參與其中的前端同學(xué)而言,也是快速熟悉業(yè)務(wù)的一種捷徑。更進(jìn)一步說(shuō),可以作為技術(shù)驅(qū)動(dòng)業(yè)務(wù)的入口,因?yàn)閮?yōu)化重構(gòu)的過(guò)程中你更容易發(fā)現(xiàn)歷史業(yè)務(wù)的不合理之處,從而推動(dòng)業(yè)務(wù)方的改造,可以提升個(gè)人的技術(shù)影響力。
二、立規(guī)期
性能優(yōu)化工作并非一朝一夕的事,今天達(dá)成了目標(biāo),并不意味著明天躺著睡覺也能維持成果。相反,前端性能通常呈現(xiàn)出較高的反復(fù)性,這和新的業(yè)務(wù)需求有著非常直接的關(guān)系,但更底層的原因通常是我們并未把性能優(yōu)化的規(guī)范給確定下來(lái)。2011年的下半年,我們并未在具體性能優(yōu)化技術(shù)點(diǎn)上投入更多的工作,而是做了性能優(yōu)化的“守道士”,不過(guò)這個(gè)“守”不是保守的“守”,而是以攻為守。
一方面我們制定了針對(duì)性能優(yōu)化前端代碼規(guī)范,其中最重要的是對(duì)頁(yè)面圖片資源的管理規(guī)范,納入到SVN管理,提高新圖片文件添加的成本。
另一方面我們建立了“性能聯(lián)盟”:性能優(yōu)化不僅僅是前端同學(xué)單方面就能夠保證的,更需要產(chǎn)品經(jīng)理、設(shè)計(jì)師、Java開發(fā)同學(xué)的支持和配合。在這一點(diǎn)上我們做了很多工作,當(dāng)然更多的是溝通和意識(shí)的影響,讓大家形成一個(gè)共識(shí):性能是最重要的業(yè)務(wù)功能點(diǎn)!在平時(shí)的業(yè)務(wù)需求中,一定要從性能的角度考慮問題,有理有據(jù)的拒絕掉一些有損于前端性能的業(yè)務(wù)需求。
經(jīng)過(guò)大家的努力,在這個(gè)階段,搜索頁(yè)面的性能一直維持在7秒鐘左右,長(zhǎng)達(dá)半年的時(shí)間。
立規(guī)期優(yōu)化經(jīng)驗(yàn)所得:
1、攻城難,守城更難。制訂優(yōu)化規(guī)范,并嚴(yán)格執(zhí)行,是優(yōu)化成果得以長(zhǎng)期保持的必要保障。
2、性能優(yōu)化不是前端同學(xué)自己的事情,需要業(yè)務(wù)各合作方的共同認(rèn)同和支持。性能是最重要的業(yè)務(wù)功能點(diǎn)!
3、前端同學(xué)要增強(qiáng)自己的技術(shù)判斷力,正確評(píng)估業(yè)務(wù)需求對(duì)性能的影響。同時(shí)要提升自身的溝通和影響力。
三、創(chuàng)新期
進(jìn)入到2012年,隨著我們對(duì)搜索業(yè)務(wù)理解的逐步深入,我們已不滿足于在原有前端框架上的修修補(bǔ)補(bǔ),而是有了更多的自信去徹底重寫整個(gè)搜索前端應(yīng)用框架。這也使得性能優(yōu)化工作進(jìn)入到一個(gè)新的階段。
在這個(gè)階段,我們努力的核心目標(biāo)是:從應(yīng)用框架和工具的層面做性能優(yōu)化,讓性能優(yōu)化成為一件低成本的事,真正的做到 fast by default!
在搜索應(yīng)用框架jEngine的構(gòu)建過(guò)程中,我們將一年多的前端優(yōu)化實(shí)踐思路融合在其中,實(shí)現(xiàn)了對(duì)性能優(yōu)化友好的模塊注冊(cè)機(jī)制、BigRender優(yōu)化模式、<script>標(biāo)簽無(wú)阻塞加載等利用框架即可低成本實(shí)現(xiàn)優(yōu)化的模式的支持。同時(shí)jEngine應(yīng)用框架在模塊化、前端異常監(jiān)控方面也有著自己獨(dú)特的實(shí)現(xiàn),感興趣的同學(xué)可以研究下。
簡(jiǎn)單介紹下對(duì)性能友好的模塊注冊(cè)機(jī)制的實(shí)現(xiàn):jEngine的模塊管理引入了“懶注冊(cè)”的機(jī)制,所有的頁(yè)面模塊被分為以下三種模塊:
一個(gè)模塊的是首屏加載還是延遲加載,和它本身的類實(shí)現(xiàn)沒有關(guān)系,只和模塊的注冊(cè)方式有關(guān)系。
如果他出現(xiàn)在首屏,就使用正常的模塊注冊(cè)方式:AppCore.register(“sw_mod_sn”, Searchweb.Business.Category);
如果非首屏模塊,需要頁(yè)面滾動(dòng)加載,或是鼠標(biāo)事件觸發(fā)加載,那么它的注冊(cè)方式只需改成這樣:
通過(guò)這種的方式,可以低成本的改變頁(yè)面初始化過(guò)程中對(duì)頁(yè)面各模塊的加載方式,從而減少首屏加載的文件個(gè)數(shù)和JS執(zhí)行時(shí)間。
***這個(gè)階段,我們不僅形成了對(duì)性能友好的前端應(yīng)用框架jEngine,還完全重寫了搜索各業(yè)務(wù)模塊代碼,完成了從YUI到j(luò)Query基礎(chǔ)框架的升級(jí),最終把頁(yè)面加載時(shí)間長(zhǎng)期穩(wěn)定在4秒左右。
創(chuàng)新期優(yōu)化經(jīng)驗(yàn)所得:
1、從架構(gòu)、框架上發(fā)力能夠降低性能優(yōu)化的后期維護(hù)成本。
2、技術(shù)思路上的創(chuàng)新是性能優(yōu)化持續(xù)進(jìn)行的源動(dòng)力。
3、性能優(yōu)化工作是提升前端同學(xué)技術(shù)能力水平的一個(gè)很好的切入點(diǎn)。
性能優(yōu)化領(lǐng)域一個(gè)是值得前端同學(xué)深入研究的領(lǐng)域,網(wǎng)站性能直接影響到用戶體驗(yàn)和各項(xiàng)業(yè)務(wù)指標(biāo)。隨著移動(dòng)互聯(lián)網(wǎng)的快速發(fā)展,這個(gè)領(lǐng)域的研究熱點(diǎn)也有向移動(dòng)性能優(yōu)化轉(zhuǎn)向的趨勢(shì),相信今后會(huì)有更多更精彩的技術(shù)出現(xiàn)。