凹凸技術揭祕 · Deco 智能代碼 · 開啓產研效率革命

作者:凹凸曼

1、背景介紹

近幾年中臺的興起,團隊圍繞業務中臺化這個場景,將我們已有的諸多能力進行解構、重組、積木化,希望能將拆解後的積木進行體系化地串聯,從而達到降本增效的目的。

對於電商平臺來說,每年都需要面臨大量的大促活動頁面需求,對於如何提高頁面產出效率,大家都不約而同採用「頁面可視化搭建」解決方案。對應的,我們也構建了「羚瓏可視化頁面搭建平臺」。但近兩年大促活動定製化需求井噴,平臺有限的組件模塊已無法滿足產品運營需求,前端工程師也無法再用「複用」的思想簡單地解決問題。當業務發展到一定程度,有限的人力以及冗長的開發流程更是無法滿足蓬勃發展的業務需求。

我們需要「求變」,傳統的人力密集型研發無法解決的問題,是否能用智能化的思想來解決呢?順着這個方向,我們把目標瞄準了「前端智能化」,希望藉助 AI 和機器學習的能力拓展前端能力圈,打通設計與研發的工作流程,實現規模化生產。

2、項目介紹

Deco 智能代碼項目是團隊在「前端智能化」方向上的探索,我們嘗試從設計稿生成代碼(DesignToCode)這個切入點入手,對現有的設計到研發這一環節進行能力補全,進而提升產研效率。

在一個日常需求開發流程中,往往需要遵循固定的一套工作流程,產品提交需求 PRD,交互設計師根據 PRD 輸出交互稿,再由視覺設計師輸出產品視覺稿,接着再進入前端開發工作流。對於前端工程師來說,輸入源是視覺稿 + PRD,輸出結果是可上線的頁面代碼。

傳統開發流程

Deco 期望解決的是上述流程中,對於前端工程師而已相對低價值,以及可用複用思想處理的工作:

  • UI 視覺稿還原,即頁面重構,編寫 HTML + CSS;
  • 可複用的業務邏輯綁定;

Deco新研發流程

以「設計稿生成代碼」爲切入點,我們需要用智能化的解決方案來替代傳統的人工頁面重構(分析圖層樣式+切圖等),期望能從視覺稿原始信息中提取結構化的數據描述,進而再與智能佈局等算法結合,輸出可維護的頁面代碼。

3、技術方案

設計稿智能生成代碼能力的核心是如何生成一份「結構化的數據描述」信息,這份數據稱爲 D2C Schema。

Deco 設計稿智能生成代碼主要做了兩件事情:

  1. 從視覺稿中提取「結構化的數據描述」;
  2. 將「結構化的數據描述」表達成代碼;

本質上,Deco 智能代碼是通過設計工具插件從視覺稿原始信息中提取結構化的數據描述(D2C Schema),然後結合規則系統、計算機視覺、智能佈局、深度學習等技術對 D2C Schema 進行處理,轉換爲佈局合理且語義化的 D2C Schema JSON 數據,最後再借助 DSL 解析器轉換爲多端代碼。

流程圖

Deco 智能代碼的核心鏈路構成了團隊「前端智能化」探索的核心技術體系,圍繞產研流程的體系化建設,結合 Cloud IDE、Taro 多端統一解決方案、設計研發資產平臺,以及羚瓏智能設計等能力,實現一個良性的產研閉環,爲整體的工程鏈路降本提效。

4、智能代碼技術分層

Deco 智能代碼核心鏈路現階段主要包含組件識別、圖層處理、佈局算法以及語義化處理四大分層,下面會圍繞這些細分的分層展開內部實現原理的剖析。

4.1 組件識別層

組件識別層負責識別設計稿圖片中的元素,包括業務組件識別、基礎組件識別以及區塊識別。 通過識別能力,輸出設計稿中與現有組件庫組件匹配的部分,進行組件推薦與複用,並輔助後續處理層處理,比如語義處理層等根據組件屬性進行語義化命名,提高生成代碼的可用性。

4.1.1 組件識別

組件識別層藉助了AI能力,使用深度學習目標檢測算法來進行識別,輸入設計稿導出的圖片,輸出圖片中的組件類別及組件位置。

4.1.2 數據集

