Picasso:開啟大前端的未來

Picasso:開啟大前端的未來

來自專欄美團技術博客

背景

Picasso是大眾點評移動研發團隊自研的高性能跨平台動態化框架,經過兩年多的孕育和發展,目前在美團多個事業群已經實現了大規模的應用。

Picasso源自我們對大前端實踐的重新思考,以簡潔高效的架構達成高性能的頁面渲染目標。在實踐中,甚至可以把Native技術向Picasso技術的遷移當做一種性能優化手段;與此同時,Picasso在跨越小程序端和Web端方面的工作已經取得了突破性進展,有望在四端(Android、iOS、H5、微信小程序)統一大前端實踐的基礎之上,達成高性能大前端實踐,同時配合Picasso布局DSL強表達能力和Picasso代碼生成技術,可以進一步提升生產力。

客戶端動態化

2007年,蘋果公司第一代iPhone發布,它的出現「重新定義了手機」,並開啟了移動互聯網蓬勃發展的序幕。Android、iOS等移動技術,打破了Web應用開發技術即將一統江湖的局面,之後海量的應用如雨後春筍般湧現出來。移動開發技術給用戶提供了更好的移動端使用和交互體驗,但其「靜態」的開發模式卻給需要快速迭代的互聯網團隊帶來了沉重的負擔。

客戶端「靜態」開發模式

客戶端開發技術與Web端開發技術相比,天生帶有「靜態」的特性,我們可以從空間和時間兩個維度來看。

從空間上看需要集成發布

美團App承載業務眾多,是跨業務合流,橫向涉及開發人員最多的公司,雖然開發人員付出了巨大的心血完成了業務間的組件化解耦拆分,但依然無可避免的造成了以下問題:

  1. 編譯時間過長。 隨著代碼複雜度的增加,集成編譯的時間越來越長。研發力量被等待編譯大量消耗,集成檢查也變成了一個巨大的挑戰。
  2. App包體增長過快。 這與迅猛發展的互聯網勢頭相符,但與新用戶拓展和業務迭代進化形成了尖銳矛盾。
  3. 運行時耦合嚴重。 在集成發布的包體內,任何一個功能組件產生的Crash、內存泄漏等異常行為都會導致整個App可用性下降,帶來較大的損失。
  4. 集成難度大。 業務線間代碼復用耦合,業務層、框架層、基礎服務層錯綜複雜,需要拆分出相當多的兼容層代碼,影響整體開發效率。

從時間上看需要集中發布

線上Bug修復鬚髮版或熱修復,成本高昂。新功能的添加也必須等待統一的發版周期,這對快速成長的業務來說是不可接受的。App開發還面臨嚴重的長尾問題,無法為使用老版本的用戶提供最新的功能,嚴重損害了用戶和業務方的利益。

這種「靜態」的開發模式,會對研發效率和運營質量產生負面影響。對於傳統的桌面應用軟體開發而言,靜態的研發模式也許是相對可以接受的。但對於業務蓬勃發展的移動互聯網行業來說,靜態開發模式和敏捷迭代發布需求的矛盾日益突出。

客戶端動態化的趨勢

如何解決客戶端「靜態」開發模式帶來的問題?

業界最早給出的答案是使用Web技術

但Web技術與Native平台相比存在性能和交互體驗上的差距。在一些性能和交互體驗可以妥協的場景,Web技術可以在定製容器、離線化等技術的支持下,承載運營性質的需要快速迭代試錯的頁面。

另一個業界給出的思路是優化Web實現

利用移動客戶端技術的靈活性與高性能,再造一個「標準Web瀏覽器」,使得「Web技術」同時具有高性能、良好的交互體驗以及Web技術的動態性。這次技術浪潮中Facebook再次成為先驅,推出了React Native技術(簡稱RN)。不過RN的設計取向有些奇怪,RN不兼容標準Web,甚至不為Android、iOS雙端行為對齊做努力。產生的後果就是所有「吃螃蟹」的公司都需要做二次開發才能基本對齊雙端的訴求。同時還需要盡最大努力為RN的兼容性問題、穩定性問題甚至是性能問題買單。

