🔧 阿川の電商水電行
Shopify 顧問、維護與客製化
💡
小任務 / 單次支援方案
單次處理 Shopify 修正/微調
⭐️
維護方案
每月 Shopify 技術支援 + 小修改 + 諮詢
🚀
專案建置
Shopify 功能導入、培訓 + 分階段交付

Web前端們!我用三年親身經歷,說說從 uniapp 到 Flutter怎麼轉型的,這條路我爬過,坑我踩過

前言

大家好,我是【小林】
說來有點意思,我的後台私信,最近有點熱鬧熱鬧,點開一看,翻來覆去都是同一個問題:
“哥們,我一Web前端,能轉 RN/Flutter 嗎?好轉嗎?水深不?”
問的人多了,我一個個回實在有點累。而且我發現,這已經不是一個簡單的“能不能”的問題,背後是 Web 開發者對未知移動端領域的一系列困惑、焦慮和好奇。
所以,我決定乾脆寫一篇文章,把我從一個純粹的 Web 前端,一步步“爬”到 Flutter 開發的經歷和思考,掰開揉碎了分享給大家。我不講某個 API 怎麼用,也不貼大段的源碼,咱就聊點大實話,聊聊這條路到底是怎麼回事。
先自報家門,讓大家知道我不是在“瞎忽悠”。
我,22年畢業就做了 Web 前端。第一份工作在上海一家小公司,上來就是硬仗,用 uni-app 從0到1搞換電小程序的微信和支付寶版。後來老闆為了融資,說小程序體驗不行,要做 App,於是我又臨危受命,在 uni-appRNFlutter 三個技術裡選型,最後硬著頭皮上了 Flutter,那時候可沒現在這麼多 AI 能幫你,全靠一行行手敲,愣是把 App 給幹上線了。
後來跳槽到了北京一家上市公司,正式成為一名 Flutter 開發,做 AIGC 項目,就是大家玩的文生圖、圖生圖那些。再後來,我又去了小米(外包),參與錢包裡的 AI 記帳模塊,體驗了一把大廠的混合開發模式。現在入職一家中廠,有專門的 Flutter 技術團隊...
一路上,從 uni-app 的 WebView,到 Flutter 的自繪引擎,從一個人單打獨鬥,到和原生開發協同作戰,也自己封裝了幾個插件發佈到 pub.dev,算是混了個臉熟。
所以,關於“Web前端轉跨平台”這個話題,我覺得我還是能聊幾句的。

篇章一:捋直概念,什麼是跨平台開發

在很多 Web 同學眼裡也包括曾經的我,移動端開發就俩物種:原生(Native)跨平台(Cross-Platform)

原生開發和跨平台開發的區別在哪?

這個理解沒錯,但有點籠統。我們用個好懂的比喻來解釋。
原生開發(Native Development)

想像一下,你要在北京和上海各開一家本地特色菜館。
你會在北京請一位精通京醬肉絲、烤鴨的北京本地廚師(Android 開發者),用本地的食材和灶具(Java/Kotlin + Android SDK)。
你會在上海請一位精通紅燒肉、腌篤鮮的上海本地廚師(iOS 開發者),用上海的食材和灶具(Objective-C/Swift + iOS SDK)。
優點:兩家菜館都做出了最地道、最原汁原味、上菜最快的本地菜(性能最好、體驗最棒、最貼合系統特性)。
缺點:你得雇兩個廚師,溝通兩套菜單,管理兩個廚房,成本直接翻倍(開發成本高、周期長、團隊維護難)。

原生開發解決的核心責任是:榨乾平台性能,提供極致的用戶體驗。 任何與系統底層深度交互的功能,比如定製化的系統級服務、複雜的藍牙/NFC通信、高性能的圖形處理,原生都是當之無愧的王者。在我做 AIGC 項目時,那兩個安卓和 iOS 的同事,他們不直接參與業務開發,但他們負責打包、負責把算法團隊給的 C++ SDK 集成到原生工程裡,再暴露接口給我們 Flutter 調用。這就是原生的“特區”,跨平台技術輕易不敢涉足。

跨平台開發(Cross-Platform Development)

現在,你覺得兩家店成本太高,決定開一家融合菜館。
你請來一位天才大廚(跨平台框架),他帶來了一套自己獨門的萬能廚具和標準化的烹飪流程(一套代碼)。
他用這套流程,既能做出八九不離十的京醬肉絲,也能做出味道不錯的紅燒肉,而且兩道菜可以同時開火,效率極高(一套代碼,多端運行,降本增效)。
優點:你只需要管理一個廚師和一個廚房,成本大大降低,上新菜也快(開發成本低、效率高、UI一致性好)。
缺點:雖然菜好吃,但終究不是本地老師傅做的,口感上可能差那麼點“地道”的感覺(性能和體驗通常有損耗),而且如果遇到特別刁鑽的本地食材(特定系統API),這位大廚也得去請教本地廚師怎麼處理(需要原生輔助)。