數據集是使用深度學習處理問題的大頭,我們彙集了羚瓏平臺活動頁數據、大促會場設計稿以及Relay平臺數據,構建了含有2w+樣本的組件識別數據集。其中,引入了自動化標註,通過對使用組件搭建的羚瓏頁面進行Dom結構解析,獲得絕對精準的標註數據,減少人工標註成本。

爲了進一步地豐富數據集,解決組件之間數量不均衡的問題,採用了自動化樣本生成方案,基於Quark 官方業務組件庫以及大促會場沉澱的 jdcop 大促原子組件庫,支持十類樣本生成。採用組件模版搭配隨機屬性的方式,由組件組成完整的頁面,並在導出的過程中自動進行標註。

4.1.3 區塊識別

移動端設計稿大部分高寬比過長,有達到 10:1 以上的,且分佈不均,不利於目標檢測識別,由此,首先將頁面劃分爲區塊,區塊識別算法基於傳統圖像處理流程,使用邊緣檢測以及漫水填充算法獲得連通區域,設置過濾閾值留下樓層大小的識別框。

區塊識別算法應用於圖層處理層自動成組,優化圖層的嵌套結構,助力於佈局算法產生更合理的組件結構樹。 此外,將未識別區域自動劃分爲新樓層。通過固定高度限制,臨近區塊組合爲一個更大粒度的區塊,達到將不等高度的設計稿劃分爲高度相差不大的幾個區域的效果,再投入目標檢測網絡進行識別。

4.2 圖層處理層

圖層處理層主要將設計稿中的圖層進行分離、合併、提取元信息,同時結合組件識別層智能成組、分類,導出第一份 Deco Schema DSL。Deco 工作流就像軟件工程裏的管道與過濾器設計模式,設計稿就是管道的入參,管道中的流就是每一階段生成的 DSL,管道的輸出是一份語義化代碼。

圖層處理層通過藉助組件識別層的 AI 能力,智能識別設計稿每個區塊,將區塊內的圖層信息合成一個組,再通過區塊匹配算法自動匹配區塊與圖層,實現了設計稿的自動成組,成組數據有利於佈局算法判斷區塊的層級信息和父子關係。

一份 Sketch 文稿是由若干圖層元信息(分爲 Document 和 Pages 等)和資源文件(主要是圖片)組成的一個壓縮文檔(文件後綴爲“.sketch”),我們通過對圖層元信息進行加工處理後得到一份供佈局算法服務處理的 DSL。

通過開發 Sketch 插件,使用 Sketch 提供的 API 能夠幫助我們去操作 Sketch 裏的文稿,拿到圖層信息後,對這些數據加工、篩選等處理。圖層信息的處理主要是分爲兩層:

  1. 設計稿加工層:

    1. 複製出一份原樣的設計稿,在這份複製的設計稿上進行各種加工的操作;
    2. Symbol 解耦,將文稿中的 Symbols 解耦爲實際的圖層組;
    3. 篩選不可見圖層,過濾掉設計師隱藏的圖層以及空圖層組;
    4. 圖層合併,將一些特殊的圖層或圖層組合並,並轉爲圖片;
    5. 蒙層處理,蒙層下的圖片如果超出蒙層範圍需要裁剪,同時蒙層下的圖層位置和寬高信息需要重置。
  2. 圖層信息處理層:

    1. 提取圖層中有用的信息,比如樣式處理、文字拆分、圖層層級等;
    2. 圖層信息的轉化,比如將圖片的 base64 位字符串數據轉爲 CDN 圖片地址;
    3. 無用圖層檢測,將一些無樣式或透明樣式的圖層去除;
    4. 圖層打平處理,將圖層數據由樹狀的層級打平爲一維的結構;
    5. 成組信息篩選,將未成組的數據通過比對位置和大小將其歸類到已成組的數據中。

下圖是對圖層信息的處理流程:

除了對圖層信息的基礎處理之外,我們建立了一系列的數據導出的優化規則,用於增加布局以及語義的合理性。比如在一些大促設計稿上,複雜背景圖的設計可能是在一個圖層組下由若干個矢量圖形組成(如下圖),如果原封不動地將這些圖層導出,會給佈局帶來很多複雜度和不確定性。

