1.0時代css
前期模塊化已經作的不錯了,至少沒必要花大量時間去重構代碼。模塊劃分以下圖,邏輯層次上仍是比較清晰。html
前端模塊化依賴的主流庫也就數國內的Seajs和國外的requirejs,這裏就不陳述。採用了Seajs做爲模塊管理器,zepto做爲基礎庫文件,lib主要包含了項目中用到的主流第三方庫文件。前端
咱們知道模塊化帶來的最大弊端即是HTTP請求數增長,因此上線的時候必須合併文件。下圖中的package模塊是文件大集合,打包了不少個JS模塊,除去上圖中的基礎庫文件和業務模塊層,在上線的時候大部分文件都被打包在package.js裏。node
大部分頁面的JS請求是這樣的:git
細心點的同窗可能注意到兩個問題:文件的大小和加載時間。剛纔的截圖仍是在PC端截取的,手機和不一樣網絡環境的表現會更加糟糕。github
如今來看下目錄 瀏覽器
目錄看起來算規範,但其實是公共的和業務的混在一塊。緩存
大部分文件合併在一個文件,合併策略不合理。cookie
由第二點引起的第三個問題,發佈上線時,只要兩人發佈涉及到package文件,衝突必然發生。網絡
發佈時須要down下上一次的文件,對照合併的新文件,以避免發錯。
注意,第四點是人工。一不當心發錯,或者把他人剛發佈的文件覆蓋了,這種事情發生10+次。
只有一臺測試機器,測試環境常常覆蓋是常事。
版本控制問題,不以SVN爲版本,而是預發佈機器上代碼,管理混亂
不敢想象若是10+人的團隊一塊兒在這種模式下開發,會是怎樣的場面。
22.0時代
由第一個版本引發的問題,着實讓人很蛋疼,每次開發版本就是一次陣痛,尤爲是測試、發佈環節。因此就開始慢慢着手解決。隨着業務擴展,人員增多,就誕生了下面這個圖。
調整模塊,讓共用的模塊更加共用,業務模塊跟隨業務自身。
更改模塊合併策略,既然大了,我就分紅小,必定程度緩解了衝突。
替換原有的同步文件工具,包括測試與正式環境,接入ARS,提測發佈流程順暢多了。
ARS帶有衝突檢測功能,告別人工對照合併,覆蓋再也不容易發生。
公共JS文件緩存在localstorage中,模擬manifest,帶版本號控制。
以SVN爲板塊控制工具,再也不對照外網代碼。
localstorage本地緩存
localstorage緩存命中率
首屏時間
window.onload時間
一切看起來很美好,可是好景不長,由於新的問題又來了。
以前拆分package.js文件爲多個文件,實際請求的時候則是合併了請求,包括JS文件和CSS文件。combo文件實際上會有延遲問題,在發佈的時間節點上存在不一樣步的問題,直接致使頁面掛了。
拋開combo文件不說,因爲瀏覽器緩存的問題,每次更新版本的時候要手動加上一個時間戳,來規避緩存形成的錯誤。也是個很蛋疼的點。
隨着業務增加,愈來愈多頁面是放在APP裏面訪問。觸屏頁面已經再也不是重點,如何更好的利用APP加速頁面纔是關注點。不少人想到了手Q的離線包,但據說實踐起來也不是特別方便,咱們就採用了客戶端緩存hash文件的策略,告別304。因此這裏又涉及到自動化。
雪碧圖基本是手工;
代碼混淆沒有壓縮;
CSS合併文件要手寫地址,相似下面:
http://at.qq.com/min/f=cssv4/common/reset.css,cssv4/common/base.css,cssv4/module/btns.css,cssv4/module/tab.css,cssv4/module/app-list.css,cssv4/module/talk-bar.css,cssv4/module/popup.css,cssv4/page/game-detail.css,cssv4/page/talk.css,cssv4/module/comments-bar.css
33.0時代
爲了解決上述問題,流程須要進一步優化,簡單點就是讓自動化程度更提升。
前期在方案選擇上也作過一些討論,本身徹底從底層寫時間上不容許。以前折騰過Grunt發現並非那麼好用,後來發現百度的前端解決方案FIS可以知足咱們的需求。
生成以hash值(後綴)命名的文件,代碼更改,生成新文件,且都會自動更新HTML中的引用(核心訴求),就像下圖:
合併雪碧圖
壓縮混淆文件
文件合併(包括JS文件和CSS文件)
能作到這幾點基本就知足了咱們的需求。前期的一切都是未知的,不太明白會遇到什麼大問題。乍看起來很是好用,若是簡單的頁面,確實會很簡單,只要簡單幾行配置就能夠搞定,但到如今FIS的配置文件200+行。一些特性很難知足,須要二次開發。上手簡單,要深刻難,必需要看源碼改源碼,寫插件,這大概就是用FIS的心得。
前期想了要怎樣把開發——測試——預發佈——發佈這個流程依賴工具流暢的跑起來,大概構思以下:
注:
調試、發佈代碼與源代碼分離
本地調試用代理如fiddler,或者上開發機
deploy是構建工具同步文件的一個功能
保證源碼的版本最新,發佈代碼走ARS。
工程化進展卻不是想象中的順利,實踐中遇到了一些問題,也只能硬着頭皮咬着牙去解決。
衝突問題
衝突問題一直存在,在2.0時代不那麼明顯罷了。緣由是測試環境的JS已經被合併過一次。
時間問題
因爲剛開始文件比較少,構建速度基本沒啥問題。後來業務愈來愈多,參與的開發也越來約多。文件暴增到4000+,構建時間一步步增長。
開發調試耗時 3987ms
發佈構建的時候由於要進行md5計算,文件壓縮等,要181745ms!已經沒法忍了。
ARS流程
用過ARS的同窗確定明白,流程仍是比較蛋疼,要完成提交SVN,點擊同步等等一系列操做,繁瑣。
構建命令
命令比較長,參數多,難以記憶
產出文件多,發佈麻煩
每改動一個字母,發佈的時候就會生成一個新的文件,發佈的時候真是在文件堆裏找!!
這一系列的問題如山倒,組內的開發同窗已經無法愉快的開發了。
減小衝突問題
進一步解決的方案仍是細分模塊,測試環境不進行文件合併,這樣衝突的機率幾乎很小,由於公共庫通過2.0的調整已經基本穩定。
縮短期
構建時間這麼長,這樣發展下去是不行的。花了一些時間研究FIS源碼,發現FIS監聽的是整個項目文件,每一次構建都要掃描所有文件,這樣時間必然會隨着文件增長而變長。而後進行深度改造,變得不那麼像FIS了。
進行一次又一次優化,改變構建策略。依賴構建:當某個文件依賴另外一個文件時,另外一個文件纔會被構建。假如a.html依賴了b.js ,在構建產出的文件就只有這兩個文件,其餘文件不會被構建,文件數也減小,時間大大縮短。
開發構建 (單位ms )
發佈構建 (單位ms)
構建命令優化
輸入命令麻煩,就用GUI界面,點點按鈕就行。這裏要感謝@koppthe@kolawang同窗短期內用node寫的GUI。
產出文件多
依賴構建以後,只會產出相關文件,產出文件大大減小,發佈難度減小不少。
ARS流程
修復bug的時候不用ARS同步,監聽文件變化直接同步到測試環境。
只須要8ms!!!。若是打開了同步按鈕,修改的文件會立立刻傳到測試環境上,會不會有相互覆蓋的問題。組內每一個人負責的模塊都不一樣,並且公共模塊已經基本穩定,很難出現這樣的問題,在實踐中不多發生這樣的事情,相反小夥伴以爲簡直得到解脫,相比找文件傳文件這樣繁瑣的流程,這輕鬆了許多。
發佈優化
構建工具會產出文件列表,點擊就能打開文件夾,找到對應文件;列表對應SVN路徑,直接貼到ARS就能提單。
雪碧圖的優化
發佈的時候全部引用的CSS文件會合併成一個,而後將引用的圖標合併爲雪碧圖,有點粗暴。由於公共的CSS文件的圖片單獨合併爲雪碧圖會更加合理,公共的圖片變更頻率不會那麼高。開發一插件,在CSS合併前雪碧圖一次,合併後再雪碧圖一次。
用戶網絡類型(粗略)
unknown是沒法統計到的,理論上wifi仍是佔大部分。從其餘四種類型看,wifi佔據絕大部分,2g用戶很是少。
PC VS Mobile
在JS下載和執行效率上,移動端明顯要低於PC端。
JS優化
以前APP內部的JS文件都是經過seajs來下載文件,後來發覺何不直接乾脆點直接寫<script>
下載就行了,優化後下載執行時間降低顯著:
注:這裏統計的時間,包括了下載JS和執行JS的時間。
JS內嵌與外聯對比
在考慮優化的時候,咱們一種方案即是將外聯的JS代碼(僅業務代碼)經過工具內嵌到頁面。如今來對比下性能:
http://gqq.gtimg.com/static/mobile/js/v3/page/gift/list/inappand.a9a524eb.lc.js 文件大小8.7kb,gzip壓縮後3.3kb。
內聯加載時間幾乎爲0 0.0015793,外聯的下載時間:
下載時間不到200ms,但相對來講已是很長了,才8.7kb。
咱們知道,DOMContentLoaded事件的觸發基本意味着頁面已經渲染完成,JS已經執行(異步的除外),已經達到可交互的狀態了,具體可參考這篇文章。下面看下內聯與外聯對DOMContentLoaded的影響:
藍色線條是外聯的JS,時間明顯要比內聯的高出一些,大概200ms。因而可知,將小量的JS文件內聯到頁面,可以提升速度。但大的JS文件適不適合內聯,目前尚未實驗。這裏須要在減小HTTP請求和利用緩存之間把握一個平衡,不少時候優化準則是並非那麼容易實施,由於可能自相矛盾,也可能和工程自己相矛盾。優化不是按照準則照本宣科的作,須要靈活變通。
優化措施
按照雅虎優化的14條準則,把還沒作到的都處理了。
腳本域名切換,去cookie。
文件合併
利用瀏覽器緩存,無限增大緩存期max-age=15552000
雪碧圖
減小HTTP請求,構建工具內嵌JS到HTML
感受速度仍是不夠快,再充分利用本地緩存和APP提供的緩存能力
瀏覽器使用localstorage緩存腳本
APP緩存hash文件名腳本
緩存HTML片斷
調試、測試、體驗流程
反向代理+白名單控制策略,域名對外訪問是403,公司內網可訪問。不用代理,手機直接鏈接wifi訪問。環境分爲開發——測試——預發佈——正式(每一個環境對應一個獨立域名),任何角色(開發、測試、設計、產品)均可隨時訪問。
APP的debug包,可任意切換上面四種環境進行調試、測試、體驗。
這是過去一年工做的總結,一直都沒靜下來梳理。回過頭想,本身是否是把這個流程變得更加複雜了。可能都有一個從簡單到複雜再到簡單的過程,堅持優化一直沒有停下來,只要可以變得更好一點點,都會去嘗試,所謂生命不息,折騰不止。
做者:addy(許斌)