而我們給出的答案是Picasso

Picasso另闢蹊徑,在實現高性能動態化能力的同時,還以較強的適應能力,以動態頁面、動態模塊甚至是動態視圖的形式融入到業務開發代碼體系中,贏得了許多移動研發團隊的認同。

Picasso框架跨Web端和小程序端的實踐也已經取得了突破性進展,除了達成四端統一的大前端融合目標,Picasso的布局理念有望支持四端的高性能渲染,同時配合Picasso代碼生成技術以及Picasso的強表達能力,生產力在大前端統一的基礎之上得到進一步的提升。

Picasso動態化原理

Picasso應用程序開發者使用基於通用編程語言的布局DSL代碼編寫布局邏輯。布局邏輯根據給定的屏幕寬高和業務數據,計算出精準適配屏幕和業務數據的布局信息、視圖結構信息和文本、圖片URL等必要的業務渲染信息,我們稱這些視圖渲染信息為PModel。PModel作為Picasso布局渲染的中間結果,和最終渲染出的視圖結構一一對應;Picasso渲染引擎根據PModel的信息,遞歸構建出Native視圖樹,並完成業務渲染信息的填充,從而完成Picasso渲染過程。需要指出的是,渲染引擎不做適配計算,使用布局DSL表達布局需求的同時完成布局計算,即所謂「表達即計算」。

從更大的圖景上看,Picasso開發人員用TypeScript在VSCode中編寫Picasso應用程序;提交代碼後可以通過Picasso持續集成系統自動化的完成Lint檢查和打包,在Picasso分發系統進行灰度發布,Picasso應用程序最終以JavaScript包的形式下發到客戶端,由Picasso SDK解釋執行,達成客戶端業務邏輯動態化的目的。

在應用程序開發過程中,TypeScript的靜態類型系統,搭配VSCode以及Picasso Debug插件,可以獲得媲美傳統移動客戶端開發IDE的智能感知和斷點調試的開發體驗。Picasso CI系統配合TypeScript的類型系統,可以避免低級錯誤,助力多端和多團隊的配合;同時可以通過「兼容計算」有效的解決能力支持的長尾問題。

Picasso布局DSL

Picasso針對移動端主流的布局引擎和系統做了系統的對比分析,這些系統包括:

  1. Android開發常用的LinearLayout。
  2. 前端及Picasso同類動態化框架使用的FlexBox
  3. 蘋果公司主推的AutoLayout

其中蘋果官方推出的AutoLayout缺乏一個好用的DSL,所以我們直接將移動開發者社區貢獻的AutoLayout DSL方案列入對比。

首先從性能上看,AutoLayout系統是表現最差的,隨著需求複雜度的增加「布局計算」耗時成指數級的增長。FlexBox和LinearLayout相比較AutoLayout而言會在性能表現上有較大優勢。但是LinearLayout和FlexBox會讓開發者為了布局方面需要的概念增加不必要的視圖層級,進而帶來渲染性能問題。

從靈活性上看,LinearLayout和FlexBox布局有很強的概念約束。一個強調線性排布,一個強調盒子模式、伸縮等概念,這些模型在布局需求和模型概念不匹配時,就不得不藉助編程語言進行干預。並且由於布局系統的隔離,這樣的干預並不容易做,一定程度上影響了布局的靈活性和表達能力。而配合基於通用編程語言設計的DSL加上AutoLayout的布局邏輯,可以獲得理論上最強的靈活性。但是這三個布局系統都在試圖解決「用聲明式的方式表達布局邏輯的問題」,基於編程語言的DSL的引入讓布局計算引擎變得多餘。

Picasso布局DSL的核心在於:

  1. 基於通用編程語言設計。
  2. 支持錨點概念(如上圖)。

