距離上次首頁改版,已有2年3個月零五天。相比上次改版對首頁總體框架、開發流程的大刀闊斧(前兩次改版總結傳送門:2016版,2017版),此次的改版看起來顯得有點像跳水——沒什麼水花。在站在巨人肩膀上的小巨人的叮嚀與期盼下,此次改版在延續17版的框架與流程的基礎之上,爲首頁的穩定性、安全性、視覺體驗、無障礙體驗方面見縫插針地添了磚加了瓦。javascript
在性能幾近無懈可擊的狀況下,咱們決定從穩定性入手,爲項目引入強類型校驗,彌補 JavaScript 這種弱類型語言在不可預測性上的缺陷。前端
強類型語言 TypeScript 已發佈6年有餘,國內應用的開發者也在慢慢增加。通常來講,業務開發週期短,迭代頻繁,TypeScript 的引入對於很大一部分開發者來講是一件費時費力的事,用的話業務能夠上線,不用的話業務照樣能夠上線,所以團隊極少在業務生產中應用。但秉承着不折騰不凹凸的理念,新版首頁不負使命的,進行了基於 TS 的重構。java
作 TS 重構並不難,把 js 後綴改爲 ts 就行了。完。小程序
固然是開玩笑的啦!顯然,這樣的 TS 是沒有意義的。只有嚴格遵循 TS 標準的代碼才能最大化 TS 的效用。在項目中,咱們對 TS 的檢查開啓 strict 模式,每次提交時,都會對代碼作一次完整的檢查,只要有 TS 報錯就禁止提交,旨在向成員傳達一個信息——寫強類型語言就該有覺悟,不然就是耍流氓。瀏覽器
沒有深刻使用過 TS 的同窗在前期可能會感到人生的艱難,但這些都是爲你好爲了保證代碼的健壯性。例如,在以往難以定位、查找的 window 全局變量的管理上,十分令開發者頭疼,而引入了 TS 以後,只要對全局變量進行了接口設置,各個組件中不再會出現多餘或是未知全局變量的狀況。再例如,在寫一個擁有 get
、set
方法的存貯類的時候,TS 能幫助檢測獲取內容的類型:緩存
interface MemoryState {
testa: boolean
testb: string
}
class Controller {
state: StateType
constructor() {
this.state = {
state: {},
}
}
get<K extends MemoryStateKeys>(key: K) {
return this.state.memory[key]
}
set<K extends MemoryStateKeys>(key: K, value: MemoryState[K]): MemoryState[K] {
this.state.memory[key] = value
return value
}
}
複製代碼
當咱們使用 new Controller().get("testb")
的時候,TS 可以在開發階段檢測 testb
是不是 string
類型。經過 TS 的檢測插件,咱們能放心的使用 string
類型對象的方法,簡化繁複的判斷邏輯,同時保證代碼在獲取到非指望值時能及時經過報錯發現,一切的輸入和輸出都是穩定可預測的,四捨五入就是在寫代碼的時候自動走了一部分測試,爲項目的開發與迭代保駕護航。安全
舊版首頁項目使用的構建工具 Athena,推動了開發流程自動化,可是涉及到定製化的構建流程時,因爲 Athena 的通用性,不方便直接作改動。首頁包含直出、同步、異步三種類型的資源引用,需對資源的打包進行特殊處理,因此咱們此次迴歸 Webpack,基於 Webpack 4.0 作了如下的方案優化:性能優化
舊版的發佈流程中,每次發佈須要對改動的文件進行 diff 檢查,避免產生不符合預期的誤改動。Webpack 默認打包機制的特色,是根據模塊的打包順序爲每個模塊提供一個按順序編號的 ID,對文件的包進行依賴管理。舊版首頁的入口文件包含依賴包管理的執行環境,所以任何一個包引入順序發生變更時,入口文件都會發生變更。以上的打包機制會出現一個文件發生引入順序變更時,可能會影響到編譯後的幾個甚至十幾個文件發生變更的狀況,而這些文件中的邏輯代碼部分其實並不須要更新,這就下降了 diff 代碼的準確性,使得這一中間檢查措施失去了本來的意義。首頁緩存機制與資源懶加載機制使得靜態資源在發佈時,須要對發生變更的文件進行 CDN 緩存清除的操做,也就意味着,改動文件越多,須要清除的緩存資源連接就越多,而連接越多,因爲緩存清除不一樣步引發的資源異步加載出錯的機率就越高,每次上線發佈都存在必定的風險。架構
爲了減小發布風險,新版首頁的打包機制改變了 Webpack 的打包邏輯,經過設置,每一個模塊再也不經過順序編號的 ID 管理依賴包,而是經過文件目錄生成哈希編碼的專有 ID,並把依賴包的執行環境從入口文件中抽離出來做爲一個單獨的資源請求,這樣每次改動文件時,能夠只針對改動的文件 diff,剔除了其餘非預期的 diff 狀況。經過新的構建方案,使代碼改動控制在預期的範圍內,保證部署流程的穩定。框架
舊版頁面的性能優化方案中,包含了部分 js 片斷直出,這些代碼是項目所依賴的基函數,須要在覈心 js 代碼執行以前啓動。但這樣的方案也有一些不盡人意的地方:
針對以上問題,新版中咱們將這些代碼從新放入核心代碼,模板代碼中再也不承載任何邏輯代碼,迭代發版再也不涉及模版發佈,只需進行靜態資源的發佈便可,開發過程當中統一使用 JS 高級語法,去除人工維護兼容語法代碼的過程。
至此,咱們經過加強資源打包的可預測性、以及優化項目資源架構兩個方面對資源的發佈方案進行了優化。
一個頁面開發完成後,在對其進行提測以前,對頁面進行自測是一個必不可少的環節。一方面,保證頁面所開發的功能能正常運做;另外一方面,保證在對一個功能進行開發時,沒有影響到頁面其餘區域功能的正常使用。
通常狀況下,自測須要人爲手動地進行測試,但這樣會有兩個缺點,第一,須要測試的區域數量過於巨大,類似的測試操做過於頻繁,浪費了人力,也影響了測試的效率;第二,人爲的自測因爲沒有統一的自測規範,所以在測試時很容易有所疏漏,從而忽視了一些看似微小,實則影響巨大的 bug,花費了大量的時間,卻得不到自測所須要的效果。針對這種狀況,咱們產生了實施自動化測試的想法。以新版首頁爲例,咱們經過使用 Nightwatch.js,爲新版首頁建立了一個自動化測試腳本,對新版的首頁的73項用例進行自動化測試。
結果顯示,經過自動化測試,在不到三分鐘的時間內,完成了對新版首頁73項用例的測試,這也意味着,若要經過自動化測試,來對任一頁面進行自測,自測的時間均可控制在五分鐘之內,而且準確性更高。將自動化測試應用在發佈前以及上線後5分鐘以內,及時檢查測試用例,保證每次發版的安全。
舊版頁面的前端監控體系覆蓋了瀏覽器信息、頁面加載測速、樓層隱藏方面,但信息通知較爲滯後,且僅覆蓋了頁面 onLoad 時間,收到告警信息時,沒法作到快速定位問題。
參考京東購物小程序目前的監控機制,新版首頁針對代碼報錯、接口可用性增長了上報監控。
經過 BadJS 框架捕獲頁面報錯,並分析處理報錯信息上報至京東 BadJS 服務。經過上報數據,咱們能夠獲得報錯的詳細信息以及發生次數。經過分析上報數據,能夠發現一些潛在的問題,及時修復,保證首頁代碼的健壯性。同時根據上報數,還能夠預估出一個問題所形成的影響範圍,便於預估損失。
本次改版,在可用率上報系統中爲首頁補充了特定斷定規則,包含調用次數、可用率、和 TP(性能指標)三個維度,在此基礎上還能夠對這三個維度進行環比,以減小誤報的可能性,近期系統還上線了紅燈告警-語音通知功能。
可用率上報系統通常被用來監聽接口可用性,但對於首頁來講,除了接口,還需關注樓層隱藏的狀況。目前的兜底方案中,每一個樓層中的模塊接口兜底所有失效的狀況下,會隱藏當前樓層。樓層一旦發生隱藏,則意味着出現了比較嚴重的問題,需快速關注並解決。可用率上報系統可作到觸發告警規則時,1分鐘以內即推送通知,精確到接口,便於及時發現問題,及時止損。須要注意的是,如何設置一套可以較爲精確反映問題發生、減小假報警的閾值尤其重要,畢竟狼來了喊多了,也就等於沒有監控。
這一部分延用了舊版的 Athena 測速上報方案,並對一些與業務數據上報重複的部分作了減法,同時增長了接口的測速上報,完善故障追溯數據體系。
舊版頁面懶加載的佔位方案採用了統一區域 loading 動畫的方式,這種方式的優點在於複用成本低,適配性強。但若是遇到較大面積的模塊或是模塊較爲密集的狀況時,區域 loading 動畫的體驗有所降低————要麼是空白區域過大,要麼是 loading 動畫過於密集,模塊加載過程形成的視覺差別感知較爲明顯。而對於 PC 首頁來講,空白區域過大是主要存在的問題。
此次改版,咱們引入了骨架屏方案,最終目的是以灰色豆腐塊的形式儘可能縮小真實模塊結構與加載佔位之間的視覺差別。執行起來能夠按照視覺差別分爲兩種對應關係:
考慮到首頁的特殊性,咱們最終選擇了強對應關係的骨架屏方案,併爲了可擴展性,使用的是使用樣式渲染的骨架屏,而不是直接使用圖片佔位。除了開發成本的上升,頁面首屏加載代碼量也有所增長。
使用骨架屏所要達到的效果包含如下幾點:
也就意味着骨架屏的內容須要與頁面作同步加載處理,結合懶加載組件,骨架屏組件需提早做爲 loading 結構傳入,並保證樣式在頁面渲染的第一時間進行加載,不然就失去了骨架屏的意義。
每一個須要骨架屏樣式的組件,單獨拆分出一個 placeholder 組件。組件內的佔位結構包含兩類樣式——顏色與尺寸定位,加上容器外層的動畫效果樣式。顏色樣式全頁公用,尺寸定位樣式與正式組件公用:
尺寸定位樣式與正式組件公用的目的是爲了在未來組件樣式發生變化時,保證骨架屏與正式樣式的統一修改,避免出現樣式修改上的遺漏,但同時增長了樣式的維護成本。同時樣式編寫與拆分的過程當中也須要開發者注意兼容骨架屏的樣式,例如須要佔位豆腐塊的容器間距 padding、margin 的選擇都很重要。所以此次首頁的骨架屏嘗試並不適合快速複用至其餘項目。
互聯網信息無障礙,即針對視力障礙人士所提供的輔助。系統級別的輔助主要依賴讀屏工具,讀屏工具能夠解決網頁端信息無障礙 60%的阻礙,剩餘的 40%須要在網頁開發的過程當中由開發者進行體驗優化。
沒有作任何信息無障礙處理的網頁,使用讀屏工具訪問時通常存在如下幾個問題:
爲了造福國內一百一十人中的一個視障人士(數據來自這裏),本次改版,咱們決定在 PC 首頁開啓京東商城桌面端首個信息無障礙實踐。
桌面端視障用戶的操做主要經過鍵盤進行。針對剛纔提出的幾個問題,PC 首頁初步的無障礙體驗優化方案分爲幾個階段。
第一階段,語義化一切 tab 可及的元素——包含頁面外跳轉連接的 a
標籤統一添加 aria-label
屬性,以便讀屏軟件可以簡化讀取元素信息;
第二階段,保證頁面主要模塊的訪問——懶加載內容佔位容器將 tab-index
設置爲大於 0 的值,使得 tab 鍵可以遍歷到,以便觸發頁面懶加載,避免 tab 直接跳過;
第三階段,擴展帶彈出浮層等元素的操做——針對無障礙增長彈出浮層交互邏輯,入口增長 aria-haspopup
屬性,告訴讀屏軟件這裏是彈出浮層的入口,將 tab-index
設置爲大於 0 的數值使得 tab 操做可聚焦到,浮層彈出後焦點自動聚焦至浮層;
第四階段,爲視障用戶額外增長快捷跳轉——參考 Google 搜索結果頁,可在頁面的頂部,增長一些隱藏的快捷跳轉。PC 首頁本次對搜索框以及底部的「爲你推薦」位置增長了隱藏跳轉連接,只有使用鍵盤操做的用戶可以定位到。
對於商城頁面來講,第一階段能知足基本的內容訪問,而若是能作到第四階段,才能算一個完整的信息無障礙網站。商城業務中,無障礙體驗一直缺少相應的規範與測試流程,所以經過本次 PC 首頁的改版實踐,輸出了一份針對商城頻道頁的信息無障礙開發規範,內容包含:
將來將藉由這份規範,陸續實現商城其餘業務的無障礙體驗優化。
綜上,本次改版對於開發者來講最大的變化,就是本地開發體驗更加舒服、發佈風險有所下降、故障追溯更加完善,而對用戶來講,頁面加載跳動感大大減少,視障用戶的體驗終於得以照顧到。做爲商城桌面端的入口與門面,首頁的改進必定不止於此,但願每一次的改版都能有一絲的優化,使得首頁這個項目趨近完美。