複製代碼
做者:禹霖
原文地址: tech.meituan.com/2018/03/16/…
隨着美團點評金融業務的高速發展,前端研發數量從 2015 年的 1 我的,擴張到了如今橫跨北上兩地 8 個事業部的將近 150 人。業務新,團隊新,前端領域框架技術又層出不窮,各個業務的研發團隊在技術選擇上沒有明確的指導意見,導致業務與業務之間的技術差別愈來愈大,在技術工具研發上沒法共建,在資源調度上成本也很高。html
2017年下半年,金融平臺發起了技術棧統一行動,行動分爲後端、iOS、Android及前端等四個方向,在前端方向我做爲組織者和參與者與金融平臺 8 個事業部的前端技術表明進行討論。 經過對各方意見進行概括整理,結合各團隊的狀況,金融平臺對於技術棧的選型達成了共識。本文將介紹美團點評金融平臺前端的技術選型以及背後的思考。先從一些基本原則講起。前端
金融業務的移動端項目佔比超過 70%,尤爲是 Hybrid 項目,團隊在整個移動端生態的設計上投入了大量的精力,例如 Vue 的選擇、EH 的設計、組件庫 Vix 的設計等。vue
同時因爲業務的金融屬性,對於可用性的要求很是高。在可用性保障上咱們還會有一些側重,例如 TypeScript 的使用,自動化流程測試框架 Freekite 的使用等。git
金融大多數團隊都處於初創時期,所以團隊歷史包袱相對較少,接受新鮮事物的能力強,但快速搭建團隊中也會對技術棧有上手成本的要求。在整個技術體系的搭建當中,咱們會優先考慮那些新的、上手成本低的技術。github
咱們主張使用簡單的技術手段解決複雜的問題,而不是用複雜的技術手段解決簡單的問題,例如 Hybrid 體驗問題的解決,常規的有 RN、Weex 等方案,在業界有豐富的實踐,但咱們也會設計實現更簡單的解決方案 EH,讓問題的解決變得更聚焦於問題的本質。在首屏渲染速度優化方案上的選擇也是同樣,業界有很好的 SSR 技術,但咱們也會實踐研發構建時預渲染技術,讓 TTFB(首字節時間)更快,讓系統流量負載更高,同時減小關鍵環節,讓整個系統可用性更強。web
標準化指的就是儘量讓上下游銜接造成標準,並在標準下構建效率和質量工具。後端
例如在組件庫 Vix 的研發上,咱們與 UED 造成一致的、強同步的標準,從而大大減小界面搭建的時間消耗。後面會詳細介紹。瀏覽器
用技術去鏈接技術,用技術去簡化步驟,解決某個工具到使用者的「最後一千米」問題。緩存
例如咱們使用的自動化流程測試工具 Freekite,不用一行代碼便可以完成複雜的分支邏輯自動化測試與持續集成。咱們使用的聯調平臺 Portm 能夠將接口設計和前端 Mock 、後端單測、接口文檔有機的結合起來,將先後端的研發進度解耦,從而大大提高研發效率。安全
顧名思義就是選型上儘可能使用公司已有的系統和工具,從而更好的與團隊、業務結合。
例如全平臺監控工具 CAT,業務埋點工具靈犀等等。下面來看看咱們技術體系的細節。
咱們將從開發階段開始介紹,從視圖層、語言層、協做層,再到質量保障工具、體驗優化工具、安全技術等。接下來過渡到編譯部署階段,講一講編譯部署和上線工具。而後是線上監控和埋點工具。最後介紹一些各個團隊正在探索和實踐當中的技術。
在移動端使用 Vue 生態,在桌面版上咱們使用 React 生態 或者 Vue 生態。
Vue 的使用主要考慮如下幾點:
React 的使用主要考慮如下緣由:
組件庫是前端領域一個重要的技術單元,爲效率、質量、體驗服務。
效率是爲了可以抽象業務研發中業務組件的共同點去避免重複勞動;質量是若是一個組件通過了測試和質量迭代,那麼正確的使用不該該出現質量問題;體驗方面組件庫能夠去統一交互的體驗,讓組件的表現更一致。
上述三點中,組件庫貢獻最大的是效率。
談到組件庫如何對效率作貢獻,首先想到的是什麼樣的組件庫纔可以儘量的提高咱們的研發效率,我認爲這裏咱們須要注意的一點是「控制變量」,由於變化產生了額外的工做量和時間成本,若是這個產品和上個產品徹底同樣,咱們直接複製一份就行了,不必開發。在咱們的前端業務研發當中,變量是什麼?是交互和視覺設計,每一個產品之間有不一樣,也有相同。咱們控制變量就應該去控制設計。所以咱們與金融 UED(設計部門) 溝通制定了一個視覺組件標準,共同建立了視覺組件庫:Vix。
Vix 是一個移動端組件庫,其特色是徹底遵照與金融 UED 制定的視覺組件標準並保持同步,在 UED 側有完善的新組件設計提審及審覈流程,在業務前端研發側有強同步的約束。
Vix 的結構分爲基礎組件、複雜組件和業務組件三層,基礎組件例如輸入框、按鈕等;複雜組件包括組合搜索、日期選擇等;業務組件例如支付密碼輸入框、帳單、帳單詳情等。
再上升一層則是一些包含後端服務的先後端組件,咱們稱爲「微服務」,是一種更高層次的業務服務抽象,在更高的維度優化效率和服務體驗一致性,例如支付密碼驗證服務,找回支付密碼服務等。Vix 包含的是前三層,其結構以下圖:
在以往的實踐過程中,C端業務使用開源組件庫會和設計有很大差別,須要作大量的改造工做才能使用,然而可能還要爲各類各樣改造過程當中所產生的問題負責,同時開源組件庫的業務不相關性限制了業務產品的設計或實現。在 Vix 中,因爲標準統一,咱們的研發效率大大提高,同時質量也更加可控。
大多數移動端產品研發過程當中至少 40% 以上的精力是在作界面的繪製。有了 Vix 後咱們達到了:
PC 端面向用戶和商戶的大多都是較爲獨立的產品,標準化的意義並不大,前端在 PC 端的研發精力主要投入在內部系統上,在內部系統前端研發上有四個特色:
所以在內部系統的研發上有四點要求:
PC 端組件庫因爲設計沒有要求,不存在來自設計的「變量」,因此選擇不少。
React Cells 也是美團點評內部的一個組件庫,金融在使用 React 生態的後臺系統研發中使用 React Cells 做爲組件庫,其具備以下幾個特色能夠知足咱們的需求:
在 Vue 生態實現的 PC 端內部系統中,咱們使用 Element-UI 做爲組件庫,組件數量不少,質量也很高,在 Vue 生態中是排名靠前的開源組件庫,這裏很少贅述。
針對ES6,本文再也不進行過多闡述。對於 TypeScript 的使用是從2015年末開始,當時咱們的移動端 Web 版收銀臺要作質量和可用性保障(詳情參考以前的文章《前端可用性保障實踐》),在 JS 層面咱們遇到的最多的運行時問題就是 something is undefined,也就是空指針問題。另外就是因爲銀行卡支付過程的業務邏輯很是複雜,代碼層面可控性差,擴展性也不好。這時候想到的就是使用強類型語言來管理咱們的項目,強類型語言能夠幫助咱們作兩個事情:
當時咱們面臨兩個選擇,一個是微軟的 TypeScript ,一個是 Facebook 的 Flow。選擇 TypeScript 是由於如下幾點:
而不選擇 Flow 的緣由主要包括如下幾點:
TypeScript 包括 類型守護、聯合類型、類型推導、嚴格非空檢查等功能。
舉個例子如圖所示:
參數 s 是可能爲空的,在 TypeScript 裏,若是不作非空檢查就會報錯,作了非空檢查經過 TypeScript 的類型推導就可以經過。
經過使用 TypeScript 咱們能夠找出前端項目中 99% 的引用問題,因爲咱們的整個前端框架所有支持 TypeScript,有效的避免了空指針這種運行時低級錯誤的存在。
在 TypeScript 的使用上金融支付也是公司第一個在線上使用 TypeScript 的業務線,2015年末咱們還制定了 TypeScript 代碼規範。
在平常開發當中,先後端聯調常常遇到一些環境問題或者接口設計的問題,致使先後端當中一方等待另一方,這種狀況在效率上影響很是大。協做解耦指的就是讓先後端的研發工做不互相依賴,從而優化研發效率。
上圖表示的就是協做耦合所形成的效率問題,字母 A 表明項目 A,在先後端研發過程當中,前端可能由於後端問題而沒法繼續開發,反之亦然。
2015年的時候我還在技術工程部,那個時候組內同窗一塊兒想到了一個方法去解決這個問題。最初的想法就是「咱們能不能經過接口設計一方面生成提供給前端研發使用的假數據,另外一方面生成後端的單測。」
這個想法最終落地就是 **Vane **這個工具,如今叫 Portm。
它能夠在一個項目的接口設計時切入,先後端使用這個平臺進行接口設計,同時寫入各類邏輯 Case 的輸入輸出,它能夠直接生成三個東西:
在項目研發過程當中,前端面向假數據開發沒必要擔憂遇到後端環境問題;後端面向單測開發沒必要擔憂本身跑通了前端跑不通。當雙方都能跑通的時候進行集成聯調,這個時候先後端集成度會很是高,先完成的一方能夠直接進入下一個項目,從部門角度來說,大大優化了產品迭代研發的效率。
下圖表示的是優化後的效果,能夠看到先後端已經無需互相等待了。
針對自動化測試,美團點評開發了一款工具叫 Freekite ,它的做用是從用戶使用角度驗證界面業務流程的正確性,解決了爲實現模擬用戶點擊而帶來的諸多問題及 Case 管理的複雜度問題。
Web自動化流程測試除了能夠驗證 Case 的正確性之外,最重要的功能就是要有一個異常強大的 Case 管理模塊。業界目前並無理想的工具可以支撐咱們的場景。「Freekite」 在 Case 驗證功能的基礎上,有一個強大的可視化 Case 管理模塊,支持複雜的 Case 細分。除了界面操做的細分外,能夠全量 Mock 或部分 Mock 後端的數據響應,根據響應拆分出不一樣的 Case 分支。除此以外,還包含智能自動化斷言功能,斷言基本不須要人工參與。
Case 錄完之後遇到界面改版的狀況很差處理,Freekite 還支持單獨節點的從新錄製,也就完美的解決了 Case 的維護問題,大幅度減小工做量優化效率。緊接着咱們會在項目中增長 Freekite 的持續集成,在項目的每個階段進行流程上的自動化迴歸驗證,業務邏輯覆蓋率的問題就基本解決了。下圖爲 Freekite 可視化 Case 管理的一個應用示例。
不一樣的角度對用戶體驗有不一樣的分拆方法,從前端角度講,我把用戶體驗分爲如下兩個方向:
前端主要在「交互體驗」 中的功能體驗和界面體驗上尋求優化。
Titans 是美團點評解決 Hybrid 功能體驗的一個集團範圍的解決方案,它爲 Hybrid 模式的產品封裝 Native 的能力供 Web 調用,其能力包括幾個大的方向:
業務能夠在 Titans 的基礎上構建豐富的 Hybrid 應用,既能享受無需發版便可更新迭代的優點,又可使用 Native 的大多數功能。
在解決了功能體驗後,接下來咱們再說界面體驗的問題。
談到界面體驗咱們不得不從新講起 Hybrid,我的認爲在解決功能體驗的前提下 Hybrid 存在如下主要的優點和劣勢:
針對 Hybrid 的劣勢,行業內現有的解決方案有不少,典型的有 Facebook 的 React Native 和阿里的 Weex,除去其它因素,只講技術自己,它們有幾個共同點:
因而可知行業內解決此類問題的關鍵套路就是使用 Native 來呈現。
那麼回到問題自己,爲何 Native 不存在此類問題而網頁存在,通過研究咱們發現有如下兩個主要區別:
關於第一個區別你們可能存在一些困惑,這裏咱們舉個例子,下圖就是 Native 爲何沒有白屏的根本緣由:
如圖所示,Native 從視圖 A 跳轉到視圖 B,當用戶點擊 A 中的按鈕觸發跳轉到 B 的動做時,B 的代碼會開始執行,只有當 B 已經加載完成後,系統纔會讓 A 跳轉到 B,在 iOS 中的生命週期是 viewWillAppear,在此以前 viewDidLoad 已經執行完畢,Android 也是類似的生命週期。再加上 Native APP 的資源是本地化的,Native APP 有更多的運算資源和系統級別優化,它能夠把這個加載過程時間縮短到接近瞬間。而把界面繪製和加載代碼寫到 viewWillAppear 以前是這些廠商指導咱們去這樣作的,而且提供了相應的系統級別支持。這時候咱們思考一個問題,若是 Native 代碼將界面繪製的代碼寫到 viewDidAppear 中會發生什麼?答案是也會出現白屏。
因而可知,並非純 Native 必定體驗好,若是你不按照廠商的指導要求作,體驗同樣很差。
當咱們想清楚緣由後咱們就開始作了一個界面體驗技術,名字叫 Enhanced Hybrid (加強混合),簡稱 EH。
EH 的核心是「解決 Hybrid 與 Native 體驗差別的技術瓶頸」。它包括兩個部分,第一個部分是一個 Native SDK,有目前咱們積累的全部解決體驗差別技術瓶頸的功能,第二個部分是界面體驗指南,也就是如何讓咱們的 Web 頁面變的界面體驗更好。
舉個例子,在剛剛的白屏例子中,咱們能夠看到一個重要的信息,A 跳轉到 B 的時候,當 A 中點擊執行跳轉動做時第二個界面就已經開始執行了,在 B 執行完渲染部分以前系統不會執行 A 到 B 的實際界面跳轉動做。這個操做在 Web 中是不可行的,咱們沒法在 Web 中讓 B 在跳轉前執行完渲染部分的代碼。
那麼無白屏的前提條件是什麼?
無白屏的前提條件是渲染完成,或者至少渲染到一個用戶跳轉過來有東西,不會給人突兀的感受。
咱們思考這個裏面的技術瓶頸是什麼?
當咱們想清楚這個技術瓶頸之後動手解決了這兩個問題。首先,B 的渲染完成並非一個絕對的狀態,而是由研發本身知道本身控制的,研發能夠在到達這個狀態的時候把狀態主動通知出去。第二咱們費了一些周折,在兩個平臺中能夠經過一些技術去控制 A 等待一個通知,再讓 B 展現出來,最終結合起來的方案以下圖所示:
單獨使用此技術會遇到在 A 等待時間長的問題,再輔以「離線化技術」即可以完美解決。(離線化技術會在後面詳細講)
EH 目前全部的功能包含:
目前還有更多黑科技功能在逐漸增長中,上述技術當中前三個已經成功申請專利。
不少人會存有疑問,爲何咱們不使用 React Native 或者 Weex,而是本身作一個體驗技術?
使用此類技術存在這麼幾個問題:
平臺化而非插件化:使用此類技術後,你的總體前端業務代碼就要所有構建在這個平臺之上,若是平臺出現問題或者架構更新,轉型成本是徹底重寫一套業務代碼。而採用插件化方案,加了體驗會更好,沒有也能夠降級,這樣轉型的成本會少不少
技術棧捆綁:每個技術都有捆綁的一個生態,在用 RN 的時候你必須使用 React ,在用 Weex 的時候必修使用 Vue,轉型成本一樣高,且限制了業務選型
解決問題被動:當系統更新或技術自己出現質量問題的時候,業務的研發團隊幾乎沒有能力去解決,只能等待技術官方研發團隊或開源社區去解決,這會使咱們的業務很被動
EH 自己不捆綁任何技術,即便你不使用任何的框架也能夠完整使用 EH 的功能。
體驗 EH 功能能夠在應用商店中下載 「美團錢包」,在首頁中點擊手機充值、生活繳費或「優惠」 Tab 中的內容。
Server Side Rendering 這裏就很少贅述了,你們都瞭解。構建時預渲染技術是咱們特殊研發的一個技術。它的特色是從首幀速度優化角度來說,理論上比 SSR 更快更穩定。
構建時預渲染技術主要實現方式是:在編譯完成後,啓動一個 Web Server 來運行整個網站,再開啓多個無頭瀏覽器(Headless Chrome,PhantomJS 等無頭瀏覽器技術)去請求全部項目的路由,當被請求的網頁渲染到第一個有意義的渲染時(FMP 參考 Google 的衡量體系)主動拋出一個事件,該事件由無頭瀏覽器截獲,無頭瀏覽器截獲後將此時的頁面 HTML 內容保存下來生成一個 HTML。最終發佈這個 HTML。此 HTML 中包含 FMP 所須要的全部 CSS 及 DOM 結構。
事實上 SSR 和構建時預渲染技術都是爲首幀速度優化服務的,首幀速度優化的核心有兩點:
爲何說構建時預渲染會比 SSR 快呢?
SSR 目前前端領域主流實現方式是使用 Node 做爲中間層,負責數據的獲取和界面的拼裝,其 Node 層可能後面對接着一個或多個數據來源(業務系統),它的響應速度受限於最慢的那個數據來源。而構建時預渲染劣勢是不包含數據,但優點是其首幀事件徹底不依賴任何數據來源,從 Nginx 層直接返回,響應速度更快,同時流量負載更高。
爲何說構建時預渲染會比 SSR 更穩定?
SSR 在 Nginx 層後面還須要一層 Node(典型架構)作支撐 ,而構建時預渲染從 Nginx 層直接返回,其關鍵鏈路上少了一環須要保障穩定性的服務,因此穩定性更強。
金融服務平臺在 SSR 和構建時預渲染上都有不少項目在運行,在 SSR 的優化上也有豐富的經驗去保障速度和穩定性,在選型上的考量主要是首幀對數據的依賴程度。
離線化技術能夠將網頁的網絡加載時間變爲 0,在離線化的選型上美團點評內部有不少選擇,咱們也在不一樣的方向進行嘗試。其中咱們的選擇包括:
留下來的只剩下兩個自有技術,這兩個技術的最大區別是,是否解決了首次加載問題?離線化方案的首次加載問題是一個很難的技術領域,我認爲其最核心的問題是什麼時候加載,提早加載會不會用戶在很長一段時間內都不會用到致使浪費流量?使用包含首次加載優化的離線化技術的項目多了會不會形成加載擁塞?是否是須要分析用戶行爲數據去更精準的進行離線包的提早加載?這當中存在太多不肯定性,不過我相信咱們的技術團隊必定可以想出優美的解決方案去解決這個問題。
另外基於 Native 能力的離線化技術還存在一些來自平臺的限制,如 iOS 的 WKWebView 不支持請求攔截,而請求攔截是離線化的關鍵技術,這個緣由致使在 WKWebView 上沒法實現離線化。
WKWebView 的優點是:運行和渲染速度更快,與 Safari 內核一致 Apple 重點迭代跟進問題;劣勢是:啓動速度慢,沒法攔截請求進而使用自有的離線化技術。
權衡離線化所帶來的巨大優點和 WKWebView 的速度優點,咱們選擇繼續使用 UIWebView。(曾經在 iOS 11 發佈前業界一度認爲 Apple 會在 iOS 11 中支持 WKWebView 的請求攔截)
字符級增量更新方案是一個前端領域研究了好久的課題,智能支付團隊近期在這一領域有了突破性進展,這個技術方案能夠經過字符級增量更新減小文件傳輸大小,節省流量、提升頁面成功率和加載速度。其中增量計算能力由美團平臺的靜態資源託管方案 Build Service 支持。主要應用在掃碼付項目上。
掃碼付項目是美團金融智能支付團隊面向 C 端消費者推出的一款 H5 融合支付類的產品,消費者在商家消費以後,可以使用多種 App 進行掃碼支付,同時可對商家進行評價,支持美團、大衆點評、微信、支付寶、美團錢包等多種 App,目前業務日均 PV 千萬級。
字符級增量更新方案的詳細介紹,請參考以前的文章美團金融掃碼付靜態資源加載優化實踐。
美團點評內部前端監控系統包括:
在技術棧統一前,咱們團隊這三個監控工具在同時使用,然而監控系統上前端和後端不一樣的是前端對代碼尺寸有要求,接入的監控系統多會對項目的加載速度有影響。綜合多方面因素,咱們在本次技術棧統一中選擇了CAT來做爲咱們主要的監控系統。主要是它包含前二者的功能。
CAT(詳情能夠參考《深度剖析開源分佈式監控CAT》 一文)是一個美團點評的全端基礎監控組件,在後端爲各業務線提供全面的監控服務和決策支持,提供系統的性能指標、健康情況、基礎告警等功能。在前端覆蓋美團點評全部APP,提供近實時的多維數據分析、立體式監控、告警等功能。提供了近實時的多維數據分析,立體式監控功能。
CAT很大的優點是它是一個實時系統,從數據生成到服務端處理結束是秒級別,秒級定義是 48 分鐘 40 秒時基本上能看到 48 分鐘 38 秒的數據,總體報表的統計粒度是分鐘級;第二個優點,數據是接近全量統計,目前大約5%的高QPS 項目是採樣統計。
目前咱們使用的協議均爲 HTTP/2,支付是金融最先使用 HTTP/2 的部門,因爲支付業務的特殊性,在一開始咱們就是使用的 HTTPS ,進而很早就使用上了 SPDY。
在15年 HTTP/2 標準化的時候咱們直接更新集羣使用上了 HTTP/2,在 SPDY 和 HTTP/2 這種具備多路複用功能的協議上咱們的前端架構所有作的都是按需加載的方式,大大減少了由「減小請求數」 所帶來的流量冗餘。最大化利用了 HTTP 自己的緩存機制,經過減少客戶端大小的方式大大提高了網絡加載性能。
安全方面在前端咱們使用:
同時在覈心接口上咱們有一個自研的網頁請求籤名方案,來在必定程度上保障請求是從咱們的客戶端中正常發出的。
以上是對金融平臺前端技術體系的介紹和我的的一些思考,最後說一下采用此技術體系所達到的一些效果。
使用這幾項技術的一個直接感覺是人效大幅提高,一個前端同窗能夠並行 2~4 個項目,同時對接 4~10 個後端研發。
在使用 Titans 解決功能體驗,使用 EH 解決界面體驗的狀況下,加上構建時預渲染和離線化技術的加持,咱們能夠作出專業前端都看不出來是 Hybrid 的高體驗 Hybrid 應用。
在質量方面咱們有:
在整個質量體系架構的演進過程當中,其實不僅是這些工具來保障質量和可用性,還會有不少流程規範去保障,在可用性保障上感興趣能夠參考這篇文章:《前端可用性保障實踐》。
在這些實踐中咱們很好的保障了產品的穩定運行。同時也歡迎你們在前端可用性保障上多探討。
最後,金融平臺的技術體系仍是在不斷快速演進中,而前端領域也是一個快速演進的領域,咱們須要更多的優秀人才加入,感興趣的小夥伴能夠將簡歷發送到我所在的錢包團隊,郵箱:chenyulin02[at]meituan.com,或將簡歷投送到金融平臺(詳見:美團點評招聘官網)。同時團隊提供大量 Web 前端、Android、iOS、Java 實習機會,尋找實習機會的同窗也能夠將簡歷發到個人郵箱中。
如發現文章有錯誤、對內容有疑問,均可以關注美團技術團隊微信公衆號(meituantech),在後臺給咱們留言。
咱們每週會挑選出一位熱心小夥伴,送上一份精美的小禮品。快來掃碼關注咱們吧!