跨平台解決的核心責任是:在保證體驗基本盤的情況下,最大化地復用代碼,降低成本,提升效率。 它是商業和技術權衡下的產物,尤其適合那些業務邏輯複雜、UI多樣的應用。

移動端開發需要的思維模式

在聊技術之前,我們先聊點更重要的東西:思維模式。從 Web 轉移到移動端,最大的坎不是學 Dart 或 React,而是你大腦裡根深蒂固的“瀏覽器思維”。

  • 從“無狀態”的網頁到“有狀態”的應用
    Web 的世界,本質是請求-響應。用戶點一下,頁面刷一下,大部分時候我們不關心用戶上一步幹了啥。而 App 是一個活物,它有生命周期:從後台被喚醒、被一個電話打斷、被系統因為內存不足而殺死……你寫的每一行代碼,都得像個操心的老媽子,考慮這個“活物”在各種狀態下的表現。這是一種從“面向文檔”到“面向狀態”的根本轉變。
  • 從“溫室”的瀏覽器到“嚴酷”的移動環境
    在 Web 端,我們是溫室裡的花朵,背後有強大的伺服器和穩定的網路。但在移動端,你的 App 是在一個資源極其有限、環境極其惡劣的“荒野”求生。性能不再是錦上添花,而是生死線。我做 AIGC 項目時,一張圖的生成過程,如果導致 UI 掉幀,用戶會立刻感覺到卡頓;如果內存控制不好,低端機直接閃退。電量、內存、網絡抖動、CPU 使用率……這些過去我們不太關心的指標,現在成了懸在頭上的達摩克利斯之劍。
  • 從“文檔流”的佈局到“約束”的佈局
    Web佈局是“順流而下”,我們用 Flex、Grid 改變水流方向。而移動端佈局是“戴著鐐銬跳舞”,每個組件都被父級死死地“約束”在一個矩形內。你必須學會從“我想把它放哪”轉變為“我該如何約束它,讓它在我想要的位置”。

好了,心態擺正了,我們再來看技術,你會發現很多設計的“所以然”。

篇章二:直擊底層:三大跨平台框架的架構原理剖析

uni-app: WebView 容器的集大成者

  • 核心架構:WebView + JSBridge
    uni-app 在構建 App 時的核心思想,是將你的 Vue.js 應用運行在一個原生的“容器”之內,而這個容器的主要組件就是一個高性能的 WebView。WebView 本質上是一個嵌入在 App 內部的、被閹割和強化的瀏覽器內核(iOS 的 WKWebView,Android 的 WebView)。你的所有頁面和組件,實際上都是在渲染一個本地的 HTML、CSS 和 JavaScript 文件。

  • UI 渲染機制
    UI 的渲染工作完全由 WebView 的渲染引擎負責。這意味著,你寫的 <view> 標籤最終會被渲染成 <div>,動畫效果依賴於 CSS Transitions/Animations,佈局遵循標準的 Web 文檔流和 Flexbox 模型。這對於 Web 開發者是零成本上手,但同時也意味著,UI 的性能上限被 WebView 本身牢牢鎖死

  • 邏輯與原生通信:JSBridge
    當你的 Web 頁面(JS 代碼)需要調用原生的能力時,比如掃碼、獲取地理位置,就需要通過 JSBridge 這個“信使”來完成。其工作流程通常是:

    1. JavaScript 調用:你在 JS 中調用 uni.scanCode()
    2. 數據序列化:JSBridge 將這個調用和參數打包成一個特定格式的字符串(通常是 JSON)。
    3. 消息傳遞:通過 WebView 提供給原生環境的接口,將這個字符串消息發送給原生代碼。
    4. 原生執行:原生代碼接收並解析消息,執行真正的掃碼操作。
    5. 結果返回:原生將結果再次序列化,通過回調機制傳回給 WebView 中的 JavaScript。

這個過程是異步的,並且涉及多次數據序列化/反序列化線程上下文切換(JavaScript 线程 ↔ 原生 UI 线程)。對於低頻調用,這沒有問題;但對於高頻交互(如自定義手勢、實時通信),JSBridge 就會成為明顯的性能瓶頸。

  • 架構總結
    uni-app 的架構是一種極致的實用主義。它用 Web 開發者最熟悉的技術棧,以最低的成本實現了跨端。但其代價是性能和體驗的天花板較低,永遠無法擺脫“網頁感”,因為它本質上就是一個高度優化的本地網站。