使用錨點概念可以簡單清晰的設置非同一個坐標軸方向的兩個錨點「錨定」好的視圖位置。同時錨點可以提供描述「相對」位置關係語義支持。事實上,針對布局的需求更符合人類思維的描述是類似於「B位於A的右邊,間距10,頂對齊」,而不應該是「A和B在一個水平布局容器中……」。錨點概念通過極簡的實現消除了需求描述和視圖系統底層實現之間的語義差距。

下面舉幾個典型的例子說明錨點的用法:

1. 居中對齊:

view.centerX = bgView.width / 2 view.centerY = bgView.height /2

2. 右對齊:

view.right = bgView.width - 10 view.centerY = bgView.height / 2

3. 相對排列:

viewB.top = viewA.top viewB.left = viewA.right + 10

4. 「花式」布局:

viewB.top = viewA.centerY viewB.left = viewA.centerX

Picasso錨點布局邏輯具有理論上最為靈活的的表達能力,可以做到「所想即所得」的表達布局需求。但是有些時候我們會發現在特定的場景下這樣的表達能力是「過剩的」。類似於下圖的布局需求,需要水平排布4個視圖元素、間距10、頂對齊;可能會有如下的錨點布局邏輯代碼:

v1.top = 10 v1.left = 10 v2.top = v1.top v3.top = v2.top v4.top = v3.top v2.left = v1.right + 10 v3.left = v2.right + 10 v4.left = v3.right + 10

顯然這樣的代碼不是特別理想,其中有較多可抽象的重複的邏輯,針對這樣的需求場景,Picasso提供了hlayout布局函數,完美的解決了水平排布的問題:

hlayout([v1, v2, v3, v4], { top: 10, left: 10, divideSpace: 10 })

有心人可以發現,這和Android平台經典的LinearLayout如出一轍。對應hlayout函數的還有vlayout,這一對幾乎完整實現Android LinearLayout語義的兄弟函數,實現邏輯不足300行,這裡強調的重點其實不在於兩個layout函數,而是Picasso布局DSL無限制的抽象表達能力。如果業務場景中需要類似於Flexbox或其他的概念模型,業務應用方都可以按需快速的做出實現。

在性能方面,Picasso錨點布局系統避免了「聲明式到命令式」的計算過程,完全無需布局計算引擎的介入,達成了「需求表達即計算」的效果,具有理論上最佳性能表現。

由此可見,Picasso布局DSL,無論在性能潛力和表達能力方面都優於以上布局系統。Picasso布局DSL的設計是Picasso得以構建高性能四端動態化框架的基石。

同時得益於Picasso布局DSL的表達能力和擴展能力,Picasso在自動化生成布局代碼方面也具有得天獨厚的優勢,生成的代碼更具有可維護性和擴展性。伴隨著Picasso的普及,當前前端研發過程中「視覺還原」的過程會成為歷史,前端開發者的經歷也會從「複製」視覺稿的重複勞動中解脫出來。

Picasso高性能渲染

業界對於動態化方案的期待一直是「接近原生性能」,但是Picasso卻做到了等同於原生的渲染效率,在複雜業務場景可以達成超越原生技術基本實踐的效果。就目前Picasso在美團移動團隊實踐來看,同一個頁面使用Picasso技術實現會獲得更好的性能表現。

Picasso實現高性能的基礎是宿主端高效的原生渲染,但實現「青出於藍而勝於藍」的效果卻有些反直覺,在這背後是有理論上的必然性的:

  • Picasso的錨點布局讓 布局表達和布局計算同時發生。避免了冗餘反覆的布局計算過程。
  • Picasso的布局理念使 視圖層級扁平。所有的視圖都各自獨立,沒有為了布局邏輯表達所產生的冗餘層級。
  • Picasso設計支持了 預計算的過程。原本需要在主線程進行計算的部分過程可以在後台線程進行。

在常規的原生業務編碼中,很難將這些優化做到最好,因為對比每個小點所帶來的性能提升而言,應用邏輯複雜度的提升是不能接受的。而Picasso渲染引擎,將傳統原生業務邏輯開發所能做的性能優化做到了「統一復用」,實現了一次優化,全線受益的目標。

