iOS 原生渲染與 Flutter 有什麼區別 (下)
theme: smartblue
「這是我參與2022首次更文挑戰的第20天,活動詳情檢視:2022首次更文挑戰」。
在上篇文章「iOS 原生渲染與 Flutter 有什麼區別 (上)」中,我們瞭解了渲染原理以及原生渲染的流程,在這篇文章中,我們來聊聊Flutter
是如何渲染,以及前端是如何在iOS上渲染。
Flutter 渲染
Flutter
介面是由 Widget
組成的,所有 Widget
組成 Widget Tree
,介面更新時會更新 Widget Tree
,然後再更新 Element Tree
,最後更新 RenderObject Tree
。
接下來的渲染流程,Flutter 渲染在 Framework
層會有 Build
、Wiget Tree
、Element Tree
、RenderObject Tree
、Layout
、Paint
、Composited Layer
等幾個階段。將 Layer
進行組合,生成紋理,使用 OpenGL
的介面向 GPU 提交渲染內容進行光柵化與合成,是在 Flutter
的 C++
層,使用的是 Skia
庫。包括提交到 GPU 程序後,合成計算,顯示螢幕的過程和 iOS 原生基本是類似的,因此效能也差不多。
Flutter
在緩衝策略上與 iOS原生稍有不同的是:
Flutter
使用的是 VSync + 三重緩衝 (Triple Buffering)
,在iOS原生
使用的是 VSync + 雙重緩衝 (Double Buffering)
。
渲染管道
Flutter
渲染管道涉及到多重步驟:
- 首先得到使用者的輸入,例如觸控式螢幕幕事件,一些動畫可能會隨之產生,然後開始構建元件並去渲染它們;
- 渲染可以細分為3個子步驟;
Layout
(佈局),它的作用是在螢幕上確定每個元件的大小和位置;Paint
(繪製),它提供一系列方法把元件渲染成使用者看到的樣子;Composite
(圖層合成)它把繪製步驟生成的圖層或者紋理堆疊在一起,按照順序組織它們,以便它們可以高效的在螢幕上進行呈現,圖層合成是元件最終呈現在螢幕上之前很關鍵的也是最後的一個優化步驟;
- 最後是光柵化,它把抽象的表現對映成物理畫素顯示在螢幕上。
前端 渲染
前端大部分都是使用WebKit
框架下的WebView
,WebView
需要額外解析 HTML + CSS + JavaScript
程式碼,首次內容載入時, WebView
會比原生渲染慢。
除了首次載入解析要耗時,以及 JavaScript
語言本身解釋慢導致的效能問題外,WebView
的渲染程序是單獨的,每幀的更新都要通過 IPC 呼叫 GPU 程序。頻繁的 IPC 程序通訊也會有效能損耗。
WebView
的單獨渲染程序還無法訪問 GPU 的 context,這樣兩個程序就沒有辦法共享紋理資源。紋理資源無法直接使用 GPU 的 Context 光柵化,那就只能通過 IPC 傳給 GPU 程序,這也就導致 GPU 無法發揮自身的效能優勢。由於 WebView
的光柵化無法及時同步到 GPU,滑動時容易出現白屏。
寫在最後
相比較,不難發現其實Flutter
某些層面上可能表現和原生不相上下,某些層面甚至是超越,相比較而言,由於WebView
渲染層級多,限制多,計算多,所以在效能和速度方面還是要弱於原生和Flutter
。
- LeetCode 初級演算法之陣列(上),看看你都學會了嗎?
- LeetCode 初級演算法之連結串列,看看你都學會了嗎?
- LeetCode 初級演算法之字串(上),看看你都學會了嗎?
- 純程式碼佈局,也可以一樣的簡潔
- UIStackView之一問一答
- 使用UIStackView來簡化iOS的介面佈局
- 夏天來了,iOS開發者們該如何減少App耗電?(上)
- 夏天來了,App開發者們如何看待手機發燙問題?
- 聊聊iOS中UITableView複用的那些事
- 曾經經典的微信打飛機遊戲還有人記得嗎?
- iOS 原生渲染與 Flutter 有什麼區別 (上)
- 瞭解 Mach-O檔案
- CocoaPods中podsepc檔案設定詳解
- iOS 原生渲染與 Flutter 有什麼區別 (下)
- 簡單瞭解 iOS CVPixelBuffer (上)
- 談談 iOS 包瘦身方案
- 播放器重構的探索之路
- 如何使用CocoaPods製作私有庫
- iOS 元件化方案