React Native: 邁向“無橋接”新时代的原生 UI 映射

  • 核心架構:JavaScript 线程 + 原生 UI 线程
    RN 的設計哲學與 WebView 完全不同。它並沒有把你的代碼跑在瀏覽器裡,而是啟動了一個獨立的 JavaScript 线程(通常使用為移動端優化的 Hermes 引擎)來執行你的 React 代碼(業務邏輯)。當你的組件樹發生變化時,RN 會計算出最小化的 UI 更新操作,然後通過一套通信機制,告知原生 UI 线程去創建、更新或刪除對應的原生 UI 組件

  • UI 渲染機制
    你寫的 <View> 組件,最終會由 RN 轉化為 iOS 上的 <UIView> 或 Android 上的 <android.view.View>渲染工作是100%由原生系統完成的。這使得 RN 應用在外觀和基礎交互上能夠達到與原生應用幾乎無異的水平。

  • 邏輯與原生通信(划重點:架構的演進)
    RN 的通信機制是其性能演進的關鍵,經歷了兩個時代:

    • 舊架構 (Bridge) :這是 RN 早期的通信核心。它是一個異步的、可批處理的橋。JS 线程和原生线程通過這個橋來回傳遞序列化後的 JSON 消息。這個設計的瓶頸在於:1) 異步:JS 無法同步調用原生方法並立即獲得結果。2) 序列化開銷:對於大量或頻繁的數據交換(如列表滾動時的事件數據),JSON 轉換的開銷很大。這導致了在複雜場景下,UI 響應可能會延遲。
    • 新架構 (JSI - JavaScript Interface) :這是 RN 的革命性升級。JSI 允許 JavaScript 直接持有一個對 C++ 對象的引用,並通過這個引用同步調用該對象的方法。這意味著:
      1. 告別 JSON 序列化:數據可以直接在內存中共享,無需低效的字符串轉換。
      2. 實現同步調用:JS 可以像調用本地函數一樣調用原生功能,這對於需要即時反饋的複雜交互至關重要。
        基於 JSI,RN 推出了新的渲染器 Fabric 和新的原生模塊系統 TurboModules,共同構成了“無橋接”的新时代。
  • 痛點是什麼?

    • Bridge 性能瓶頸:當你的遙控器按得太快(比如頻繁的動畫、列表快速滾動),信號太多,電視機就可能反應不過來,導致卡頓。這是 RN 歷史上一直被詬病的問題,雖然現在有了新的架構(JSI)在改進,但這個通信成本是客觀存在的。
    • “Write once, debug everywhere” :因為 RN 只是“調用”原生組件,而兩端原生組件的表現有時會有細微差異,所以經常會出現一個佈局在 iOS 上好好的,在 Android 上就歪了的情況,需要寫平台特定的代碼來抹平差異。
  • 架構總結
    RN 提供的是真正的原生 UI 體驗。它的架構演進,本質上是在不斷解決“如何讓兩個分離的世界(JS 與 Native)更高效、更同步地對話”這一核心問題。新架構極大地提升了其性能上限,使其在絕大多數場景下都表現出色。

Flutter: AOT 編譯與自繪引擎的性能猛獸

  • 核心架構:Dart AOT 編譯 + C++ 渲染引擎 (Impeller/Skia)
    Flutter 的架構獨樹一幟,它完全獨立於系統原生 UI 組件。其本質上更像一個遊戲引擎,只不過它渲染的是 UI 元素而非遊戲角色。

    • 代碼執行:你的 Dart 代碼在發佈模式下,會被 AOT (Ahead-of-Time) 編譯成平台相關的原生 ARM 機器碼。這意味著運行時沒有中間層(如 JS 虛擬機)的解釋開銷,代碼執行效率極高,性能穩定可預測。
    • UI 渲染:Flutter 接管了整個螢幕的渲染。它要求操作系統提供一塊空白的畫布(Surface),然後調用其自帶的 C++ 渲染引擎,一個像素一個像素地將整個介面繪製出來。
  • UI 渲染機制(劃重點:引擎的進化)
    Flutter 的渲染引擎是其性能的基石,也經歷了一次重大演進:

    • Skia 引擎:這是 Google 開源的 2D 圖形庫,也是 Chrome 和 Android 的底層圖形引擎。Skia 性能強大,但存在一個被稱為“著色器編譯卡頓 (Shader Compilation Jank) ”的問題。即當一個複雜的動畫或效果首次出現時,Skia 需要在運行時動態編譯其所需的著色器(Shader),這個編譯過程可能導致零點幾秒的掉幀,影響首次體驗的流暢度。
    • Impeller 引擎:為了根治此問題,Flutter 開發了新的渲染引擎 Impeller(目前在 iOS 上已默認啟用)。Impeller 的核心優勢在於,它會在 App 構建時預編譯所有可能用到的著色器。這樣,在運行時就不再有編譯開銷,從根本上消除了“首次卡頓”現象,使得動畫和過渡效果如黃油般絲滑。
  • 邏輯與原生通信:Platform Channels
    當 Flutter 需要與平台原生服務(如藍牙、电量、相機)交互時,它使用一種名為 Platform Channels 的機制。這是一種類似於 JSBridge 的異步消息傳遞系統,同樣涉及數據序列化。但關鍵區別在於:Flutter 僅在需要調用原生服務時才使用它,而 UI 渲染完全不依賴它。相比之下,RN 的舊架構中,每一次 UI 更新都需要跨橋通信。

  • 總結
    Flutter 的架構選擇了一條“大包大攬”的道路。通過 AOT 編譯和自繪引擎,它在跨平台 UI 渲染的性能一致性上達到了巔峰。這種架構確保了複雜的 UI 也能穩定運行在 60/120fps,代價是更大的初始包體和與原生 UI 生態的隔離。

