本文做者:IMWeb IMWeb團隊 原文出處:IMWeb社區 未經贊成,禁止轉載html
騰訊 OED 的客戶端團隊在 2019 年上半年 ,就已經把 Flutter 落地到 企鵝輔導 的業務中了。今年咱們又一塊兒去上海蔘加了 2019 年穀歌開發者大會,碰見了更多的 Flutter 開發者,此次體驗比第一次去的時候感受熟悉了不少。但願將來有機會把他們邀請來深圳,進行一些 Flutter 的技術分享。這次開發者大會又恰逢 Flutter to Web 也已經正式合入 Master,那麼,前端同窗是否能夠趁着這股東風一塊兒參與到 Flutter 的協同開發中呢,我想這問題會困擾着不少人?若是您有好的想法,能夠在留言區參與評論。前端
本文不是一篇 Flutter 詳細的學習教程,更像是一個概覽,用盡量平實的語言和對比的思路去描述它。本着依舊從前端同窗的角度出發,去理解一項新的技術,但又不限於前端技術自己。但願您能經過這篇文章相對全面的理解 Flutter 這項技術自己。特別感謝領導的鼓勵和支持,讓我有機會去學習和理解 Flutter 框架,由於相對我而言,OED 的客戶端團隊的同窗經驗會遠超於我,他們已經完整經歷了業務從 0 到 1 的過程,這是一種很是有意思的體驗。react
在談及 Flutter 以前,咱們仍是要先簡單回顧一下,客戶端的上一次技術革新 —— React Native(此後簡稱 RN)。相信很是多的團隊都有去落地實踐 RN 的機會,不少 APP 的首屏渲染方案都是用 RN 技術棧進行的。咱們本身的產品 企鵝輔導 和 騰訊課堂 內的應用也是同樣。git
這裏簡單回顧一下,在有客戶端開發的場景下,爲何又出現了 RN ?github
RN 的價值簡單來說就是 —— 可接受的頁面性能 + 高效開發 + 熱更新。web
更新:傳統的 APP 上架以後,出現了業務 BUG,用戶只能去更新 APP,進行 BUG 修復。客戶端實現熱更新修復 BUG,有多難,能夠問問 IOS 的開發同窗。大機率猜想,手 Q 和微信,應該仍是有方案能夠熱更新的。可是對不少小廠商這確實是很是艱難的事情。所以,得益於強大的動態化能力 RN 的價值也就完美的體現出來了。算法
高效:一個 APP 發佈上線,Android 和 IOS 同時須要開發兩個應用,而 RN 只須要一套代碼,就能夠運行在雙平臺上,節省很大的人力成本。而且不少業務線有很強的業務運營訴求,可能會存在很短期內的屢次改版和發佈的狀況出現,客戶端開發的人力瓶頸和發佈週期的限制,已經很難知足這樣的業務場景了。尤爲在一些有損發佈的狀況下,趕着時間點,帶着 BUG 上線的場景,在後續進行增量的修復,再這樣的狀況下,傳統客戶端的表現,簡直就是災難性的。npm
性能:RN 具備優於 H5 的性能體驗。畢竟是經過客戶端進行的頁面渲染,速度上比 WebView 渲染仍是要快很多的。這個在 Weex、Hippy 上都有所體現,雖然低於 Native 的性能,可是在可接受範圍。編程
PS:這裏的表達,不是描述客戶端開發很差。只是單純從業務角度上看待問題,而把合適的技術放在合適的位置是很是重要的,這也是架構師核心價值之一。瀏覽器
回顧了以上三點,咱們發現 RN 的出現,有它的必然性。那麼回到主題,RN 已經這麼優秀了,爲何還要有 Flutter 的存在,有一次向 Ab 哥請教技術成長的時候,Ab 哥提到了頗有意思的一個觀點,就是您對一項技術瞭解的深刻程度,取決因而否能認清這項技術的侷限。 就像人同樣,他(她)有多少優勢,就會存在多少缺點。沒發現,不等於不存在,由於必定存在。所以,順着這個思路,咱們簡單的看一下 RN 的問題。
首先,看維護成本,雖然 RN 是一套代碼多端運行。但仍是須要 IOS 和 Android 開發幫助咱們去一個一個的繪製組件,尤爲遇到特殊訴求的時候,還要 case by case 的處理,而且隨着 IOS 和 Android 系統自己的迭代和升級,以及框架自身發展的歷史包袱,咱們可能還須要處理不少與原生系統之間的平臺差別,修復各類奇奇怪怪的 BUG,這對業務來講是很大的負擔。
其次,對性能訴求,不管是產品仍是開發同窗,對於用戶體驗的追求,永遠都不會中止。RN 存在諸多性能的短板,所以,纔會有 Weex 這樣的產品出現,去定製化的解決業務場景下的問題。JS 和 Native 的通訊,頁面的事件監聽,複雜動畫的渲染和交換成本,都是很大的性能挑戰。
所以,在存在更強的業務訴求的時候,人們就不得不去尋找更好的方式去實現。很是存感激的看待谷歌這家公司,都是定位於商業公司,但實際上對世界的影響力上面,公司與公司之間差距仍是很是大的。這個課題範圍太大,之後有機會能夠深度討論一下。
您看到了上面的描述,爲了解決上面這些問題 —— 自繪引擎時代出現了,以 Flutter 爲表明的技術方案會應運而生,相信必定不會只有 Flutter 一項技術出現的,畢竟,歷史是驚人的類似。其實想到自繪引擎,我最早想到的是那些遊戲引擎。那如今又爲何給出 自繪引擎 這樣的一個概念呢?H5 是依賴於瀏覽器渲染,RN 依賴於客戶端渲染,而 Flutter 基於 Skia 本身繪製的圖形界面。所以,Flutter 才能真正實現跨端!相信在不久的將來,在傳統客戶端上也能看到 Flutter 的身影,這樣才能真正達到多端統一。想起了一句話 ~ 思路決定出路。
最後,咱們再簡單總結一下有哪些問題:
一、Web 性能差,跟原生 App 存在肉眼可見的差距;
二、React Native 跟 Web 相比,支持的能力很是有限,特定長場景問題,須要三端團隊一個一個處理;
三、Web 瀏覽器的安卓碎片化嚴重(感謝 X5,騰訊的同窗過得相對輕鬆一些)。
爲了解決上面的問題,Flutter 出現了:
一套代碼能夠運行在兩端
自繪 UI,脫離平臺,也能夠簡單的把它理解爲一個瀏覽器的子集。
鋪墊了這麼多,就是爲了幫助您回憶起技術發展的脈絡和技術趨勢,能夠更好的理解下面即將要表達的文稿,下面咱們正式開始介紹 Flutter。
Flutter 能介紹的技術點其實很是多,這裏找了一些具備表明性的技術項,結合本身的理解跟你們分享一下。包括設計思路、渲染方式、UI 的生命週期。由於這幾個點,跟 React 技術棧風格很是類似,以這種思考結構去對比介紹,能夠幫助你們更好的理解這項技術自己。
Google 了一下關鍵詞,搜素獲得了這張圖片,從下向上進行一些描述:
Embedder:是操做系統適配層,實現了渲染 Surface 設置,線程設置,以及平臺插件等平臺相關特性的適配。從這裏咱們能夠看到,Flutter 平臺相關特性並很少,這就使得從框架層面保持跨端一致性的成本相對較低。
Flutter Engine:這是一個純 C++實現的 SDK,其中囊括了 Skia 引擎、Dart 運行時、文字排版引擎等。不過說白了,它就是 Dart 的一個運行時,它能夠以 JIT、JIT Snapshot 或者 AOT 的模式運行 Dart 代碼。在代碼調用 dart:ui 庫時,提供 dart:ui 庫中 Native Binding 實現。 不過別忘了,這個運行時還控制着 VSync 信號的傳遞、GPU 數據的填充等,而且還負責把客戶端的事件傳遞到運行時中的代碼。具體的繪製方式,咱們放在後面描述。
Flutter Framework:這是一個純 Dart 實現的 SDK,相似於 React 在 JavaScript 中的做用。它實現了一套基礎庫, 用於處理動畫、繪圖和手勢。而且基於繪圖封裝了一套 UI 組件庫,而後根據 Material 和 Cupertino 兩種視覺風格區分開來。這個純 Dart 實現的 SDK 被封裝爲了一個叫做 dart:ui 的 Dart 庫。咱們在使用 Flutter 寫 App 的時候,直接導入這個庫便可使用組件等功能。
PS:雖然很早知道 Flutter,但實際寫 Flutter 時間也比較短暫。引擎源碼層面,目前也沒有深刻的涉獵。瞭解的方式能夠經過本身閱讀源碼,或者找谷歌、阿里、美團、以及我司的開發者幫忙。從技術角度來了解這些,在須要的階段,不會成爲你們的瓶頸。畢竟商業世界充滿了壁壘,而應用層面的技術自己是開放的。
JIT 在運行時即時編譯,在開發週期中使用,能夠動態下發和執行代碼,開發測試效率高,但運行速度和執行性能則會由於運行時即時編譯受到影響。
AOT 即提早編譯,能夠生成被直接執行的二進制代碼,運行速度快、執行性能表現好,但每次執行前都須要提早編譯,開發測試效率低。
它的目標在於成爲下一代結構化 Web 開發語言。Dart 發佈於 2011 年 10 月 Google 的 "GOTO 國際軟件開發大會"。是一種基於類編程語言(class-based programming language),在全部瀏覽器都可以有高性能的運行效率。Chrome 瀏覽器內置了 Dart VM,能夠直接高效的運行 dart 代碼(2015 年被移出)。支持 Dart 代碼轉成 Javascript,直接在 Javascript 引擎上運行。dart2js
開發時 JIT,提高開發效率;發佈時 AOT,提高性能。不會面對 JS 與 Native 之間交互的問題了。 Dart 的內存策略,採用多生代算法(與 Node 有一些相似)。線程模型依舊是單線程 Event Loop 模型,經過 isolate 進行隔離,能夠下降開發難度(與 Node 也很是相似)。 Dart 的生態,這個跟 Node.js 差距十分明顯,npm 仍是行業中最活躍的。 而靜態語法與排版方式,純前端入門仍是有必定成本。
備註:(1)TS 能夠必定程度上幫助 JS 添加一些靜態檢測,但本質上依舊是沒法達成這樣的效果;(2) 關於入門成本這個問題,若是您想深刻,我相信這都不會成爲問題。關鍵看是否能爲業務和團隊帶來價值。
健全的類型系統,同時支持靜態類型檢查和運行時類型檢查。 代碼體積優化(Tree Shaking),編譯時只保留運行時須要調用的代碼(不容許反射這樣的隱式引用),因此龐大的 Widgets 庫不會形成發佈體積過大。 豐富的底層庫,Dart 自身提供了很是多的庫。多生代無鎖垃圾回收器,專門爲 UI 框架中常見的大量 Widgets 對象建立和銷燬優化。跨平臺,iOS 和 Android 共用一套代碼。JIT & AOT 運行模式,支持開發時的快速迭代和正式發佈後最大程度發揮硬件性能。Native Binding。在 Android 上,v8 的 Native Binding 能夠很好地實現,可是 iOS 上的 JavaScriptCore 不能夠,因此若是使用 JavaScript,Flutter 基礎框架的代碼模式就很難統一了。而 Dart 的 Native Binding 能夠很好地經過 Dart Lib 實現。
看到了上面的介紹,這裏總結一下 Flutter 的實現思路。它開闢了新的設計理念,實現了真正的跨平臺的方案,自研 UI 框架,它的渲染引擎是 Skia 圖形庫來實現的,而開發語言選擇了同時支持 JIT 和 AOT 的 Dart。不只保證了開發效率,同時也提高了執行效率。因爲 Flutter 自繪 UI 的實現方式,所以也儘量的減小了不一樣平臺之間的差別。也保持和原生應用同樣的高性能。所以,Flutter 也是跨平臺開發方案中最靈活和完全的那個,它重寫了底層渲染邏輯和上層開發語言的一整套完整解決方案。
完全跨端:
與現有方案核心區別:
談到 UI 渲染方案,做爲前端開發,咱們是繞不過如今如火如荼的三大框架的。爲何要談 類 React 方案呢?由於 Flutter 的設計方案,與 React 設計具備同樣的思路。在渲染這裏咱們會談及 控件、渲染原理、以及生命週期。
Flutter 是如何進行頁面渲染的呢?傳統 Web 是經過瀏覽器,而 Flutter 是自繪。所謂自繪就是用戶界面上 Flutter 本身繪製到界面,無需依賴 Ios 和 Android 原生能力,是經過一個叫作 Skia 引擎進行頁面繪圖。
Skia 是一個 2D 的繪圖引擎庫,其前身是一個向量繪圖軟件,Chrome 和 Android 均採用 Skia 做爲繪圖引擎。Skia 提供了很是友好的 API,而且在圖形轉換、文字渲染、位圖渲染方面都提供了友好、高效的表現。Skia 是跨平臺的,因此能夠被嵌入到 Flutter 的 iOS SDK 中,而不用去研究 iOS 閉源的 Core Graphics / Core Animation。
Skia 是用 C++ 開發的、性能彪悍的 2D 圖像繪製引擎,其前身是一個向量繪圖軟件。 Skia 在圖形轉換、文字渲染、位圖渲染方面都表現卓越,並提供了開發者友好的 API。Android 自帶了 Skia,因此 Flutter Android SDK 要比 iOS SDK 小不少。正是得益於 Skia 的存在:
用戶能夠看到一張圖像展現,至少須要三類介質:CPU、GPU 和 顯示器。CPU 負責圖像的數據計算,GPU 負責圖像數據的渲染,而顯示器是最終圖片展現的載體。CPU 拿到須要上屏的數據作處理和加工,處理完成以後交給 GPU,GPU 在渲染以後將數據放入幀緩衝區,隨後隨着控制同步信號 (VSync) 以週期性的頻率,從緩衝區內讀出數據,在顯示器上進行圖像呈現。並且操做系統就是一個無限循環的機制,不停的重複上面的操做,進行顯示器的更新.
Flutter 的渲染總體流程也是這樣的, Dart 進行視圖數據的合成,而後交給 Skia 引擎進行處理,處理以後再交給 GPU 進行數據合成,而後準備上屏。當一幀圖像繪製完畢後準備繪製下一幀時,顯示器會發出一個垂直同步信號(VSync),因此 60Hz 的屏幕就會一秒內發出 60 次這樣的信號。
如上圖所示,Flutter 渲染流程分爲 7 個步驟:
首先是獲取到用戶的操做,而後你的應用會所以顯示一些動畫
接着 Flutter 開始構建 Widget 對象。
Widget 對象構建完成後進入渲染階段,這個階段主要包括三步:
最後的光柵化由 Engine 層來完成。
佈局
佈局時 Flutter 深度優先遍歷渲染對象樹。數據流的傳遞方式是從上到下傳遞約束,從下到上傳遞大小。也就是說,父節點會將本身的約束傳遞給子節點,子節點根據接收到的約束來計算本身的大小,而後將本身的尺寸返回給父節點。整個過程當中,位置信息由父節點來控制,子節點並不關心本身所在的位置,而父節點也不關心子節點具體長什麼樣子。
爲了防止因子節點發生變化而致使的整個控件樹重繪,Flutter 加入了一個機制——Relayout Boundary,在一些特定的情形下 Relayout Boundary 會被自動建立,不須要開發者手動添加。
邊界:Flutter 使用邊界標記須要從新佈局和從新繪製的節點部分,這樣就能夠避免其餘節點被污染或者觸發重建。就是控件大小不會影響其餘控件時,就不必從新佈局整個控件樹。有了這個機制後,不管子樹發生什麼樣的變化,處理範圍都只在子樹上。
緩存:要提高性能表現,緩存也是少不了的。在 Flutter 中,幾乎全部的 Element 都會具備一個 key,這個 key 是惟一的。當子樹重建後,只會刷新 key 不一樣的部分。而節點數據的複用就是依靠 key 來從緩存中取得。
在肯定每一個空間的位置和大小以後,就進入繪製階段。繪製節點的時候也是深度遍歷繪製節點樹,而後把不一樣的 RenderObject 繪製到不一樣的圖層上。
繪製
在佈局完成以後,渲染對象樹中的每一個節點都有了明確的尺寸和位置。Flutter 會把全部的 Element 繪製到不一樣的圖層上。與佈局過程相似,繪製的過程也是深度優先遍歷,先繪製父節點,而後繪製子節點。如下圖爲例:節點 一、節點 二、節點 三、四、5,最後繪製節點 6。
如上圖能夠看到一種場景,就是好比視圖可能會合並,致使 節點 2 的子節點 5 與 它的 兄弟節點 6 處於同一個圖層,這樣會致使當 節點 2 須要重繪的時候,與其無關的節點 6 也會被重繪,帶來性能問題。
爲了解決上面的問題,Flutter 提出了佈局邊界的機制 —— 重繪邊界(Repaint-Boundary)。在重繪邊界內,Flutter 會強制切換新的圖層,這樣能夠避免邊界內外的互相影響,避免無關內容雖然處於同一個層級致使的沒必要要的重繪。
重繪邊界的一個典型場景就是 ScrollView。ScorllView 滾動的時候會刷新視圖,從而觸發內容重繪,而當滾動內容重繪時,通常狀況下其它內容是不須要被重繪的。這個時候重繪邊界就很是有價值了。
這裏思路就是更精細化的對組件的更新進行最小範圍的控制。
合成和渲染
最上面已經展現了 Flutter 的 7 層渲染流水線(Rendering pipline)的圖裏。這裏主要描述一下對合成和渲染的理解。渲染流水線是由垂直同步信號(Vsync)驅動的。這個概念很相似咱們平時說的 FPS 的概念,每秒 60 幀,太低的頻率會顯得頁面很卡。
當每一次 Vsync 信號到來之後,Flutter 框架會按照圖裏的順序執行一系列動做:
動畫(Animate)、構建(Build)、佈局(Layout)和繪製(Paint)
最終生成一個場景(Scene)以後送往底層,由 GPU 繪製到屏幕上。
Flutter App 只有在狀態發生變化的時候須要觸發渲染流水線。當你的 App 無任何狀態改變的時候,Flutter 是不須要從新渲染頁面的。因此,Vsync 信號須要 Flutter App 去調度。好比,咱們在 Widget 內使用了 setState 方法改變了控件的狀態。
整個渲染流水線是運行在 UI 線程裏的,以 Vsync 信號爲驅動,在框架渲染完成以後會輸出 Layer Tree。Layer Tree 被送入 Engine,Engine 會把 Layer Tree 調度到 GPU 線程,在 GPU 線程內合成(compsite)Layer Tree,而後由 Skia 2D 渲染引擎渲染後送入 GPU 顯示。這裏提到 Layer Tree 是由於咱們即將要分析的渲染流水線繪製階段最終輸出就是這樣的 Layer Tree。因此繪製階段並非簡單的調用 Paint 函數這麼簡單了,而是不少地方都涉及到 Layer Tree 的管理。
Flutter 只關心向 GPU 提供視圖數據,GPU 的 VSync 信號同步到 UI 線程,UI 線程使用 Dart 來構建抽象的視圖結構,這份數據結構在 GPU 線程進行圖層合成,視圖數據提供給 Skia 引擎渲染爲 GPU 數據,這些數據經過 OpenGL 或者 Vulkan 提供給 GPU。
這裏描述一下合成的概念,所謂合成就是由於咱們繪製的頁面結構複雜,若是直接交付給繪圖引擎去進行圖層渲染,可能會出現大量的渲染內容重繪,所以,須要先進性一次圖層合成,就是說先把全部的圖層根據大小、層級等規則計算出最終的顯示效果,將相同的圖層合併,簡化渲染樹,提高渲染效率。
Flutter 會將合成以後的數據,交給 Skia 進行頁面二維圖層的渲染。
Flutter 繪製界面的基礎是 Widget,也就是描述頁面的最小模塊。
Flutter 的核心設計思想就是 "一切皆 Widget":
前端同窗能夠把 Widget 理解爲 Web Component 的 組件 便可。
一種結構化數據的抽象,包含了組件的佈局、渲染屬性、事件響應信息等。
在這一個部分咱們對比着 React 的設計方式對比着看一下 Flutter 的實現,在 React 中您能夠看到三種很重要的名稱。JSX、Virtual Dom、真實 Dom,而在 Flutter 中咱們依然能夠看到對應的三類抽象的數據結構分別是 Widget、Element 和 RenderObject,他們的功能與 React 內三個數據抽象有殊途同歸之處。
Widget 相似 React VM 的 F(x) = Y 中的 x 存在
Flutter 中的 Widget 是徹底不可變的!只要當視圖發生變化,Flutter 就會從新建立一個新的 Widget 進行更新。便是 React 也是有必定的數據 Diff 的策略,而這裏變動即建立的方式,會帶來大量的銷燬和重建的過程,是否很是消耗性能?
Widget 對標的是 標識 React 的虛擬 DOM 節點的 數據描述 JSX,不是真實渲染的頁面 DOM。只是數據的抽象,不涉及視圖渲染。而且 Widget 具備不可變性,也提高了 Widget 自己的複用性。所以並沒大量的性能消耗,而 Dart 的做爲靜態語言的運行速度,也會有着超越 JS 的性能。
Element 是 Widget 的一個實例化對象
Element 承載了視圖構建的上下文數據,是鏈接結構化的配置信息到完成最終渲染的橋樑; Element 是一個可變的數據結構, 能夠大體理解爲 Virtual DOM。能夠進行 diff 更新; 能夠將真正須要修改的數據同步到 RenderObject 中。最大程度的下降渲染視圖的修改,提高渲染效率。
RenderObject 負責視圖渲染的對象
Flutter 的渲染分爲 4 個部分。佈局、繪製、合成、渲染,其中 佈局和繪製是在 RenderObject 中完成的。 Flutter 採用深度優的方式渲染對象樹,肯定樹中的各個對象的位置和尺寸,並把它繪製到不一樣圖層, 繪製完成以後交給 Skia 在 VSync 信號同步時從渲染樹合成位圖,而後交給 CPU 進而完成上屏。
Widget 一樣分爲有狀態 和 無狀態組件
無狀態控件 StatelessWidget 相似 React 的 PFC。 有狀態控件 StatefulWidget 就是 React 的 組件。 如同 react 組件同樣,使用有狀態組件是有成本的。正確的評估你的需求,避免使用無心義的有狀態組件。
這裏比較大的區別,是 Flutter 直接把 Widget 設計成爲了一個不可變的! 這也致使了技術方案的實現上存在了差別。
每當您看到組件、狀態、視圖這些名詞的時候,伴隨着它們的存在,必定會存在一個叫生命週期的概念。是的 ,Flutter 也存在它的生命週期。
建立
構造函數 --> initState --> didChangeDependencies --> build
State:構造方法是生命週期的起點,Flutter 會經過 StatefulWidget.createState 來建立一個 State。咱們能夠經過初始化方法,接收父 Widget 傳遞過來的初始化 UI 配置參數,這些配置參數決定了 Widget 的最初配置效果
initState:會在 State 對象被插入視圖樹的時候調用,這個函數在 State 的生命週期中只會被調用一次,因此咱們能夠在這裏作一些初始化工做,好比爲狀態變量設定默認值。
didChangeDependencies:則用來專門處理 State 對象依賴關係變化,會在 initSate()調用結束後被 Flutter 調用。
build:做用是構建視圖。經過以上步驟,Framework 認爲 Sate 已經準備好了,因而調用 build。咱們須要在這個函數中,根據父 Widget 傳遞過來的初始化配置數據,以及 State 的當前狀態,建立一個 Widget,而後返回。
更新
Widget 的狀態更新,主要由三個方法觸發:setState、didChangeDependencies 和 didUpdateWidget。
setState:是 咱們最熟悉的方式,控件內更新,而後重新 build。
didChangeDependencies:State 對象的依賴關係發生變化時,Flutter 會回調這個方法,隨後觸發組件構建。哪些狀況下 State 對象的依賴關係會發生變化呢?典型場景是,系統語言 Locale 或者應用主題改變時,系統會通知 Sate 執行 didChangeDependencies 回調方法。
didUpdateWidget:當 Widget 的配置發生變化時,好比,父 Widget 觸發重建(即父 Widget 的狀態發生變化)時,熱重載時,系統會調用這個函數。
一旦這三個函數被調用,Flutter 隨後就會銷燬老 Widget,並調用 build 方法重建 Widget。
銷燬
組件的銷燬相對比較簡單。好比組件被移除,或是頁面銷燬的時候,系統會調用 diactivate 和 dispose 這兩個方法,來移除或銷燬組件。
當組件的可見狀態發生變化時,deactivate 函數會被調用,這時 Sate 會被暫時從視圖樹中移除。值得注意的是,頁面切換時,因爲 State 對象在視圖樹中的位置發生了變化,須要暫時移除後再從新添加,從新觸發組件構建,所以這個函數也會被調用。
當 State 對象被永久地從視圖樹中移除時,Flutter 會調用 dispose 函數。而一旦到這個階段,組件就要被銷燬了,因此咱們能夠在這裏進行最終的資源釋放、移除監聽、清理環境。
從後臺切入前臺,控制檯打印的 App 生命週期變化以下:
AppLifecycleState.paused->AppLifecycleState.inactive->AppLifecycleState.resumed;
從前臺退到後臺,控制檯打印的 App 生命週期變化以下:
AppLifecycleState.resumed->AppLifecycleState.inactive->AppLifecycleState.paused;
更詳細的生命週期詳解,您能夠 Google 搜索 Flutter 生命週期 ,Github 上美團的工程師也有一個例子
粗略了整理了一下體驗學習過程當中關於 Flutter 基本的部分,這上面大部分分支已經經過代碼體驗和實踐過了。這裏就不在一一的介紹了。這裏找了三個實例,跟您分享,您能夠 clone 下來,跟細節的體驗一下:
代碼實例: github.com/nisrulz/flu…
FlutterDemo: github.com/OpenFlutter…
除了我上面列出的這些,還有不少要作,好比 運維、調試、自動化測試、兼容性、客戶端 SDK 封裝、國際化等等。固然對於開發者來講,工程化、調試體驗、組件化都是很是重要的。
這裏我轉換的代碼是咱們的 APP 裏面的業務代碼。詳細的操做流程 Flutter 官方文檔具備很好的說明。若是單純轉一個徹底不依賴 APP 的工程,估計您安裝完環境就可使用了。轉換商業產品的代碼,仍是要處理一些奇奇怪怪的問題,相信這對您都不會是問題。您能夠在這裏 安裝和環境配置 進行環境配置。Flutter 官網提供了一個 案例 您能夠嘗試一下。官方給了一個開箱即學的 開發文檔 。
上面的視頻裏面展現咱們 企鵝輔導 的第三個 TAB 內的 Flutter 業務,以及轉換後的 Web 頁面。能夠明顯看到,有一局部確實有些失真,可是徹底可用。這裏頁面渲染有一部分 Canvas 渲染 和 DOM 填充 進行的頁面展現。Dart 當年自然支持在 Chrome 中使用,而且長期以來一直支持轉換爲 JavaScript。所以,能夠碰見的將來,隨着 Flutter 的發展,Dart To Js 業務實踐的進化速度,可能會超過 WASM 的使用。
這裏須要解決一些問題,整理了一下官方建議和實踐的體驗:
首先還不建議,在產品化中使用,但既然已經合入 Master,相信這一天也不會遠了。
業務使用的時候,須要把系統依賴解決掉,好比:本地存儲、網絡請求這些。如客戶端使用的是 WNS,而前端須要使用的是 HTTPS。對 3D 動畫依賴比較嚴重的業務,短時間就不要選擇 Flutter 做爲業務選選了。Flutter to Web 將來做爲業務容災的策略仍是能夠的。
這裏再次感謝前人的沉澱,確實要學習的東西太多了,實際想要寫的文章,遠比這裏面描述要多不少,可是因爲時間成本太高,不得不砍掉了很是多的內容。後面隨着對 Flutter 更深刻的瞭解,有機會再跟您更詳細的分享 Flutter 的內部設計原理。我只是知識的搬運工,在應用層領域做爲開發,最大的價值就是服務好產品,最大限度的用技術知足產品訴求。至於核心的底層開發建設,人生能作到什麼程度,要看緣分;可是最大限度的服務好業務,只要有責任心就能夠了。
在此,也特別感謝領導的鼓勵,去嘗試體驗 Flutter 這項技術。瞭解和認知只是一個開始,後面若是有機會,也能夠作一些業務嘗試。在行業內部阿里的閒魚作的仍是很是深刻,美團的小夥伴也有深度的嘗試,感謝他們對行業的貢獻。
固然,我更但願您是前端,而且也對 Flutter 實踐有着興趣,可是又缺乏落地的項目,您也能夠聯繫咱們,團隊能夠給您提供一個靶場,進行業務實踐的落地。光說不練都是假把式,核心仍是要用業務去砸!
IMWeb 團隊隸屬騰訊公司,是國內最專業的前端團隊之一。
咱們專一前端領域多年,負責過 QQ 資料、QQ 註冊、QQ 羣等億級業務。目前聚焦於在線教育領域,精心打磨 騰訊課堂、企鵝輔導 及 ABCMouse 三大產品。
社區官網:
加入咱們:
careers.tencent.com/jobdesc.htm…
掃碼關注 IMWeb前端社區公衆號,獲取最新前端好文
微博、掘金、Github、知乎可搜索 IMWeb或 IMWeb團隊關注咱們。