在合圖的這一流程中,針對一個圖層組下所有圖層都是矢量圖形的情況,我們會將它合成爲一張圖片,這樣會大大減輕佈局的困難度。最終合圖效果如下圖:

當然,上面提到的這些優化規則並不能滿足所有的情況,畢竟設計師是自由的。爲了提高佈局和語義的合理性,我們對入參的設計稿提了一些規範協議供設計師以及開發者使用。

4.3 佈局算法層

4.3.1 爲什麼需要佈局算法

佈局算法是建立在輸入源符合 Deco Schema 規範的數據,該數據規範可以通過 Deco Sketch 插件對視覺高進行處理,最終會導出設計元素信息。

經過 Deco Sketch 插件導出的元素數據,都是以左上角 (0, 0) 爲座標原點座標的絕對定位爲基礎的元素信息,並且在一般情況下(無主動編組、無AI識別等等情況 )元素都是扁平化的,也就是元素間沒有從屬關係。

在前端開發過程中,絕對定位佈局無論是擴展性、可讀性都達不到開發要求,那麼如果不解決,就成爲 一次性代碼 。因此,需要佈局算法來提高生成代碼的擴展性、可讀性,供後續二次開發使用。

4.3.2 佈局層核心算法

佈局算法層的設計包含三大層:數據結構轉換層、佈局推導層、樣式計算層。

4.3.2.1 數據轉換層

數據結構轉換層是將 Deco Schema JSON 數據轉換爲類似 DOM 樹的結構,可以進行節點插入、刪除、查找操作。

下面是 LayoutNode 基本數據結構:

LayoutNode {
  ...省略節點屬性
 
  ...部分節點方法
  appendChild (child) {}
  prependChild (child) {}
  insertAfter (insertedChild, afterChild) {}
  insertBefore (insertedChild, beforeChild) {}
  replaceChild (newChild, replacedChild) {}
  removeChild (child) {}
  get x () {}
  get y () {}
  get width () {}
  get height () {}
  get offsetLeft () {}
  get offsetTop () {}
  get previousSibling () {}
  get nextSibling () {}
  intersect (node) {}
  contains (node) {}
  disjoint (node) {}
  tangent (node) {}
  hitTest (node) {
  ...
}
4.3.2.2 佈局推導層

佈局推導層則是進行行列分割推導,總體上包含:空間佈局算法、投影佈局算法、背景圖佈局算法、特徵檢測佈局算法、座標推導算法、背景圖層及冗餘圖層檢測算法等等。

![](https://img12.360buyimg.com/img/s510x296_jfs/t1/166468/16/224/48801/5fed9913E97706fe1/d3fab3b55e7f022a.jpg![](

其中特徵檢測包括標題、列表、Tab 等等一些列常見的佈局檢測。

4.3.2.3 樣式計算層

樣式計算層,是對經過佈局推導層得到的結果進行一系列的計算,而 Deoc 樣式大部分佈局採用 Flexbox,有些特殊情況需要使用絕對定位。在佈局推導之後,Layout 結構已經有了明晰的層級關係及相鄰關係。

基於層級關係,可以通過座標計算得出 Flexbox 主軸、側軸;基於相鄰關係,可以計算出相鄰之間的 margin 等等樣式。

4.4 語義化層

當設計稿數據經過佈局算法處理後我們就能獲得結構較爲良好的代碼,但此時我們會發現由於節點元素缺乏相應的語義化類名,代碼依然不具備很好地可讀性。爲了最終能得到可以二次開發的代碼,我們需要在佈局算法層之後加入語義化處理層來讓代碼擁有良好的語義性。

語義化層首要解決的問題就是如何爲元素節點加上具有語義化的類名。

爲了實現這一目標,我們可以先回顧一下在我們開發的時候是如何給元素節點加上類名的,以如下的單個商品圖爲例。

上圖是一個商品圖的示例,我們會通過圖片、價格、圖片下方文案等因素來判斷出這是一個商品,然後我們就可以給這一個區域賦予類名 goods ,而區域內的節點,比如圖片可以賦予類名 goods_pic ,圖片下方文案可以賦予類名 goods_tit ,價格可以賦予類名 price ,這就是我們爲元素節點添加類名的一般邏輯。

可以看出,通常我們去確定一個區域,一個組件的語義時,我們需要依據區域內節點的語義組合才能進行判定,比如上面的商品組件,需要依靠內部的圖片、價格、文案等元素才能確定語義,從而確定類名。因此,語義化的處理方式,就是從容器元素的子節點出發,先確定子節點的語義,然後再推斷出容器元素的語義,一層層往上進行推斷,最終推斷出整棵節點樹完整的語義。

在語義化層,我們主要的處理對象就是經過佈局算法層處理後的 JSON Schema 數據,我們稱之爲佈局樹,此時佈局樹已經具備了良好的結構,我們可以對它進行語義化推斷操作。推斷的流程就是從樹的葉子節點出發,一層層向上冒泡到枝節點,最後再冒泡到根節點。

![](https://img12.360buyimg.com/img/s1734x1266_jfs/t1/155564/31/3555/279527/5fed997cE2facb891/f69f97899b664218.png![](

目前我們進行推斷的依據主要是節點的位置、樣式、大小、兄弟節點等因素,同時會結合不同節點的類型,組合一些智能化手段進行輔助推斷。例如,最小葉子節點一般可能爲圖片、文本兩種類型,針對文本我們可以通過 NLP 的方式去分析文本的詞性、語義;針對部分圖片,我們可以使用圖片分類或識別的方式確定圖片分類或者提取圖片上的關鍵信息進行圖片的語義判定。

爲了確定每個節點的語義,我們需要組合一系列的規則對現有的事實(樣式、位置等信息)進行推理,而同時,經過一些規則推理後又會得到新的事實,又需要經過其他規則推理之後才能得到最後確定的結果。所以,這是一個基於規則推理的推理系統,我們可以通過實現一個正向鏈的推理引擎,來幫助我們進行推理決策。

例如,推斷上述商品組件的過程,首先我們先找到具備價格因素的文本節點,命名爲 price ,然後我們找到 price 附近,在樹中所處層級相近的圖片節點,並且該圖片節點符合商品圖大小的要求,這樣我們就能基本確定同時包含價格和符合商品圖特徵的容器爲商品容器,再根據容器中元素個數,圖片附近是否有一段文本,以及對文本的 NER 分析,我們就能確定這段文本是否是商品名,從而確定其語義化類名。

在整個語義化層中,上述的判定規則只是冰山一角,我們結合整個電商場景,分析了大量設計稿與線上案例後總結了大量的判定規則來幫助我們進行合理化語義命名,同時在語義化過程中採用 NLP 分析、圖片分類及識別等 AI 手段,我們將在後續專門撰寫相關文章爲大家進行具體介紹。

當然,得到節點類名只是語義化先階段初步的成果,在未來我們將持續挖掘語義化,爲後續字段邏輯綁定等實現打下堅實基礎。

5、階段性成果

目前,在組件識別層、圖層處理層、佈局算法層和語義化層這四大核心模塊我們已經去取得了關鍵性突破,已經可以實現對 Sketch 設計稿進行分析,將其轉化成結構良好,具備語義化的,可以二次開發的代碼,初步實現了設計稿到代碼還原重構的階段。

我們已經在大量的電商大促設計稿上進行測試,佈局還原程度可達 90% 以上,而最終產出的代碼可用率可以達到 80%,我們已經推動在部分內部業務中嘗試進行使用。

6、未來展望

未來,在上述核心模塊完善的同時,我們將加入線上可視化編輯器,允許開發者對生成的代碼進行人工干預調整,從而得到更好的代碼,同時我們也將探索加入字段綁定和邏輯綁定的功能,讓代碼可以具備業務邏輯,讓 Deco 具備 T3 左右工程師的水平,進一步提升產研的效率。

Deco 是一粒種子,也許它此時剛剛發芽,但我們對它期許頗多,我們希望通過 Deco 來探索前端智能化的道路,探索 AI 與前端結合的各種可能性,更重要的是,我們希望能夠通過 Deco 開啓產研的效率革命,在各種前端工程化、平臺、方法論趨於完善的當下,探索爲業務降本增效的另一種方式。

Deco 的未來,值得期待。


歡迎關注凹凸實驗室博客:aotu.io

或者關注凹凸實驗室公衆號(AOTULabs),不定時推送文章。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章