篇章三:巔峰對決:到底誰才是“流暢度之王”?

聊了這麼多底層,最終都要反映在用戶指尖的感受上。我們來一場不客觀、但很真實的“60/120 FPS 滾動與動畫”流暢度對決。

  • 🥇 並列王者:原生 iOS / Flutter (Impeller 引擎)

    • 原生 iOS:親兒子,不多解釋。最小的系統開銷,最直接的硬體訪問。
    • Flutter (Impeller) :憑藉 Impeller 引擎的“提前備戰”策略和 Dart AOT 編譯成原生機器碼的“肌肉記憶”,Flutter 在 UI 渲染上幾乎抹平了與原生的差距。它就像一個頂級的遊戲引擎,目標就是穩定地“刷幀”,在 UI 密集型應用中,它的表現令人驚歎。
  • 🥈 白銀騎士:原生 Android

    • 性能同樣頂級。但由於安卓機型碎片化和 JVM 偶爾的 GC (垃圾回收) 停頓,在某些低端設備或極端情況下,可能會出現人眼可感知的微小卡頓。但這依然是標杆級的存在。
  • 🥉 青銅貴族:React Native (新架構)

    • 別誤會,“青銅”只是相對於前面幾個“怪物”而言。在新架構的加持下,RN 在絕大多數場景下已經非常流暢。但它的“原罪”在於,JS 线程依然是業務邏輯的中心。當你的 JS 线程忙於處理複雜計算或海量數據時,它傳遞給 UI 线程的“心靈感應”就可能延遲,導致動畫掉幀。雖然有 “Worklets” 等技術在努力繞開這個問題,但這個架構性特點決定了它的理論上限略低於 Flutter。

最終章:Web前端,你的路在何方?

好了,故事講完了,我們回到現實。

  • 如果你想“降維打擊”小程序,或快速將 Web 應用 App 化
    uni-app 是你的不二之選。用你最熟悉的 Vue,快速出活,成本最低。接受它的天花板,用它來解決 80% 的常規需求。
  • 如果你是 React 死忠,團隊技術棧統一
    擁抱 React Native 的新架構。它能讓你在移動端的世界裡最大化地復用你的 React 知識。生態龐大,社區活躍,找解決方案也更容易。
  • 如果你追求極致的跨平台體驗,不畏懼學習,想成為“全能藝術家”
    我個人,毫無保留地推薦你,和我一樣,跳進 Flutter 的“坑”裡。它可能需要你付出一個週末去學習 Dart,但它回饋給你的是一個性能逼近原生、UI 表現力登峰造極、未來充滿想像力的全新世界。從被 WebView 性能束縛,到用 Flutter 隨心所欲地繪製 UI,這種從“工匠”到“藝術家”的蛻變,帶來的成就感是無與倫比的。

技術的演進,永無止境。 RN 在努力填平“橋”的鴻溝,Flutter 在不斷打磨自己的“畫筆”。沒有最好的技術,只有最適合你和你的業務場景的技術。
從一個 Web 前端出發,這條路或許陡峭,但沿途的風景,絕對值得你為之攀登。你收穫的將不僅僅是寫出 App 的能力,更是對圖形學、操作系統、編譯原理更深層次的洞察。
而這些,將讓你無論將來回到 Web,還是繼續在移動端深耕,都站得更高,看得更遠。

往期文章回顧

Flutter 圖片編輯器

Flutter 全鏈路監控 SDK

Flutter 全場景彈框

Flutter日曆組件

日期選擇器


原文出處:https://juejin.cn/post/7576378563575545871


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝15   💬3   ❤️3
315
🥈
我愛JS
📝1   💬3   ❤️2
45
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次
🔧 阿川の電商水電行
Shopify 顧問、維護與客製化
💡
小任務 / 單次支援方案
單次處理 Shopify 修正/微調
⭐️
維護方案
每月 Shopify 技術支援 + 小修改 + 諮詢
🚀
專案建置
Shopify 功能導入、培訓 + 分階段交付