QQ空間的前端技術水平如何?
感覺挺複雜,挺卡的一個東西,或者說載入比較緩慢?
只是打開Qzone首頁(我的動態,這裡指http://user.qzone.qq.com/XXXXXXXXX),滑鼠沒有移動到屏幕的任何元素上,也沒有進行任何點擊,就有295個請求,圖片就不說,很合理,但是卻載入了114個JavaScript文件。前端性能優化原則難道不是盡量合併請求嗎?
看得出用了非同步載入,但是從網頁背景出現顏色,到真正各個控制項渲染完成能用能流暢滾動,還是過了很久。
感覺有些不可思議。(這是我小號我剛開通的QQ空間,沒有裝扮,也沒加上任何奇奇怪怪的掛件。)
作為空間前端老司機,看到大家討論那麼激烈。也想分享一下自己的經驗,作為空間06年到11年的前端開發,或許可以給大家分享一些當時的技術選型讓大家看到空間的技術演進(至於現在為什麼變成這樣,我不去做評價對錯)。
1. 06年,還是一個前端技術萌芽的年代,雖然04年google把ajax概念讓更多人看到了前端的重要性,但是前端技術還是非常沒有標準化的年頭。剛接手空間的前端代碼,前輩們為了極致的體驗,十幾號開發(前端,後台,甚至運營開發都有)都在同時改一個文件G4.js,文件數量可達200k(自己腦補有多少行)。當時沒有像現在那麼多框架,那麼多解決方案,更加沒有node.js,你從何下手? 如果你們都覺得文件請求合併為基本原則,那麼這個做法是不是就是對的?
2. 對於那麼大的文件,代碼本身的問題就非常多。所以接下來的事情,我想的方式是拆開,模塊化。做這個事情,後來就到了07年,為了讓模塊化開發方式簡單,自己寫了壓縮合併工具,自己定義模塊載入的方式。然而當時能想到最簡單的優化就是,把首頁用戶不需要的內容盡量非同步載入。如果回想起來,當時最遺憾的是,並沒有把模塊化的工作方式,抽象成設計模式。後來做DO分離的時候,我們把前端的工具也慢慢推動形成了公司級的工具,包括發布和壓縮,其實也是最早期的前端工程化雛形。當然工程化還包括了最早的公司web端性能的測速平台
3. 抓包中你們還能看到qzfl,這個是最早期為了解決開發規範,解決瀏覽器兼容的產物。這個框架為空間做了非常多的深度定製,同時也從整個團隊來說,讓前端開發在生產環節獲得效率的提升(當然始終沒有提升效率到,我們有時間去做開源,這個深表遺憾)。當然到現在同時看到多個基礎庫,其實是讓我覺得非常痛心的一點,在現在提倡去框架的時代,在空間依舊看到了很多基礎庫。這個確實需要後輩們想辦法,qzfl已經發揮了它最大的價值,是否還能帶來更大的價值?
4. 前端優化,這個很古老又很贊新的問題。怎麼做都沒有對錯,雖然前端優化也能有一些常規的設計模式去驅動,但是設計模式不見得都是全對的。空間的優化原則是基於數據分析的基礎去做的,所以我們會去關注真實用戶端的使用情況。空間多首屏載入做了非常多調整,以及對10%的用戶,在網路接入,運營商,使用習慣上做更多的分析。所以我們並不會說直接套用xxx優化原則就認為我們做了優化,優化隨著時間推移,隨著用戶硬體的升級,也在不斷調整著策略。
當然以上這些優化其實只解決了用戶訪問的速度問題,並沒有解決卡頓的問題。所以我在12年的velocity china上提出了前端的渲染性能優化的分析方法(有興趣可以百度搜索16毫秒的優化),希望前端開發通過渲染問題的分析,去優化空間的卡頓。因為空間長期都在和網路較量,對於複雜前端性能,確實看得不夠多,特別是運行時的性能。
空間的前端技術,也許在現在很多人看起來技術很古老。但是它已經是一個大象級別的項目。另外在業務面前,一個理性的程序員會考慮,我的重構是否對現在的優化還有價值? 空間當年從10萬到百萬,到千萬訪問量的提升的時間段內,各種優化都是值得的。然而到了現在頂峰階段,去做天翻地覆的改動價值是否得以放大?
所以,也建議大家不要以新技術的運用作為判斷前端技術是否NB的唯一標準。回想04年ajax誕生,算是新技術?其實只是一個新的設計模式。最後空間前端團隊,雖然在開源上沒有太多的貢獻,但是在騰訊內,給大家創造了非常大的成長空間,創建了騰訊的web前端通道,讓前端技術真正在公司內受到重視,做到這點已經足夠。心存感激。利益相關:QQ空間 web前端開發,你吐槽的頁面,就是我做的。
知乎從來都是只看不答,這次為了答題,總算註冊一個知乎大號。這個回答僅對題主提出的做的不好的地方做下反思和一些解釋,至於技術牛不牛,不在這裡探討,反正我是不牛的那個。
媽媽說做錯了就得承認,黃老師說不能鴨子死了嘴殼子硬。感謝題主指出了問題,讓我可以再回過頭來看做得不好的地方(老大總算要安排時間給我優化啦,哈哈哈)。
一開始,關於文件數載入,先提出我的看法:
1.最重要的時間是什麼,是用戶首次可交互時間,那麼為了儘可能的優化這個時間,我們要保證在這之前請求儘可能的少,這是必須做到極致的。
2.有些功能,用戶一進來並不會立刻使用,那麼這些功能的文件,只需要在用戶準備用它之前載入好即可。什麼時候載入,多少個請求,其實影響不大。
好啦,下邊一個一個的說吧。
1.載入了114個js文件
我進自己空間,清掉緩存,無緩存狀態,js 122個,嚇尿了。
再次進空間,帶緩存訪問,還好,文件數雖多,大多數都是從from cache,還好還好。
回過來繼續看哪些文件可合併,哪些文件不可合併。逐個說下吧。
1)基礎庫文件 3個
這幾個是基礎庫,可不可以合呢?當然可以合,為什麼不合呢?基礎庫文件基本是不會改動的,我們又設置了長緩存。對大部分用戶來說,這個文件是會使用緩存的,如果我們把這3個文件突然改成合併載入,所有用戶都會重新下載這部分文件,浪費流量啊,浪費流量就是浪費錢。
2)說說發表框的文件 3個
這些文件可不可以合呢,從抓包可以看出,其實我是合了的。為什麼是3個而不是1個呢?因為合成1個url就太長了,超出老ie的限制,就要報錯。沒辦法,拆成3個。那為什麼不低版本ie 3個請求,新版本瀏覽器1個請求呢?有些其他原因,這裡不好說
3)個人中心的各種模塊 8個文件
這裡的合併沒做好,從長度上來說,可以減少到3到4個請求,這裡有優化空間
4)音樂播放器文件 3個
這裡也有優化空間,不多說啦
5)評論框的文件 20個
這個可以合併一下,為什麼之前不合併呢?要講好長一個故事,題主估計也不想聽,不廢話啦
6)其他接入的團隊的文件 11個
合不合呢?我也想合,待我去問問
7)/qzone/mall/目錄文件 6個
有個基礎庫重複載入啦,慚愧慚愧。其他的代碼都是一些功能模塊,可以合併么?也可以,不過這些模塊進某些頁面時用,有些頁面時不用,而且不是首屏的功能,多幾個請求對體驗的影響不大。總的來說,合也可,不合也可。
8)/qzone/photo/目錄文件 8個
這個目錄的文件倒是可以把請求合併一下,預計可以減少到3 到4個請求。
9)又是一堆功能模塊 37個
這裡也可以優化,預計可以減少到8個以內
10)3個配置文件
可以合,不過合併後,1個文件變更會導致其他文件也重新下載,性價比不高。而且這些文件並不會在第一屏載入。合不合對體驗的影響不大。
綜上,預計優化後總請求數在40個以內。還有優化空間的,我們也可以再探討
2.對最高贊的匿名用戶(請原諒,你匿名了,我只能這樣稱呼你了)提出的問題稍微解釋下:
1)有些文件沒混淆,有些文件混淆了。
為什麼呢?我們是在發布系統上做的壓縮混淆。最開始是指做壓縮,不做混淆的。在某個時間點才開啟了混淆。只要在那個時間點之後發布的文件,就是做過混淆的。我的看法是,如果經常改的文件,下次修改發布後,自然就混淆了。如果不是經常改的文件,有沒有必要去混淆呢?得看收益了
那舊文件要不要去混淆呢?我們找個文件分析一下吧。
以這個文件為例:
http://qzonestyle.gtimg.cn/qzone/photo/v7/js/lib/photo.js
原始文件大小:136K
只去注釋換行空格,開啟gzip,大小:21k
去注釋換行混淆,開啟gzip,大小:19k
以上的結果可以看出,做不做混淆,對一個136k的文件來說,影響在2k。
我們當時的策略是:對cdn上流量較大的文件,重新發布一遍,做混淆。流量小的,就等到下個版本發布時就混淆。一直等不到下個版本的,流量又小的,就不管了。
你又可能會問:把所有舊代碼發布一遍,很麻煩么?發布不麻煩,麻煩的是,有些舊代碼過不了gcc simple級別的壓縮,重新發布一遍(上萬個文件),意味著發布的時候得花很多時間去改舊代碼。時間就耗進去,需求不做了么?不做需求,那麼還要不要領工資呢?不領工資,回家老婆要買驢牌,孩子要學跳舞,這些都要錢啊!面對現實,還是忍了
2)中英文混搭
中英文混搭的地方確實很多,沒辦法,讀了這麼多年書,最對不起就是英文老師。不過你這個例子舉得不好,因為這裡的dianping指的就是大眾點評,如果我去改成英文什麼的,反而更影響了理解。
3)空if
這裡實在是慚愧,不解釋,接受打臉。
4)代碼審查的力度
這也是我想吐槽的,如果借這個機會能換的大家的重視,這臉打得值得。
感謝你能看到這裡。
最後的最後,題主和那位匿名的兄弟,如果有興趣,可以私信我,如果我們彼此能看上眼,可以來我們這裡試試。
20151117利益相關:作為一個剛離開空間前端團隊,現在已經不在騰訊的程序猿,我也來說兩句吧。
單從文件沒有合併,個別代碼沒有壓縮混淆就說這個團隊技術不行是有失偏薄的。雖然說肯定有不對的地方,但很多是歷史原因,目前沒有改進也不是一件天地不容的事。具體一些原因@雕兄 有提到。我這裡也想補充幾點:
1.我們是以用戶首屏可交互時間為考核標準,對這個指標的優化也簡直到了變態的程度.而文件合不合併不管對於用戶體驗還是考核標準來說多沒有多大的影響,所以之前一直是忽略了
2.文件數過多另外一個原因是預載入,在用戶空閑的時候就提前載入接下來可能要用到的模塊,這樣用戶在使用的時候就能快速打開了。(這個預載入邏輯也會分高峰和閑時決定執不執行,另外對於高峰時段,還有很多優雅降級的方案,比如圖片換小一個規格,大圖模式變小圖模式,部分模型改變載入策略等。額,好像扯遠了。
其實在這裡我更想說的是:QQ空間的前端技術絕對能算上國內領先水平!!
我們做個很多東西,但都沒有對外說,以至於大家覺得我們啥也沒幹,然後通過一些不好的地方,就說我們技術不行。實在令人寒心。
結合在空間這三年,我再說我們做的一些事情吧:
從12年7月入職騰訊實習,當時還在做朋友網,那時候已經在用seajs做模塊化,還內部做了一個構建工具,當時的構建工具已經具有這些功能:
1.自動把html模板編譯成Function寫到文件作為一個js模塊來使用
2.把多個js模塊合併到一個文件,還自動按文件路徑給模塊補id,實現跨項目公用文件(這個功能spm一直沒有提供,可能他們也沒這個需求吧)
3.監聽文件變化實時編譯
這個工具到現在也是用的很爽,最近webpack,fis3這些構建工具開始流行,而我們在12年就自己開發了一個啊。另外也提一下,在13年的時候大家都在說前端模板,比如artTemplate這些,都在說自己編譯性能好,其實早在12年我們就把模板在構建工具里預編譯了,要比么?
構建工具說完再說一下一些新技術的使用吧.Webp圖片壓縮技術到現在不知道有多少人了解,簡單說一下,就是通過Webp格式壓縮圖片,在同等質量的情況下體積比jgp圖片還小約30%.體積能減少這麼多無論從節省存儲空間,減低流量,減少用戶載入時間.
這麼好的技術肯定希望能儘快用起來.然後當時只有chrome瀏覽器支持,IE完全不支持,怎麼辦呢? IE的用戶比例還是大頭啊,當時google給的解決方案是把圖片通過Flash來顯示,一個頁面只有一張圖片還有,像空間動態一屏都是圖片如果要同時載入上十個flash肯定卡死,後來怎麼解決呢,我們還是通過flash去載入webp圖片,不過在flash裡面再把圖片轉成jpg格式,然後再轉成base64傳到頁面,不過IE8 base64編碼不能超過32k,怎麼破?直接在flash把圖片分割,傳回頁面後再用多個Img標籤把圖片合起來.至此,已經實現webp對IE8+的支持.哦,對了,做這個事情還是在13年初.
Webp說完再重點說一下Nodejs這邊應用吧:
12年的時候如果有聽說哪個公司把Node用在生產環境應該是一件不可思議的事吧。當時朋友網就用了兩台伺服器搭Node Server做了在線聊天和頁面直出的功能。要知道,那時Node還沒有cluster模塊,怎麼利用好伺服器多核環境呢?當時的做法是一個父進程監聽80,和cup數-1個子進程處理請求,父進程做任務分發實現負載均衡.(為什麼不用Nginx做分發?因為當時發現子進程突然無緣無故就掛掉了,所以又引入了心跳包機制,子進程沒10s發消息給父進程我還活在,如果過了10秒父進程沒收到心跳包就kill掉子進程重啟).
那時候還有一個比較嚴重的問題是內存泄露,不過當時沒有很好的內存分析工具,這個問題沒有得到很好的解決,不過這也沒有影響我們在生產環境中使用,有內存泄露,每天定時重啟一下就好.(內存泄露問題後面heapdump,memwatch工具出來之後得以徹底解決,並且把很多內存使用不合理的地方優化下來,比如長文本String改用buffer等)
有了Node做Sever之後,我們做了更多事情,就不細說了,點一下:
1.請求後台Sever要實現負載均衡,公司有一個L5的組件解決這個問題但沒有Node版的,怎麼辦?寫Node擴展
2.在虛擬機上內核數識別不對,最後定位到是Node的bug,讀的變數不對,改源碼解決
3.用Node在轉發請求,實現全站域名統一,快速解決跨域問題.實現HTTP 2.0 / SPDY
4.模塊錯誤在線實時監控
5.Node直接調用後台二進位介面,跟手機介面統一,大大減少後台工作量.
6.Node性能優化,通過v8性能分析工具發現require中用到正則,性能堪憂,通過優化後整體性能提升了5%,開始以為require有緩存就隨便寫,發現這個坑後,以後ruquire還是寫在最外層吧
說了這麼多也不是說空間的技術最牛,但國內領先肯定是說得上的.當然,因為產品形態的原因也不能所有技術都用上,比如現在一些流行的mvvm框架,對於空間這種頻繁交互的場景不太合適,不過facebook開源的react native之後,我們也開始去用React來開發Hybrid App
在這個團隊學到了很多東西.對這個團隊也是無限的感激.也非常推薦剛畢業,對技術有追求的同學加入這個團隊.
很久沒寫過這麼長的文字了,就作為離職的一個總結吧.作為空間web前端的現任司機,我也來說幾句,立場中立。
我是來回答標題的,但因剛發出來就回答得太快,問題更新幾波後,我的答案並沒有什麼鳥用,變成了現在這樣子:大家對著個PC頁面展開各種立場的討論。
首先,技術具有時效性。
去年大熱的離線包技術,放在今年講就沒有時效性,再過十年手機網速超過pc再提離線包我跟你急。
11年大熱的模塊化,今天也沒有時效性。
同理,08年大熱的js壓縮混效放在當下也沒有時效性。
技術點失去時效性,並不是說他就不重要了,只是代表著沒啥好討論的了。標準已經確立,是否遵循這個標準是各自的事,有的為了讓流程更規範落地了,有的因為價值不明顯沒的強制執行。
同樣PC web時效性也沒有了,現在很少看到大家在分享PC時代的成果。但這並不代表PC可以不管了,做得不好的承認並讓期變好。但團隊的關注點不會改變,移動端的web才是當下的王道。
時效性這一森林法則在產品上同樣適用,甚至放大到整個互聯網。
在公司內部也到處可見,如果在通道評審中,你拿一個過時的技術點講給評委,會被PK的很慘。公司內部某個框架或架構很好用,過幾年沒時效性可能就要被吐槽了。
那如何保持時效性呢,那就是迭代,快速的迭代。
大家所說的水平,大多來自這樣的評架:A用了個有時效的技術方案,B用了個過時效的技術方案。大家就會得出A比B水平高的結論。
那麼我們來看下空間web前端那些年在時效上的歷史,我是11年入職的,前面的不了解也就不說了。
11年,完成模塊化(鋪地板),同年啟動node.js與業務相結合的解決方案研究。
12年,前模板模編譯為模塊(鋪地板),原因是為了讓其能在node.js解決方案中直接復用
13年,相冊下載webp化,移動轉型
14年,完成前後端分離的開發模式(鋪地)
15前半年,提出server web開發理念,打通運維和後台二進位協議,整個空間的移動web接入層由前端開發接管,新項目已經沒有cgi層,前端開發成為域名收割者。
15後半年,接入層收歸到前端後的各種工具層出不窮,基於qq號的測試環境,基於qq號的接入層染色+抓包,首屏直出+離線+diff。
15年是移動web飛速發展的一年,間接導致服務端web的崛起,時效性的標誌。
當年我們大力投入node.js但效果甚微的時候,也懷疑過自己的方向是否正確,被質疑是為了node.js而node.js。士氣低落時,被黃老師吊了一句「node.js在公司如果不火,那就是你的責任。」
然後重新思考,即然方向沒錯,那問題出在哪。才發現,太超前也會失去時效性。然後繼續研究node.js,等待時效來臨。當然也不是乾等,而是打通公司內部各種系統,各緯度缺失的能力補齊,狂更新node版本。這個時期,對內分享都很少。
然後,今年火了,node.js在首屏性能優化,新項目接入層,登錄態隔離,域名收歸,安全打擊,https-spdy上都獲得認可。
意識到時效性來了後,當然不會藏著噎著。
通道能力模型修訂加入伺服器端web開發標準,對公司內web前端兄弟們來說又開啟一個新的領域。
在運維,後台開發,測試等角色也不斷提升對node開發工作的認可。畢竟老大認可了你才敢用吧?
下一個有時效性的技術點,大概就是react組件化了,時間點反正不在今年。
所以這個問題很火就是因為大家都假裝有時效性然後狂討論的結果。彷彿一夜回到了PC WEB時代一樣。
-------------------------------------------
空間移動web接入層全部構建在node.js之上,web前端已經從瀏覽器時代演進到server web,移動互聯網時代應該討論點移動web才有意義。現在才來寫點啥是不是晚了。。。
看到stone,子舜都被引出來還是勾起很多回憶。。。
雕兄和lv的回答也很贊,友昆作為現任掌門人請繼續加油吧,支持你
單純先說下題主的問題,首先說的都是對的,必須認同
其實這些道理都知道,為啥沒有執行,我想通過後面的講故事的方式來解釋,說找借口也可以,確實作為空間前端老年人代表要來講講,不說不痛快
Qzone開始有大量前端邏輯始於2006年4月左右,作為到現在為止還在大量使用C/C++基於自建web server框架進行CGI bin實現web開發的公司,在中國乃至全世界都是獨樹一幟,2006年4月,Qzone剛剛因為要解決CGI過重導致的web接入層性能瓶頸(當然不止這個瓶頸,用戶增長速度當時達到日增80萬且100%留存活躍)做過一輪重構,那可能是國內業界第一次百萬用戶量以上的web業務做完全的動靜分離架構,web接入層完全成為RESTful的data setter/getter,所有的表現邏輯都由web前端繪畫出來,包括首次打開,整個頁面也是用js DOM API一坨坨畫出來的。雖然丑而極端,但確實第一次極大解放了後端集群的壓力(大量的業務邏輯計算和展現模版計算開始去消耗用戶設備的資源),對於一個月內用戶量從50萬暴增到300萬的、工程師(重構前不分前後端)加運維(當時也沒有D/O分離)一共才11人的team,已經是最快的方案,當時負責前端開發工作的人員只有兩人,純前端項目的規模應該在5萬行的樣子(雖然前端都不喜歡這麼估,但考慮到和後端項目對標,姑且這樣吧)
自此之後,直到2011年前,Qzone的前後端架構分界沒有重大變化,前端工程師幾乎承擔60%+的業務邏輯維護工作,特別要提一下Qzone前端工程師的工作內容,除了和產品經理tradeoff需求外並實施外,所有用戶投訴(當然包括老闆投訴,5個大老闆從早晨9點到凌晨2點的各種輪番問題反饋,不是怪罪老闆,這樣的老闆真的能讓團隊成長很快)的受理和初步定位(遇到網路質量衍生的一系列問題要自己出方案規避,而不是丟給運維了事),公司級漏洞防禦規約(公司最大的web ugc平台的責任),自己實現業務的前端監控(頁面自測速、前後端公網調用成功率、用戶機器負載等)以及持續優化,公司自建CDN的持續迭代優化建議,前後端介面統一規範的開發維護(CGI模版的維護哦,比神馬php,python之類的麻煩多了),在後端整體做異地分布的時候,整體域名規劃、同步延遲消臟方案全部洞穿到前端,由純前端業務架構師規劃,當然還有複雜flash項目(照片上傳組建、農牧場整體前端構建等)。這一切都是在一個不到40人的前端team進行,對口產品和運營超過60人,業務規模3000萬(半小時AU,不是DAU),2011年數據。
2012年開始,其實Qzone的Desktop Web版本(也就是PC版啦)所有的重心開始偏向移動端開發,大量的web前端hc被縮減,現有團隊成員很多響應公司號召轉去mobile native開發。如果一定要看下web前端技術,可以模擬移動瀏覽環境開一下http://qzone.com瞅瞅,順便提一下,那後面都是nodejs,也是個接近千萬日活的業務。
2007年大概7月,qzfl這貨有了,當時jQ不成器,prototype、dojo、ext之類的又實在不適合,所以才自己搞了個qzfl,確實作為開發框架,裡面有些劃分不合理,比如耦合了一部分為qzone體驗高度定製的dragdrop引擎(雖然沒有耦合業務邏輯,但其實不算變成框架的必要部分)。但qzfl裡面還是有些亮點的,比如用documentFragment做根容器來get jsonp,不需要用前後端傳參數的方式防止callback function name衝突(後來有個叫adv的傢伙,通過控制毫秒級時序隊列,更好的做到了同名隔離,純粹從思想上來講,算是js在客戶端平台上的微線程實現吧);還有個叫jsLoader的貨,其實可以說是誕生很早的模塊化載入器;
2012年初在做news feeds前端模版引擎優化的時候,在後端開始嘗試了虛擬DOM的概念(Qzone內部團隊分成平台和UGC,平台news feeds幫助業務更方便的在首屏以各種花式曝光),現在看看也算是類React的東東吧,其實2012年大量web前端轉app native開發的時候我們就說過:"矽谷是人最貴的地方,不可能每個公司都搞平行的android/ios/win phone / web 幾坨人馬,養不起,一定會在矽谷誕生基於web開發native構建+運行時的方案",果然fb的react後來就出來了。。。 騰訊是一家非常業務導向的公司,在一個業務團隊,絕對不可能給你充足的人力空間搞純技術項目,大量的基礎建設都是大家用很多OT堆起來的。如果當時可以有一個5~10人的泛前端(native前端+web前端)team一起研究,做個基於jsc的類似react的engin並不是不可能。當然,馬後炮沒鳥用,不說也罷
2011年開始,朋友網前端團隊(朋友網和Qzone同屬一個部門,社交平台部)已經開始較多嘗試nodejs,朋友網相對Qzone來說用戶群較為集中且相對高端,低端老舊客戶端運行環境很少,因此是非常好的開源新技術組件實施田,朋友網的前端團隊把很多不成熟的開源項目本地化並進行了很多有意義的優化。上文部分同學說的模版compile,可比jade的這個能力早了很多,到2013年的時候,nodejs已經在Qzone相冊,觸屏站等場景大量使用。。。全都是超大規模的web業務
現在回頭想想,其實很多事情沒做好,最大的問題還是缺人;Qzone前端開發團隊人數最多的時候不超過50人(產品經理和運營共100人的時候,大家都知道運營需求最費前端)鵝廠不同於阿里,對前端技術通道的誤解更深,很多業務線其實都沒有組織架構上正式的前端團隊,也有大量業務的前端團隊由後端開發leader領軍,如今想來也是唏噓一場話說我在三年前回復過一個類似的問題: 騰訊的在線人數動態圖是在技術上是如何實現的? - Adobe Flash
記得當時得票數最多的一個回答貼了好幾張圖來證明數據數據造假,當時貌似有上百個贊(當時還是蠻多的)。經過一番討論後,回答者就把答案給刪了。沒想到過了幾年又遇到類似的問題了……
——————————————————————————————————
首先回答下提問者的問題:「前端性能優化原則難道不是盡量合併請求嗎?」。是的,確實是盡量合併就合併。但是這個是有一定歷史原因的,因為以前ie 6有並發限制,再加上計算機硬體也不怎麼地,而且以前也沒AMD和CMD等模塊載入規範(當時最牛的應該就是yui的模塊載入了),所以合併起來確實是最好的解決方案。但是,隨著遊覽器和硬體的升級,再加上網路越來越好,而且前端項目越來越複雜,這個確實不是太重要的點了(但是並非是不重要)。
其次針對QQ空間的問題,QQ空間真的沒有合併和混淆文件嗎?
那這是什麼?CDN文件合併不會不知道吧
那這是什麼?有用過seaj的的同學應該很清楚這個是什麼吧(這裡補充說明下,空間這邊在發布前就會有一套工具把零散的模塊進行合併)
那位至今不願意露臉的匿名同學提到這裡有問題,可能是不太清楚Seajs的模塊打包方法,這句話的意思不是把jQuery打包進來了,而是把括弧裡面這些子模塊打包進來了。
只有空間沒有混淆文件嗎?
https://www.taobao.com//home/js/pwdintensity.js
再回到問題來,為什麼還是有這麼多請求?
簡單講,空間不是一個簡單的頁面,裡面有各種模塊。除了核心體驗的模塊是「同步拉取」(其實也是非同步拉取的,只是這些文件是強依賴)的,其他模塊都是非同步拉取的。
這是什麼意思呢?對於用戶來講,就是能讓你在最快的時間內進行核心操作,但是一些非核心操作(如數據上報啊、還有其他非核心功能),都是在之後拉取的。其實這個也是空間這邊技術的主要優化點,為的就是不僅僅依靠性能數據,而是根據用戶的實際體驗來衡量(就是讓你在最快的時間內能夠進行操作)。
覺得我在胡扯?那看下下面這個facebook的請求截圖,一共是79個。而且facebook可沒有空間那麼多增值的功能。
這麼多請求是不是真的讓我使用起來比較卡?
把flash先關下再試試?話說由於兼容性需要,空間很多功能都是用flash實現的,flash那些眾所周知的問題就不提了。之前聽老大說有逐步推進用HTML5替代的計劃,但是由於我不是負責這方面業務的,所以具體的進度我也不太清楚。
如果我還是覺得慢咋辦?
點右上角那個綠色的東東
最後再說下關於壓縮和混淆的問題,其實現在的存儲和帶寬成本和幾年前相比真的很低了,壓縮確實可以減少文件大小,但是想想真的有那麼重要嗎?很多時候大家都把做其他一些東西的思維移植到前端,像我剛剛工作時,一個完全不懂前端的領導讓我把代碼壓縮混淆,並且很鄭重的說不這樣做會導致代碼泄漏問題。但是說個實話,只要你代碼在遊覽器端跑,我肯定是有辦法讀出你的邏輯的。當然,我並不是說壓縮和混淆不重要,只是覺得沒有必要過於鑽牛角尖。或許以後真的會有一套規範來定義JS文件的壓縮和加密,但是肯定不是現在簡單的壓縮混淆就可以做到的。
就像如果你是程序類面試官,你會因為一個人不剪指甲就不給他offer嗎?
很多人,為了彰顯自己的能力,總是喜歡挑戰權威,但是技術這東西是很嚴謹的,你看了一篇文章說XX好,可是不根據實際情況就把這點套用到任何地方,真心不是一名合格的技術人員應有的表現。
對了,前面那位匿名同學說要向淘寶學習,其實技術本來就是相互學習的。謝kelen邀。看到有一些同學已經回答的的內容就不重複了,現在我也不負責QQ空間的前端,說一點點個人的觀點吧。
1 前端技術好不好,應該是有相對客觀的標準的:用戶體驗說了算。當然也不是說平均測速數據壓倒一切,很多時候「最差的10%的用戶感受有多差」是一個更重要的指標,因為對產品的抱怨幾乎都來自於體驗最差的用戶,所以需要對他們做更多的關注。這有的時候也會導致技術實現者不一定選擇對於平均用戶體驗最佳的方案,比如說不一定要把文件合併做到極致,所有的腳本都合併成一個。
2 當然js文件數過多還是要反對的,雖然我並沒有看到題主說的100多個js請求(估計跳轉了幾個頁面後抓的包在一起統計,或者有一些http://user.qzone.qq.com域名下的json被混進去了?或者裝扮不同帶來的差異?)但是確實有一些小js應該考慮合併請求。
特別指出,合併腳本請求並不是合併腳本文件,我們使用的cdn有合併多個文件到一個請求中的功能。比如 http://ctc.qzonestyle.gtimg.cn/c/=/qzone/v8/dress/xextend.js,/qzone/v8/dress/data.js,/qzone/v8/dress/viewbase.js,/qzone/v8/dress/dditem.js,/qzone/v8/dress/menuview_v8.js,/qzone/v8/dress/weather.js,/qzone/v8/dress/visitors.js 這樣的。因此以前我們常常會在一些特性發布的初期把代碼放在獨立的小文件裡面,等成熟後改為合併請求方式。
3 前端js不壓縮不混淆是我比較堅持的原則,雖然現在前端團隊不見得還堅持這一點。這並不只是「為了線上測試方便」,當然我也很樂於看到這個方便。
不建議壓縮的原因是,實際上在網路下發的時候我們是統一做gzip壓縮的,大部分的數據冗餘在這個時候去掉了,對代碼做壓縮後再gzip跟直接gzip的差異並不大。
不建議做混淆的原因是,對信息加密史略有了解的人都知道,公開的加密演算法比秘密的加密演算法更安全。代碼也類似,容易讀的代碼對於開發者和白帽子更容易發現問題,而只要找到代碼漏洞是有利可圖的,黑客並不太在乎你的代碼是否做過混淆。
此外一些加密和混淆方式還需要在客戶端做額外的還原計算,這樣就不是優化而是劣化了。
因此我繼續呼籲大家不要在沒有監控數據支持的情況下做這類「看起來似乎有效果」的優化。
3 回應一下上面某匿名兄提出的拼音是什麼鬼的問題。 從貼出的代碼山觀看「dianping」其實是一個字元串常量賦給了wihtelist白名單變數,應該是指的一個大家夠知道的域名。多數情況下我們還是要求代碼採用英文和英文縮寫方式的,當然不排除有一些地方有歷史痕迹或者有新人帶入,還好大部分代碼並沒有做混淆(混淆的代碼我希望換成不混淆的版本),所以歡迎大家review和指出。線上代碼如何並不直接反應團隊技術水準,這個在大公司干過的應該都懂,不信你們去看看新浪博客的前端js,那代碼是04年的時候做的架構,就不說有多nb了,放到現在一些公司也是做不到的,但是博客現在基本已經毀了,這並不是技術能控制的,產品不ok,技術沒辦法發力,很多事情沒有契機去做,比如優化,大改版,技術升級等。因為產品過於複雜,很多新人不敢動老代碼,歷史問題等,鐵打的營盤流水的前端,誰care呢。
所以看了很多qq空間的技術說了一些問題,我體會也很深,有時候有些項目,真的身不由己,技術選型一開始很重要,但是10年前的產品的選型必然和今天主流不一致,但這並不能說明技術團隊技術不行.
緩存利用根據流量峰值做不同策略的嘗試,我在10年就知道騰訊在做,這個也是qq空間團隊主導的,10年啊,不吹不黑,當時淘寶和現在的淘寶應該都沒有做起來。騰訊的Qzone前端團隊和QQ前端團隊可以說是代表著整個騰訊的最高水平了。
就是產品弱了點。
QQ空間的前端技術水平如何?
QQ空間曾經是騰訊最大的前端團隊(大的還有AlloyTeam、廣研的郵箱團隊等等等),在前端這個詞還沒出現的時候就已經開始了細緻的瀏覽器端分工,設立了公司的前端技術通道,必須是挺牛的,只是個人認為公司對外分享的氛圍太低調了,不夠開放,感覺對業界的貢獻不夠多。
只是打開Qzone首頁(我的動態),滑鼠沒有移動到屏幕的任何元素上,也沒有進行任何點擊,就有295個請求,圖片就不說,很合理,但是卻載入了114個JavaScript文件。前端性能優化原則難道不是盡量合併請求嗎?
架構的水平,初級是看是否符合規則,到了出神入化的境界,就要考慮怎麼靈活組合,甚至是打破規則。有句話怎麼說來的,「規則就是用來打破的,前提是你了解他」。
# 就這裡的例子來說,按指導原則,合併請求絕逼是沒有錯的呀,可再這麼巨大的產品面前(減少資源請求是另外一個重要的原則,只是堆砌的內容確實太多了),首屏的東西誰都不少,考慮過把114個JavaScript合併成一個是什麼後果么??打開頁面後看著一個空白的頁面,等待一個幾M的js下載完成會是什麼心情。這種情景下怎麼做合理一些呢,首頁的框架html直出,你可以看到第一頁的內容,然後各種模塊的js組件在後台lazyload,等待下次要用的時候不用臨時再去下載。(PS:吐槽流量的同學,你們在用4G上PC么,哈哈哈。移動端對流量的優化也蠻極致的,強網路tcp鏈接確保速度,若網路html鏈接確保可用,不同場景屏幕大小載入的圖片size也分好幾個規格)
# 說到打破規則,還有個例子。有一條規則是將CDN、CGI請求等分給適量的不同域名,這樣子可以是瀏覽器開啟更多的並發下載。PC版的空間也是這麼搞的,後來到移動端解析域名的DNS消耗之巨大,以及下載網速之緩慢,多域名反而成了劣勢。
# 說到lazyload,想起黃老師(這裡說的是stone老師)講的農場的一個優化案例。那時候大家網速都比較慢啦,下個flash資源也要不少時間,大家偷菜種菜的時間晚上8-9點是高峰,不光大家家裡慢,高峰期的時候伺服器壓力也很大,而且公司跟運營商買的帶寬是按峰值算的,平常大家睡覺的時候白白的浪費銀子啊,後來根據用戶是否是農場用戶的屬性,在網路空閑階段提前把農場的資源下載下來緩存,大家玩的也爽,伺服器也爽,老闆也爽,反正就是各種爽。
-----------------------------------
# 上邊匿名同學從代碼看出來的問題也是實際存在的,但更多的是技術管理方面或者產品形態方面,不能片面的否認團隊的技術能力(同學們也要加油啊)。空間的技術團隊遵循」互聯網產品「的」速度是一切,勇於試錯「的指導思想,一天跟著產品需求可以發很多個大版本,難免會有些浮躁,沒有很好的環境沉下心來寫框架級別的東西,當然要想寫也沒人攔得住的,requirejs剛流行那會兒也有同學搞出來輕量的類似框架,只是沒用起來。這點和淘寶的同學比起來,商品展示支付相關的頁面更看重模塊的穩定和復用性,可以一周發一次版本,有更多精力打磨框架。
產品本身問題很多,有同學打比方,QZone的代碼就像一個陳年的破車,打滿了各種補丁,可居然還沒事兒一樣跑著……
# 至於混淆什麼的,他的好處是增加代碼閱讀的困難,如果不是敏感代碼,當真無所謂,感興趣可以看一下登錄模塊的代碼,這裡是混淆了的。如果考慮到流量什麼的話,同時開啟gzip壓縮的情況,兩種方式基本上沒有區別。
---------------------------PS ,11年加入空間團隊,和當時前輩們學了很多,很感激。現在雖已離開,很懷念……
據說很叼,至少在騰訊內部是頂尖的存在
看到這裡,忍不住想截圖給黃老師看,qq空間唯一前台技術專家。然後黃師兄,果然上來了。坐等帖子上前排。
路過
好奇看下
果然真多
其實說白了就是沒合併
其他都是借口
如果重視合併這塊兒
肯定會做的
但是不同公司細部指標不同
比如一般公司會有幾個指標
首屏啊 onload 什麼首次可交互時間啊
如果合了
前頭載入內容多且大
那麼 load 指標肯定會不好看
刷幾次
load 值驚人的小啊
1.2 秒左右呢
對比下號稱用了bigpipe什麼牛逼技術的微博
都快15秒了好不好!
差了10倍以上呢
所以你懂的少年
用戶能看見東西
首屏什麼指標就達到了
KPI也就有了
其他什麼js非同步的文件多不多
並不重要
要是指標不好看
KPI 達不到了
獎金就木有了
一切得按照別拖慢load啊首屏啊什麼指標
作為優先條件
這叫做載入指標優化
技術高的表現啊
當然人家自己肯定不會這麼說了
怎麼也得扯扯技術上的原因
歷史上的原因什麼的
省腦子
捫心自問一下,在國內的所謂大公司做純粹的前端有啥牛逼不牛逼的,又沒人願意研究瀏覽器或者勵志寫個瀏覽器。都是在應用層面堆砌產品邏輯,只是有人在堆砌的時候用了一下前端的奇技淫巧。所以我認為不要講你技術多流弊,而應該聚焦你的技術解決了什麼應用問題,好吧?都是應用層面的工程師就莫裝逼。前端童鞋普遍喜新厭舊,今天gulp,明天es6、webpack。也不要因為你多超前就鄙視一切,這些又不是我們貢獻的,你我也只是用戶,保持學習先進的東西永遠沒錯,然而不探究其思想到頭來就是學了一堆明天可能就過時的垃圾。個人認為一個人做前端到後面一定是要橫向到其他領域的,後端node, redis,mongodb感覺都是為前端工程師量身定製的,還有微信的jsapi讓前端可以很快速得搭起自己的移動app,或者樹莓派,nodemcu(一款可以用類js的語法控制針腳的開發板)來搭建自己的物聯app。一句話前端應用層面沒有牛逼的技術,都只是在瀏覽器的api體系下搭建自己的應用,前端童鞋應該保持的精氣神應該是以前端為制高點像各個領域滲透。說糙一點就是作死的折騰。
全棧前端狗路過,很早之前,其實就是幾天前,看膩了淘寶前端流程工程化……於是乎,突然想起很久很久以前助我築基的扣扣空間看看有沒有變化(是的,我的前端成長有很多看的是空間源碼!)相信很多前端初入門都是被好像很厲害的樣子的狂拽酷帥屌炸天的扣扣空間特效吸引。那時候扣扣空間的源碼確實如贊數最多的哥們索的,沒有打包壓縮。然後前幾天回過來一看,發現居然有了打包壓縮,然而老的代碼依然是原樣估計是懶得動了吧……所以扣扣空間的前端直接反映了扣扣前端團隊技術選型,前端工程化,代碼規範由無到有的一過程……
這樣子問法未免過於教條主義了,也片面。qq空間早已龐大得無法,別說一個組,甚至是一個部門的人能看透的。是,有些文件沒混淆,是,請求是多了。so what?並不能說明前端技術什麼什麼的。技巧不是說存在就應該完全應用上,很多時候都應該以能切實解決某個問題為主。
我只想說,請求多少都不能一概而論,你不能說一個請求就是最好的,也不能說100多個請求是好的,需要分情況。
請求多的優勢:
1. 多個請求便於緩存。特別是大型的網站,假設整個網站有 100 個分散的 JS 組件,頁面 A 用了 80 個,頁面 B 用了 60 個,其中 B 跟 A 不同的組件有 20 個。那麼用戶訪問了頁面 A,載入慢了點,再訪問頁面 B,只需要請求 20 個組件即可。那麼再訪問頁面 C,幾乎不需要載入多少組建了,因為所有的 100 個組件都緩存下來了。舉個合併在一起的反例,淘寶的 CDN 有 combo 功能,即可通過 CDN 將多個組件拼接合成一個大 JS 文件。那麼 A 頁面用了 80 個組件,合成一個 1M 的 JS,緩存在了本地。B 頁面用了 79 個組件,由於跟 A 頁面 url 不同,還是會重新載入一遍。
2. 多個請求便於逐步載入。比如首屏或者部分區塊的優先載入等,防止用戶等待時間太久。
3. PC 端網路不會太差,多個請求不會太慢。
請求少的優勢:
1. 節約 HTTP 連接的損耗,但是 HTTP/2 會很好的解決這個問題。
2. 降低請求數量,節省伺服器資源。
3. 沒了。
4. 適用於移動端。
題主去看看騰訊的朋友網吧,真的爛到不行
瀉藥。
其實題主@一下空間的開發來回答會更加好點。
===================================
不過還是說下我知道的一些東西。
因為前公司的技術老大是QQ空間後台的開發,所以請來了一位空間的前端(或者說全棧吧)工程師來分享空間的前端技術。在準備分享前,肯定要去了解下空間的技術什麼的,很簡單,就是用chrome打開開發者工具嘛,看下源碼什麼的,再看下請求什麼的。
然後在回答這個問題前,我再次看了一下。
技術點有幾個還是很容易看出來的:
1、模塊化(seajs)
2、combo
其他的什麼gzip、cdn這些大公司是不在話下的了。
上面說了下我看出來的東西。那空間牛逼不牛逼?
必須牛逼!當時我公司網站做模塊化,然後看到空間用了seajs,就問了下具體的情況。隱約記得當時空間的前端說也是前兩年才給空間轉到了模塊化,幾個人做了幾個月(錯了別噴我,我只是大約記得)。其實作為一個這麼老牌的網站,而且功能那麼多,模塊那麼多,接入各種第三方內容那麼多,做好真不容易,要轉一套架構更加是不容易。起碼對於在小公司的我,看起來是多麼的了不起,哈哈。
據我所知騰訊是 html+css 和 js 分開,前者結合設計走設計師U序列,後者走工程師T序列, qq 空間應該是 isux 負責的,團隊博客: 騰訊ISUX – 社交用戶體驗設計 偏重設計,js 這塊代表應該是 AlloyTeam:Web前端 騰訊AlloyTeam Blog
看得出兩個博客風格明顯就是設計師和工程師的典型區別了:)
技術上沒怎麼接觸 qzone, 但 alloyeTeam 博客以及開源的東西確實讓人覺得很牛逼。
ps:至於 js 要不要混淆不是什麼槽點,有線上排查問題便利性等多方因素的權衡在內;推薦閱讀:
※有哪些新手程序員不知道的小技巧?
※知乎上有哪些在前端開發領域的高質量回答?
※為什麼維基百科的用戶界面設計不夠友好?
※為什麼很難聘到前端工程師?