京東 PC 首頁 2019 改版前端總結(jié)
時間:2023-04-25 21:06:02 | 來源:網(wǎng)站運營
時間:2023-04-25 21:06:02 來源:網(wǎng)站運營
京東 PC 首頁 2019 改版前端總結(jié):本文將從以下幾個方面進行闡述
- 引入強類型校驗
- 升級資源構(gòu)建方案
- 接入自動化測試
- 完善監(jiān)控體系
- 優(yōu)化頁面加載體驗:骨架屏
- 優(yōu)化信息無障礙體驗
引入強類型校驗
在性能幾近無懈可擊的情況下,我們決定從穩(wěn)定性入手,為項目引入強類型校驗,彌補 JavaScript 這種弱類型語言在不可預(yù)測性上的缺陷。
強類型語言 TypeScript 已發(fā)布6年有余,國內(nèi)應(yīng)用的開發(fā)者也在慢慢增長。一般來說,業(yè)務(wù)開發(fā)周期短,迭代頻繁,TypeScript 的引入對于很大一部分開發(fā)者來說是一件費時費力的事,用的話業(yè)務(wù)可以上線,不用的話業(yè)務(wù)照樣可以上線,因此團隊極少在業(yè)務(wù)生產(chǎn)中應(yīng)用。但秉承著不折騰不凹凸的理念,新版首頁不負使命的,進行了基于 TS 的重構(gòu)。
做 TS 重構(gòu)并不難,把 js 后綴改成 ts 就好了。完。
當(dāng)然是開玩笑的啦!顯然,這樣的 TS 是沒有意義的。只有嚴格遵循 TS 標準的代碼才能最大化 TS 的效用。在項目中,我們對 TS 的檢查開啟 strict 模式,每次提交時,都會對代碼做一次完整的檢查,只要有 TS 報錯就禁止提交,旨在向成員傳達一個信息——
寫強類型語言就該有覺悟,否則就是耍流氓。
沒有深入使用過 TS 的同學(xué)在前期可能會感到人生的艱難,但這些都是為你好為了保證代碼的健壯性。例如,在以往難以定位、查找的 window 全局變量的管理上,十分令開發(fā)者頭疼,而引入了 TS 之后,只要對全局變量進行了接口設(shè)置,各個組件中再也不會出現(xiàn)多余或是未知全局變量的情況。再例如,在寫一個擁有
get
、
set
方法的存貯類的時候,TS 能幫助檢測獲取內(nèi)容的類型:
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 } } 復(fù)制代碼
當(dāng)我們使用
new Controller().get("testb")
的時候,TS 能夠在開發(fā)階段檢測
testb
是否是
string
類型。通過 TS 的檢測插件,我們能放心的使用
string
類型對象的方法,簡化繁復(fù)的判斷邏輯,同時保證代碼在獲取到非期望值時能及時通過報錯發(fā)現(xiàn),一切的輸入和輸出都是穩(wěn)定可預(yù)測的,四舍五入就是在寫代碼的時候自動走了一部分測試,為項目的開發(fā)與迭代保駕護航。
升級資源構(gòu)建方案
舊版首頁項目使用的構(gòu)建工具 Athena,推進了開發(fā)流程自動化,但是涉及到定制化的構(gòu)建流程時,由于 Athena 的通用性,不方便直接做改動。首頁包含直出、同步、異步三種類型的資源引用,需對資源的打包進行特殊處理,所以我們這次回歸 Webpack,基于 Webpack 4.0 做了以下的方案優(yōu)化:
發(fā)布流程優(yōu)化
舊版的發(fā)布流程中,每次發(fā)布需要對改動的文件進行 diff 檢查,避免產(chǎn)生不符合預(yù)期的誤改動。Webpack 默認打包機制的特點,是根據(jù)模塊的打包順序為每一個模塊提供一個按順序編號的 ID,對文件的包進行依賴管理。舊版首頁的入口文件包含依賴包管理的執(zhí)行環(huán)境,因此任何一個包引入順序發(fā)生變動時,入口文件都會發(fā)生變動。以上的打包機制會出現(xiàn)一個文件發(fā)生引入順序變動時,可能會影響到編譯后的幾個甚至十幾個文件發(fā)生變動的情況,而這些文件中的邏輯代碼部分其實并不需要更新,這就降低了 diff 代碼的準確性,使得這一中間檢查措施失去了原本的意義。首頁緩存機制與資源懶加載機制使得靜態(tài)資源在發(fā)布時,需要對發(fā)生變動的文件進行 CDN 緩存清除的操作,也就意味著,改動文件越多,需要清除的緩存資源鏈接就越多,而鏈接越多,由于緩存清除不同步引起的資源異步加載出錯的概率就越高,每次上線發(fā)布都存在一定的風(fēng)險。
為了減少發(fā)布風(fēng)險,新版首頁的打包機制改變了 Webpack 的打包邏輯,通過設(shè)置,每個模塊不再通過順序編號的 ID 管理依賴包,而是通過文件目錄生成哈希編碼的專有 ID,并把依賴包的執(zhí)行環(huán)境從入口文件中抽離出來作為一個單獨的資源請求,這樣每次改動文件時,可以只針對改動的文件 diff,剔除了其他非預(yù)期的 diff 情況。通過新的構(gòu)建方案,使代碼改動控制在預(yù)期的范圍內(nèi),保證部署流程的穩(wěn)定。
項目架構(gòu)優(yōu)化
舊版頁面的性能優(yōu)化方案中,包含了部分 js 片段直出,這些代碼是項目所依賴的基函數(shù),需要在核心 js 代碼執(zhí)行之前啟動。但這樣的方案也有一些不盡人意的地方:
- 由于代碼需要直出于頁面模版中,考慮到兼容性,這些代碼不能使用一些高級語法,每次改動都需要確保自己的代碼沒有兼容問題,導(dǎo)致維護成本巨高。同時,首頁頁面模版由后臺負責(zé)管理,直出代碼的改動需經(jīng)過后臺發(fā)布,迭代成本略高,風(fēng)險也不??;
- 由于打包的限制,核心代碼與模板代碼存在同一套公用代碼,代碼冗余不說,一旦這部分代碼發(fā)生變動還需要同時修改與發(fā)布兩部分的代碼,使得代碼的維護成本增高。
針對以上問題,新版中我們將這些代碼重新放入核心代碼,模板代碼中不再承載任何邏輯代碼,迭代發(fā)版不再涉及模版發(fā)布,只需進行靜態(tài)資源的發(fā)布即可,開發(fā)過程中統(tǒng)一使用 JS 高級語法,去除人工維護兼容語法代碼的過程。
至此,我們通過增強資源打包的可預(yù)測性、以及優(yōu)化項目資源架構(gòu)兩個方面對資源的發(fā)布方案進行了優(yōu)化。
接入自動化測試
一個頁面開發(fā)完成后,在對其進行提測之前,對頁面進行自測是一個必不可少的環(huán)節(jié)。一方面,保證頁面所開發(fā)的功能能正常運作;另一方面,保證在對一個功能進行開發(fā)時,沒有影響到頁面其他區(qū)域功能的正常使用。
一般情況下,自測需要人為手動地進行測試,但這樣會有兩個缺點,第一,需要測試的區(qū)域數(shù)量過于巨大,相似的測試操作過于頻繁,浪費了人力,也影響了測試的效率;第二,人為的自測由于沒有統(tǒng)一的自測規(guī)范,因此在測試時很容易有所疏漏,從而忽視了一些看似微小,實則影響巨大的 bug,花費了大量的時間,卻得不到自測所需要的效果。針對這種情況,我們產(chǎn)生了實施自動化測試的想法。以新版首頁為例,我們通過使用 Nightwatch.js,為新版首頁創(chuàng)建了一個自動化測試腳本,對新版的首頁的73項用例進行自動化測試。
結(jié)果顯示,通過自動化測試,在不到三分鐘的時間內(nèi),完成了對新版首頁73項用例的測試,這也意味著,若要通過自動化測試,來對任一頁面進行自測,自測的時間都可控制在五分鐘以內(nèi),并且準確性更高。將自動化測試應(yīng)用在發(fā)布前以及上線后5分鐘之內(nèi),及時檢查測試用例,保證每次發(fā)版的安全。
完善監(jiān)控體系
舊版頁面的前端監(jiān)控體系覆蓋了瀏覽器信息、頁面加載測速、樓層隱藏方面,但信息通知較為滯后,且僅覆蓋了頁面 onLoad 時間,收到告警信息時,無法做到快速定位問題。
參考京東購物小程序目前的監(jiān)控機制,新版首頁針對代碼報錯、接口可用性增加了上報監(jiān)控。
代碼報錯監(jiān)控:BadJS
通過 BadJS 框架捕獲頁面報錯,并分析處理報錯信息上報至京東 BadJS 服務(wù)。通過上報數(shù)據(jù),我們可以得到報錯的詳細信息以及發(fā)生次數(shù)。通過分析上報數(shù)據(jù),可以發(fā)現(xiàn)一些潛在的問題,及時修復(fù),保證首頁代碼的健壯性。同時根據(jù)上報數(shù),還可以預(yù)估出一個問題所造成的影響范圍,便于預(yù)估損失。
業(yè)務(wù)可用性監(jiān)控
本次改版,在可用率上報系統(tǒng)中為首頁補充了特定判定規(guī)則,包含調(diào)用次數(shù)、可用率、和 TP(性能指標)三個維度,在此基礎(chǔ)上還可以對這三個維度進行環(huán)比,以減少誤報的可能性,近期系統(tǒng)還上線了紅燈告警-語音通知功能。
可用率上報系統(tǒng)一般被用來監(jiān)聽接口可用性,但對于首頁來說,除了接口,還需關(guān)注樓層隱藏的情況。目前的兜底方案中,每個樓層中的模塊接口兜底全部失效的情況下,會隱藏當(dāng)前樓層。樓層一旦發(fā)生隱藏,則意味著出現(xiàn)了比較嚴重的問題,需快速關(guān)注并解決??捎寐噬蠄笙到y(tǒng)可做到觸發(fā)告警規(guī)則時,1分鐘之內(nèi)即推送通知,精確到接口,便于及時發(fā)現(xiàn)問題,及時止損。需要注意的是,如何設(shè)置一套能夠較為精確反映問題發(fā)生、減少假報警的閾值尤為重要,畢竟狼來了喊多了,也就等于沒有監(jiān)控。
測速上報
這一部分延用了舊版的 Athena 測速上報方案,并對一些與業(yè)務(wù)數(shù)據(jù)上報重復(fù)的部分做了減法,同時增加了接口的測速上報,完善故障追溯數(shù)據(jù)體系。
優(yōu)化頁面加載體驗:骨架屏
舊版頁面懶加載的占位方案采用了統(tǒng)一區(qū)域 loading 動畫的方式,這種方式的優(yōu)勢在于復(fù)用成本低,適配性強。但如果遇到較大面積的模塊或是模塊較為密集的情況時,區(qū)域 loading 動畫的體驗有所下降————要么是空白區(qū)域過大,要么是 loading 動畫過于密集,模塊加載過程造成的視覺差異感知較為明顯。而對于 PC 首頁來說,空白區(qū)域過大是主要存在的問題。
低網(wǎng)速下舊版首頁的 loading 體驗
這次改版,我們引入了骨架屏方案,最終目的是以灰色豆腐塊的形式盡量縮小真實模塊結(jié)構(gòu)與加載占位之間的視覺差異。執(zhí)行起來可以按照視覺差異分為兩種對應(yīng)關(guān)系:
- 弱對應(yīng)關(guān)系:只對模塊進行標題、子項等主要內(nèi)容進行塊化處理,復(fù)用性較高,適配性中等;
- 強對應(yīng)關(guān)系:以視覺效果為基礎(chǔ),對子項進一步作出圖片、文案的塊化處理,針對占位面積較大、內(nèi)容更為復(fù)雜的子項進行更細化的塊化拆分,復(fù)用性低,適配性高。
考慮到首頁的特殊性,我們最終選擇了強對應(yīng)關(guān)系的骨架屏方案,并為了可擴展性,使用的是使用樣式渲染的骨架屏,而不是直接使用圖片占位。除了開發(fā)成本的上升,頁面首屏加載代碼量也有所增加。
項目結(jié)構(gòu)
使用骨架屏所要達到的效果包含以下幾點:
- 提前占位,在頁面的加載中滾動條不發(fā)生較為明顯的跳動;
- 頁面快速滾動時也能看到骨架屏樣式的占位。
也就意味著骨架屏的內(nèi)容需要與頁面做同步加載處理,結(jié)合懶加載組件,骨架屏組件需提前作為 loading 結(jié)構(gòu)傳入,并保證樣式在頁面渲染的第一時間進行加載,否則就失去了骨架屏的意義。
每個需要骨架屏樣式的組件,單獨拆分出一個 placeholder 組件。組件內(nèi)的占位結(jié)構(gòu)包含兩類樣式——顏色與尺寸定位,加上容器外層的動畫效果樣式。顏色樣式全頁公用,尺寸定位樣式與正式組件公用:
尺寸定位樣式與正式組件公用的目的是為了在將來組件樣式發(fā)生變化時,保證骨架屏與正式樣式的統(tǒng)一修改,避免出現(xiàn)樣式修改上的遺漏,但同時增加了樣式的維護成本。同時樣式編寫與拆分的過程中也需要開發(fā)者注意兼容骨架屏的樣式,例如需要占位豆腐塊的容器間距 padding、margin 的選擇都很重要。因此這次首頁的骨架屏嘗試并不適合快速復(fù)用至其他項目。
新版首頁骨架屏 loading 體驗
優(yōu)化信息無障礙體驗
互聯(lián)網(wǎng)信息無障礙,即針對視力障礙人士所提供的輔助。系統(tǒng)級別的輔助主要依賴讀屏工具,讀屏工具可以解決網(wǎng)頁端信息無障礙 60%的阻礙,剩余的 40%需要在網(wǎng)頁開發(fā)的過程中由開發(fā)者進行體驗優(yōu)化。
沒有做任何信息無障礙處理的網(wǎng)頁,使用讀屏工具訪問時一般存在以下幾個問題:
- 多余無用信息的播報,例如:跳轉(zhuǎn)鏈接、圖片名稱;
- 彈出浮層無法訪問;
- 懶加載內(nèi)容直接跳過;
為了造福國內(nèi)一百一十人中的一個視障人士(數(shù)據(jù)來自這里),本次改版,我們決定在 PC 首頁開啟京東商城桌面端首個信息無障礙實踐。
桌面端視障用戶的操作主要通過鍵盤進行。針對剛才提出的幾個問題,PC 首頁初步的無障礙體驗優(yōu)化方案分為幾個階段。
第一階段,語義化一切 tab 可及的元素——包含頁面外跳轉(zhuǎn)鏈接的
a
標簽統(tǒng)一添加
aria-label
屬性,以便讀屏軟件能夠簡化讀取元素信息;
第二階段,保證頁面主要模塊的訪問——懶加載內(nèi)容占位容器將
tab-index
設(shè)置為大于 0 的值,使得 tab 鍵能夠遍歷到,以便觸發(fā)頁面懶加載,避免 tab 直接跳過;
第三階段,擴展帶彈出浮層等元素的操作——針對無障礙增加彈出浮層交互邏輯,入口增加
aria-haspopup
屬性,告訴讀屏軟件這里是彈出浮層的入口,將
tab-index
設(shè)置為大于 0 的數(shù)值使得 tab 操作可聚焦到,浮層彈出后焦點自動聚焦至浮層;
第四階段,為視障用戶額外增加快捷跳轉(zhuǎn)——參考 Google 搜索結(jié)果頁,可在頁面的頂部,增加一些隱藏的快捷跳轉(zhuǎn)。PC 首頁本次對搜索框以及底部的“為你推薦”位置增加了隱藏跳轉(zhuǎn)鏈接,只有使用鍵盤操作的用戶能夠定位到。
對于商城頁面來說,第一階段能滿足基本的內(nèi)容訪問,而如果能做到第四階段,才能算一個完整的信息無障礙網(wǎng)站。商城業(yè)務(wù)中,無障礙體驗一直缺乏相應(yīng)的規(guī)范與測試流程,因此通過本次 PC 首頁的改版實踐,輸出了一份針對商城頻道頁的信息無障礙開發(fā)規(guī)范,內(nèi)容包含:
- 訪問路徑設(shè)計規(guī)范
- 語義化規(guī)范
- 讀屏測試規(guī)范
未來將借由這份規(guī)范,陸續(xù)實現(xiàn)商城其他業(yè)務(wù)的無障礙體驗優(yōu)化。
綜上,本次改版對于開發(fā)者來說最大的變化,就是本地開發(fā)體驗更加舒服、發(fā)布風(fēng)險有所降低、故障追溯更加完善,而對用戶來說,頁面加載跳動感大大減小,視障用戶的體驗終于得以照顧到。作為商城桌面端的入口與門面,首頁的改進一定不止于此,希望每一次的改版都能有一絲的優(yōu)化,使得首頁這個項目趨近完美。