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