- 相關(guān)推薦
有關(guān)淘寶首頁(yè)的基礎知識
很多人都用淘寶,但是對淘寶首頁(yè)并不了解,小編這里帶來(lái)一位淘寶首頁(yè)的設計師的講解,希望可以讓你對淘寶首頁(yè)有一個(gè)基本的認識。
一、相關(guān)背景介紹
淘寶首頁(yè)是淘寶的門(mén)面,承載著(zhù)幾乎淘系所有業(yè)務(wù)的入口,流量很大,量級單位為億。近幾年無(wú)線(xiàn)端崛起,業(yè)務(wù)重點(diǎn)開(kāi)始向無(wú)線(xiàn)終端偏移(目前不能叫偏移,基本以無(wú)線(xiàn)為主了),所以淘寶 PC 端首頁(yè)的流量也有削減,不過(guò)即便如此,它的日均 PV 依然相當高。
淘寶首頁(yè)一向是內部平臺和技術(shù)的試驗田,它一直在變化著(zhù)。最新的框架和系統都會(huì )找淘寶首頁(yè)試點(diǎn),可以試想下,如果某一項需要推動(dòng)的升級或者優(yōu)化措施在淘寶首頁(yè)已經(jīng)上線(xiàn),并且拿到了良好的數據和穩定性,其他業(yè)務(wù)還有什么理由不去嘗試和更迭呢?同時(shí),去年一年身在淘寶前端的技術(shù)架構組,自然而然也會(huì )主動(dòng)去 push 一些實(shí)驗性的內容到業(yè)務(wù)上。
淘系的站點(diǎn)頁(yè)面包括首頁(yè)、其他頻道頁(yè)和活動(dòng)頁(yè)等,這些頁(yè)面并不都由淘寶前端一行一行的代碼碼出來(lái),業(yè)務(wù)如此之多,這種玩法即便人數 double 也忙不過(guò)來(lái)。事實(shí)上,大多數頁(yè)面都是依托內部的搭建平臺——運營(yíng)或者前端通過(guò)模塊搭建的方式——構建的,而前端 focus 的重點(diǎn)在于搭建平臺的建設自身以及模塊的通用性和復用率的保障,當然,還有一些工程化的東西。
使用搭建平臺搭建的頁(yè)面,前端只需要考慮組成頁(yè)面的原子模塊的開(kāi)發(fā),整體的渲染由搭建平臺提供的統一腳本全權負責。而在淘寶首頁(yè)上,考慮到頁(yè)面模塊數量巨多,加上還有少量跨部門(mén)、跨團隊的溝通,渲染模型略微不同。
二、淘寶首頁(yè)的整體變遷
背景中提到,淘寶首頁(yè)依托于內部搭建平臺,它的變遷自然也是跟著(zhù)搭建系統的變化而變化的。
1、PHP 下的淘寶首頁(yè)
接手淘寶首頁(yè)不久,便遇到了一年一度的改版,那時(shí)它還運行在 PHP 環(huán)境中。這里需要說(shuō)明的是,淘寶首頁(yè)的所有代碼完全由前端掌控,前端不會(huì )直接跟數據庫打交道,其數據來(lái)源分為兩部分。
數據來(lái)源
一是運營(yíng)填寫(xiě)的數據。 采用前端挖坑的形式,預留坑位讓運營(yíng)獲取填寫(xiě)數據,
運營(yíng)填寫(xiě)這些坑位就會(huì )產(chǎn)生這份 PHP 模板對應的數據,最后渲染出來(lái)就是一個(gè)完整的 HTML 片段(實(shí)時(shí)性渲染)。
舊版搭建系統中就是通過(guò)這種方式構造一個(gè)子模塊。我描述得十分簡(jiǎn)單,但作為一個(gè)平臺它需要考慮的東西還有很多,比如數據順序的控制、定時(shí)發(fā)布、回滾機制、過(guò)濾機制、篩選機制、數據的同步、數據的更新、版本控制、權限控制、其他系統的引用等等。
二是后端或者個(gè)性化平臺提供的數據。 不同的業(yè)務(wù)有不同的訴求。一些業(yè)務(wù)有自己的后端,他們要求使用自己業(yè)務(wù)產(chǎn)出的數據;有的業(yè)務(wù)希望用戶(hù)看到的內容不一樣,千人千面,期望接入算法;一些業(yè)務(wù)跟賣(mài)家直接打交道,期望使用招商數據;而有些業(yè)務(wù)期望采用運營(yíng)從數據池篩選出來(lái)的數據……總之,淘寶首頁(yè)需要對接形形色色的系統,接口繁多。后面會(huì )提到對動(dòng)態(tài)數據源的整合。
并且這些系統對應的域名是不一樣的,JSONP 格式自然也就成了首選。但一些特殊的系統,比如廣告,它的渲染并不是一個(gè)簡(jiǎn)單的 JSONP 請求,可能它還要干預整個(gè)廣告的渲染流程,比如加載他們的 JS,把渲染的控制權交過(guò)去。
頁(yè)面的架構
上面介紹了數據的來(lái)源和子模塊的結構,那么整個(gè)頁(yè)面又是如何構成的呢?模塊的搭建分為兩種,一種是可視化搭建,運營(yíng)或者前端可以將開(kāi)發(fā)好的模塊(或者模塊庫中選取的模塊)拖拽到容器內,形成一個(gè)頁(yè)面:
當然,上圖也只是一個(gè)模型,作為一個(gè)系統需要考慮的問(wèn)題還有很多很多,如頁(yè)面的布局、多終端適配、模塊的臨時(shí)隱藏、位置調整、皮膚選擇、模塊的復制等等。
通過(guò)模塊 id 將模塊引入,并且添加一些類(lèi)似 lazyload 的標記,方便控制渲染節奏和數據入口。源碼搭建和模塊搭建的區別在于,前者更易于控制模塊的結構以及模塊的渲染順序。
動(dòng)態(tài)數據源
首頁(yè)面對一大堆接口和平臺,對接幾十個(gè)業(yè)務(wù)方,接口是個(gè)很大的問(wèn)題,由于后臺系統的差異,基本沒(méi)有辦法統一數據源的格式,一旦運營(yíng)哪天心血來(lái)潮要換一個(gè)他自己覺(jué)得用的更爽的或者數據更好的系統,前后端估計又得溝通和對接幾次。
平臺具備數據源接入的能力,也就是說(shuō)我們挖的坑不僅僅可以讓運營(yíng)填數據,還可以從各種數據源中直接導入數據,當然,這里需要進(jìn)行一次數據字段的映射轉換。
綁定之后,數據既可以同步輸出,也可以異步輸出,這些都是平臺提供的能力。這個(gè)方案基本上解決了后端系統/接口變化的問(wèn)題,并且減少了前后端之間的溝通成本。
不過(guò)這里需要注意的是,雖然頁(yè)面上的接口都通過(guò)平臺統一梳理了一次,這也意味著(zhù),頁(yè)面所有的請求會(huì )先流經(jīng)平臺,然后分發(fā)到各個(gè)后端,平臺的抗壓能力要求很高。
2、PHP 到 Node 的變遷
淘寶首頁(yè)日均請求的這個(gè)量級,不可能是十幾二十臺臺服務(wù)器抗得住的,支撐它必須有一個(gè)服務(wù)集群。
每一個(gè) CDN 節點(diǎn)上都具備 PHP 渲染的能力,當頁(yè)面發(fā)布時(shí),我們把該頁(yè)面所有的模塊和數據同步到全部 CDN 節點(diǎn)上,基本模式大概就是如此了?雌饋(lái)還挺不錯,但是經(jīng)過(guò)一段時(shí)間的運維,很多安全、性能問(wèn)題都慢慢浮現出來(lái)了:
性能問(wèn)題。 每個(gè) PHP 頁(yè)面包含多個(gè)子模塊,而子模塊也有可能引用了其他的子模塊,PHP 的 include 操作是存在消耗的,每一次引用都是一次磁盤(pán) IO,一個(gè)渲染節點(diǎn)上跑了成千上萬(wàn)個(gè)類(lèi)似淘寶首頁(yè)的 PHP 頁(yè)面,并發(fā)一高其效率可想而知。
推送機制問(wèn)題。 文件同步是一種比較惡心的機制。首先,時(shí)間上沒(méi)法控制,一個(gè)文件同步到所有的節點(diǎn),快則幾秒鐘,慢的話(huà)耗時(shí)會(huì )超過(guò)一兩分鐘;并且同步過(guò)程還有可能失敗,健康檢測的成本也是相當高的。發(fā)布比較緊湊時(shí),需要同步的文件也很多,很容易造成隊列堆積,加劇同步差的體驗。
實(shí)時(shí)性強需求問(wèn)題。 文件在推送之前,還可能經(jīng)過(guò)一些前置系統,發(fā)布鏈路越長(cháng),線(xiàn)上生效時(shí)間越慢,慢的時(shí)候大約五分鐘才生效,這樣的延時(shí)對于實(shí)時(shí)性要求很高(如秒殺)的需求來(lái)說(shuō)是完全不能接受的。
當然,還有很多其他問(wèn)題,如運維成本增高、安全風(fēng)險增高、PHP 資深人才儲備不足等等。所以 PHP 渲染容器的命運,就是,被干掉。
服務(wù)集群為 Cache CDN,它只有靜態(tài)文件處理能力,沒(méi)有 PHP/Node 的渲染能力,所以處理效率高,性能也好,抗壓能力相當強,并且扛不住的時(shí)候還可以花錢(qián)買(mǎi)服務(wù),拓展 Cache 集群。
用戶(hù)訪(fǎng)問(wèn)時(shí),Nginx 轉到 Cache CDN,如果命中緩存則直接返回,沒(méi)有命中便回源到源站服務(wù)器。源站服務(wù)器是具備模塊渲染能力的 Node 服務(wù),它可以做很多事情:
· 控制 Cache 響應頭,通過(guò) max-age 和 s-maxage 控制頁(yè)面在客戶(hù)端的緩存時(shí)間以及在 Cache 上的緩存時(shí)間,這個(gè)緩存時(shí)間可以根據需求隨時(shí)做調整,比如大促的時(shí)候調長(cháng)一些;
· 控制內外網(wǎng)環(huán)境,和 AB 測試狀態(tài);
· 融合前端相關(guān)的工具鏈,比如檢測、壓縮、過(guò)濾等等。
它的優(yōu)勢有很多,這里不一一列舉了。這個(gè)模式中還添加了一層容災,源站服務(wù)器每隔一段時(shí)間將數據推送到于 Cache 同機房的備份服務(wù)器,一點(diǎn)源站掛了,還能夠自動(dòng)容災到備份數據上。
模式的變化不僅在運維上有了突破,CDN 被攻擊時(shí)的安全風(fēng)險也低了很多,同時(shí)也省卻了 sync 所需的各種檢測機制,每年節約成本也是百萬(wàn)以上,優(yōu)勢還是相當明顯。
3、Node,不一樣的模式
上面 PHP 模塊中,我們只說(shuō)了 HTML 和數據部分,用心的讀者應該已經(jīng)發(fā)現,CSS 和 JS 這些靜態(tài)資源都沒(méi)提到,那頁(yè)面是如何渲染的呢?
舊版 PHP 頁(yè)面中,我們是直接引入了一個(gè) CSS 和一個(gè) JS,淘寶這邊采用的是 git 版本迭代發(fā)布,這些靜態(tài)資源都是直接放在一個(gè) git 倉庫中。也就是這樣:
每次發(fā)布完 git 文件,再修改 PHP 的版本號,然后發(fā)布 PHP 代碼。當然,也做了相關(guān)的優(yōu)化,比如發(fā)布 git 時(shí)自動(dòng)更新版本號等。
一個(gè)模塊的 CSS/JS 和模板放在一起,CSS/JS 與頁(yè)面其他模塊的靜態(tài)資源是相互獨立的,目的就是希望單個(gè)模塊也能夠完整的跑起來(lái),更加利于模塊的復用。
而模塊的挖坑,也從模板中獨立了出來(lái),采用 JSON Schema 的形式定義數據格式:
模塊之間相互獨立隔離,所以會(huì )存在一定程度的冗余,不過(guò)模塊解偶帶來(lái)的收益要比這點(diǎn)冗余要多得多。事實(shí)上,我們是通過(guò)一個(gè)倉庫去管理單個(gè)模塊的。頁(yè)面的渲染就比較簡(jiǎn)單了,源站 Node 容器會(huì )將所有的 index.xtpl 合并成一個(gè) page.xtpl,為減少頁(yè)面請求,css 和 js 也會(huì ) combo 成一個(gè)文件。
任何模塊的更新,頁(yè)面都會(huì )有感知,下次進(jìn)入系統時(shí),就會(huì )提示是否需要升級模塊和頁(yè)面。
三、淘寶首頁(yè)的性能優(yōu)化
首頁(yè)模塊眾多,如果一口氣吐出來(lái),DOM 數量必然超過(guò) 4k 個(gè),其結果就是首屏時(shí)間極長(cháng)。按照 TMS 的開(kāi)發(fā)規范,每個(gè) TMS 模塊都包含一個(gè) index.js 和 index.css,最后展示出來(lái)兩個(gè) combo 的 js 和 css。首頁(yè)加載的時(shí)候也不會(huì )一口氣執行所有 index.js,否則剛開(kāi)始頁(yè)面阻塞會(huì )十分嚴重。
頁(yè)面的渲染邏輯
· 遍歷所有 TMS 模塊(包含一個(gè) J_Module 的鉤子);
· 部分 TMS 模塊無(wú) JS 內容,但是加載了一個(gè) index.js,為模塊添加 tb-pass 的 class,用于跳過(guò)該模塊 JS 的執行;
· 將頁(yè)面分為兩塊,首屏為一塊,非首屏整體為第二塊,先將首屏模塊加入到懶加載監控;
· 待首屏模塊加載完成,或者用戶(hù)處理了頁(yè)面交互時(shí)(滾動(dòng)、鼠標移動(dòng)等),將非首屏模塊加入到懶加載監控;
· 處理一些特殊模塊,它們會(huì )在進(jìn)入視窗之前幾百像素就開(kāi)始加載;
· 監控滾動(dòng),按照以上邏輯,渲染模塊;
· 部分模塊即便是被執行了,也不一定渲染出來(lái),因為它的優(yōu)先級不高,在模塊內部加了事件監聽(tīng),比如等到 mouseover/onload 事件觸發(fā)的時(shí)候再渲染這些內容。
代碼的性能優(yōu)化是一個(gè)精細活,如果你要在一個(gè)龐大的未經(jīng)優(yōu)化的頁(yè)面上做性能優(yōu)化,可能會(huì )面臨一次重構代碼。上面的文章提到的是頁(yè)面內部的細節優(yōu)化,但是在開(kāi)發(fā)流程中做的規范化、標準化,以及線(xiàn)上訪(fǎng)問(wèn)通路中的各個(gè)環(huán)節優(yōu)化還沒(méi)有提及。
四、淘寶首頁(yè)的穩定性保障
在大流量下,任何小問(wèn)題都會(huì )被放大成大問(wèn)題,所以開(kāi)發(fā)環(huán)節遇到的任何偶發(fā)性問(wèn)題都需要引起重視。不過(guò)很多偶發(fā)性問(wèn)題在我們的測試環(huán)境中是找不到的,比如與地域相關(guān)的問(wèn)題(如上海的某個(gè) CDN 節點(diǎn)掛了),用戶(hù)屬性問(wèn)題(如 nickname 最后一個(gè)為字母 s 的用戶(hù)頁(yè)面天窗),瀏覽器插件問(wèn)題,運營(yíng)商廣告注入問(wèn)題等等。
難以在上線(xiàn)之前把所有問(wèn)題考慮周全,但是有兩點(diǎn)是必須做好的:兜底容災 + 監控預警。
1、兜底容災機制
兜底容災有兩個(gè)層面的考慮:
· 異步接口請求錯誤,包括接口數據格式錯誤,接口請求超時(shí)等;
· 同步渲染,源站頁(yè)面渲染出錯。
異步接口請求,主要涉及到的是后臺系統,對接系統較多,各個(gè)系統的穩定性和抗壓能力各不相同,這方面的保障有多種方案。
每次數據請求都緩存到本地,并且為每個(gè)接口都提供一個(gè)硬兜底。還有一種方案是「重試」,請求一次不成功那就請求第二次。
對于同步渲染,它只需要頁(yè)面模板和同步數據,兩者中任一種存在錯誤,源站都會(huì )報錯,此時(shí)回源返回的內容就是一個(gè) error 頁(yè)面,狀態(tài)碼為 5xx。這個(gè)錯誤不一定是開(kāi)發(fā)者造成的,有可能是系統鏈路出現同步異;蛘邤嗦穯(wèn)題。
一旦源站任何異常,Nginx 都會(huì )轉到與 Cache CDN 同機房的首頁(yè)鏡像上去,這個(gè)鏡像內容就是淘寶首頁(yè)的 HTML 備份源碼。
2、監控預警機制
監控也有兩個(gè)層面:
· 模塊級別的監控,接口請求布點(diǎn)、模塊天窗檢測等;
· 頁(yè)面的監控,在頁(yè)面上添加特殊標記,定時(shí)回歸所有 CDN 節點(diǎn),查看特殊標記是否存在。
模塊層面的監控,內容還是相當多的,監控的點(diǎn)越多越詳細,到最后定位問(wèn)題的效率就會(huì )越高,比如在一個(gè)稍微復雜的模塊上,我會(huì )埋下這些監控:
· 接口請求格式錯誤、請求失敗、請求超時(shí),至少三個(gè)埋點(diǎn);
· 硬兜底數據請求失敗埋點(diǎn);
· 模塊 5s 內沒(méi)有渲染完成統計埋點(diǎn);
· 模塊內鏈接和圖片黑白名單匹配埋點(diǎn)。
其中部分監控還會(huì )自動(dòng)處理明確的錯誤,比如 https 頁(yè)面下出現了 http 的圖片,會(huì )立即自動(dòng)處理掉這些問(wèn)題。
3、上線(xiàn)前的自動(dòng)化檢測
這屬于淘寶整個(gè)工程化環(huán)境的一部分,前端自動(dòng)化測試。一般會(huì )在上線(xiàn)之前處理這些問(wèn)題:
· 檢測 HTML 是否符合規范
· 檢測 https 升級情況
· 檢測鏈接合法性
· 檢測靜態(tài)資源合法性
· 檢測 JavaScript 報錯
· 檢測頁(yè)面加載時(shí)是否有彈出框
· 檢測頁(yè)面是否調用 console.*
· 頁(yè)面 JS 內存記錄
當然,也可以自己添加測試用例,比如檢測接口數據格式、模塊天窗問(wèn)題等。自動(dòng)化檢測也可以設定定時(shí)回歸,還是比較有保障的。
五、淘寶首頁(yè)的敏捷措施
1、健康檢查
頁(yè)面模塊眾多,為了能夠追蹤頁(yè)面上每一個(gè)小點(diǎn)的變化,我在請求、渲染的每一個(gè)環(huán)節都做了詳細的統計。
一旦接口請求失敗,或者接口走了容災邏輯,或者模塊渲染超過(guò) 5s,控制臺都會(huì )有黃色警報,當然此時(shí),也已經(jīng)向服務(wù)器發(fā)送了警報統計。
2、接口 Hub
接口 Hub 是對數據請求的管理工具。
頁(yè)面很多模塊的渲染都需要一個(gè)以上的數據源,一旦運營(yíng)反饋?lái)?yè)面渲染數據異常,可以直接通過(guò) Hub 找到數據,加速 Bug 定位效率。同時(shí) Hub 也可以用來(lái)切換環(huán)境,將一個(gè)接口的請求切換到日;蛘哳A發(fā)環(huán)境的接口之中,它是調試的利器。
3、快捷通道
我在頁(yè)面腳本執行前后都放了一個(gè)快捷操作通道,一旦遇到緊急線(xiàn)上問(wèn)題,比如樣式錯亂溢出、接口報錯導致天窗等,可以通過(guò)快捷通道直接修改頁(yè)面的 CSS 和 JS,兩分鐘內上線(xiàn)。
不過(guò)這類(lèi)通道只適合緊急問(wèn)題的修復,畢竟隨意插入 JS 代碼是存在很大風(fēng)險的。
【淘寶首頁(yè)的基礎知識】相關(guān)文章:
淘寶客服基礎知識06-29
淘寶網(wǎng)頁(yè)美工設計如何制作網(wǎng)店首頁(yè)03-07
詳解手淘首頁(yè)的流量導入方式03-07
網(wǎng)站首頁(yè)權重比內頁(yè)高的原因分析03-18
網(wǎng)站首頁(yè)活躍度對百度收錄的影響03-22
Keepalived的基礎知識03-21
滑雪的基礎知識03-20