Picasso在美團內部的應用

Picasso跨平台高性能動態化框架在集團內部發布後,得到了廣泛關注,集團內部對於客戶端動態化的方向也十分認可,積極的在急需敏捷發布能力的業務場景展開Picasso應用實踐;經過大概兩年多的內部迭代使用,Picasso的可靠性、性能、業務適應能力受到的集團內部的肯定,Picasso動態化技術得到了廣泛的應用。

通過Picasso的橋接能力,基於Picasso的上層應用程序仍然可以利用集團內部移動技術團隊積累的高質量基礎建設,同時已經形成初步的公司內部大生態,多個部門已經向Picasso生態貢獻了動畫能力、動態模塊能力、復用Web容器橋接基建能力、大量業務組件和通用組件。

Picasso團隊除了持續維護Picasso SDK,Picasso持續集成系統、包括基於VSCode的斷點調試,Liveload等核心開發工具鏈,還為集團提供了統一的分發系統,為集團內部大前端團隊開展Picasso動態化實踐奠定了堅實的基礎。

到發稿時,集團內部Picasso應用領先的BG已經實現Picasso動態化技術覆蓋80%以上的業務開發,相信經過更長時間的孵化,Picasso會成為美團移動開發技術的「神兵利器」,助力公司技術團隊實現高速發展。

列舉Picasso在美團的部分應用案例:

Picasso開啟大前端未來

Picasso在實踐客戶端動態化的方向取得了成功,解決了傳統客戶端「靜態」研發模式導致的種種痛點。總結下來:

  1. 如果想要 敏捷發布,使用Picasso。
  2. 如果想要 高交付質量,使用Picasso。
  3. 如果想要 優秀用戶體驗,使用Picasso。
  4. 如果想要 高性能表現,使用Picasso。
  5. 如果想要 自動化生成布局代碼,使用Picasso。
  6. 如果想要 高效生產力,使用Picasso。

至此Picasso並沒有停止持續創新的腳步,目前Picasso在Web端和微信小程序端的適配工作已經有了突破性進展,正如Picasso在移動端取得的成就一樣,Picasso會在完成四端統一(Android、iOS、Web、小程序)的同時,構建出更快、更強的大前端實踐。

業界對大前端融合的未來有很多想像和憧憬,Picasso動態化實踐已經開啟大前端未來的一種新的可能。Picasso暫時還未開源,如對Picasso有興趣,歡迎加入大眾點評的大家庭。

作者簡介

曉燕,Picasso核心SDK團隊負責人,八年移動應用開發經驗,2012年加入大眾點評。Picasso 核心SDK團隊致力於探索更好的客戶端動態化實踐方案,貢獻和維護高性能高可靠性的Picasso SDK,同時推進Picasso的應用和大生態的引導和建設。

大為 ,Picasso項目負責人,點評平台移動技術負責人,點評平台在持續交付點評平台性產品的同時,持續輸出支撐集團移動技術的框架和方案;點評平台移動技術團隊同時也是廣義的Picasso團隊,全面參與建設了Picasso工具鏈,Picasso持續集成系統,Picasso分發系統,Picasso核心UI組件,點評平台會持續助力集團移動端業務的動態化演進。

也許你還想看

WWDC案例解讀:大眾點評相機直接掃描支付是怎麼實現的

大眾點評賬號業務高可用進階之路

美團點評金融平台Web前端技術體系

weixin.qq.com/r/9HVSSg3 (二維碼自動識別)

推薦閱讀:

魔都夜生活的正確方式:夜宵、蹦迪還是加班?
要錢不要臉的大眾點評,在我的推廣頁加同行的廣告,還有職業道德嗎?
廈門大眾點評火鍋描述性分析
米其林上榜餐廳唐閣無緣大眾點評必吃榜,原因何在?
大眾點評App的短視頻耗電量優化實戰

TAG:前端開發 | 前端框架 | 大眾點評 |