你是不是也遇過這種狀況:App 在你手機上跑得像樣,丟給同事的安卓機直接卡住;你以為只是 UI 沒對齊,結果是背景任務被系統砍掉;最後你坐在捷運上,訊號一下有一下沒有,畫面整個白的。
這種痛苦其實有一個共通點:你不是在做「小螢幕的網頁」,你是在做「隨時會被打斷的使用情境」。手機世界就是這麼不講理。
手機優先不是口號,是你活下來的底層設定
行動裝置開發的「mobile-first」代表你必須把效能、離線、權限、電量與裝置碎片化當成預設前提,而不是等出事再補。使用者通常在幾秒內決定留不留,卡一下就走,這不是情緒,是行為資料的常態。
先講清楚:很多人把 mobile-first 當成「版面先做小一點」。不是。
手機最狠的地方,是它永遠跟著人跑。人走、網路掉、手滑、螢幕反光、只剩一隻手可以操作。
你還要同時想:
- 電池:GPS、相機、背景定位,一開就像在燒錢。
- 記憶體:低階機就是會殺進程,還會殺得很安靜。
- CPU:你動畫做太爽,使用者體感就是「這 App 很重」。
- 權限:相機、定位、通知,問得太急會被拒絕;不問又不能用。
- 單手操作:這個真的會害死人(你以為是設計師的矯情,結果不是)。
對了,講到單手操作,我突然想到一堆人把主要按鈕放在最上面,然後怪使用者不點。
手指就伸不到啊。就這樣。
看起來很「簡單」的功能,裡面常常是地雷田
多數行動 App 的 UI 看起來很乾淨,但背後通常是 OS 權限、雲端推播、深連結、使用者偏好與伺服器安全令牌一起纏在一坨。以推播通知(push notification)為例,表面是一行訊息,實作是多個系統串接。
推播通知這件事:你以為是「傳個訊息」;實際上你在跟 iOS/Android 的規矩、使用者的耐心、還有你後端的安全性一起摔角。
- 先跟系統要權限(而且時機不對,拒絕率很高)。
- 接 Firebase Cloud Messaging 或 Apple Push Notification service(APNs)。
- 伺服器要管 token,還要能更新、能撤銷,不能亂噴。
- 要做排程:依使用者行為、時區、安靜時段(Do Not Disturb)。
- 深連結:點通知要去哪?iOS 一套、Android 又一套,還有 cold start 問題。
- 使用者要能關掉,而且你要尊重 opt-in/opt-out,不然被罵爆。
然後你還得處理「通知到了但 App 打開是空的」那種尷尬。
很常見。真的很常見。
原生 vs 跨平台:別問信仰,問你要承擔什麼代價
原生開發(iOS Swift、Android Kotlin)在效能與平台整合上更可控;跨平台(React Native、Flutter)在開發速度與人力成本上更有利。多數團隊最後仍需要原生知識來處理跨平台遇到的裝置或系統層 bug。
我先替你把爭論收斂:這不是「哪個比較強」,是「你能不能承受後面那串麻煩」。
你可以用這個判斷:
- 偏原生(Swift/Kotlin):相機、藍牙、GPS、離線運算、背景任務、電量控管…你要踩到系統深處,就別怕麻煩,直接原生比較穩。
- 偏跨平台(React Native/Flutter):MVP、時間不夠、人手不夠、要快速迭代兩端一致的功能,跨平台很香。
但我要講一句不好聽的:跨平台可以讓你跑很遠,但你常常會在最後一公里被平台 bug 卡住。
React Native 對 web 背景的人很友善;Flutter 的 UI 控制力比較強。
然後呢?
你還是會遇到「某支安卓機」就是不聽話,最後得回去寫原生 bridge 或直接寫原生修掉。嗯。
設計早就不只「扁平化」,而是反應、節奏、信任感
現代行動 UI/UX 的關鍵不只在版面,而在微互動(microinteractions)、動態轉場(motion design)、深色模式與情境式介面(contextual UI)。這些元素用來降低使用者迷路與不確定感,並在移動情境中建立信任。
你會發現:很多「看起來高級」的 App,其實不是因為字體多漂亮,是它回應得很像個正常人。
- 微互動:按下去有回饋,不要像按空氣。
- 動態轉場:讓人知道「我從哪裡來、要去哪裡」,不然就會迷路。
- 深色模式:現在很多人就是夜裡滑手機,亮瞎一次就記恨你。
- 情境式 UI:離線就誠實說離線;開車中就別一直跳視窗;晚上就不要突然彈白底。
使用者不會稱讚你的「架構很漂亮」,他只會在卡住那一秒把你刪掉。
碎片化的真正成本:你以為是 bug,其實是裝置生態在揍你
行動裝置碎片化會造成同一套程式在不同品牌、螢幕尺寸與 OS 版本出現不一致行為,Android 特別明顯。較穩妥的做法是用 3–5 台實機做分層測試,搭配 feature flags 漸進上線,並用 Firebase Crashlytics 之類的工具追蹤真實崩潰。
Android 的碎片化:不是你玻璃心,是它真的有夠多機型。
iOS 相對單純?也別太樂觀。
iPhone 尺寸、iPadOS 的 layout、還有一些你以為不會出事的旋轉狀態,照樣能讓你懷疑人生。
更煩的是某些 Android 廠商(對,像小米、華為那類客製化很兇的)會改系統行為。
背景任務被殺掉,還不通知你。
你只會看到使用者說:「怎麼都沒收到通知?」
比較務實的做法:
- 至少準備 3–5 台實機:入門、中階、旗艦各一。
- 新功能用 feature flags 分批開,不要一次梭哈。
- 上 Crash reporting:例如 Firebase Crashlytics,先把「在哪裡死掉」抓到再說。
在台灣這點特別真實,因為你會遇到一堆不同品牌的安卓機型,加上通勤、地下街、電梯裡那種訊號…嗯,大家都懂。
離線優先 + CI/CD + 效能工具:三件事不做,後面一定還你
離線優先(offline-first)需要本地儲存(Android Room、iOS Core Data)、樂觀式 UI 更新、請求佇列與版本化同步來確保斷線時仍可用並能恢復。行動 CI/CD 常用 GitHub Actions 或 Bitrise 搭配 Fastlane、TestFlight/Firebase App Distribution;效能則可用 Android Profiler 與 Xcode Instruments 持續檢測記憶體、CPU 與耗電。
先講離線(offline-first):網路在手機上不是常態,是一種運氣。
你在 4G/5G 覺得順,不代表使用者在地下室、捷運、偏鄉、或只是走進電梯也順。
比較像樣的做法會包含:
- 資料先落地:Android 用 Room,iOS 用 Core Data。
- 樂觀式 UI:先讓畫面更新,再背景同步。
- 請求佇列:失敗就排隊重試,不要直接炸給使用者看。
- 同步要有版本:不然衝突處理會把你搞瘋。
離線優先不是說「沒網路也完美」。
是「沒網路也不要丟臉」。
再來是 CI/CD:如果你還在手動打包 APK、上架、簽名、重複做那些事…你會累死。
- GitHub Actions 或 Bitrise 跑測試、打包。
- Fastlane 做簽名、build、送審流程。
- 內測:TestFlight(iOS)或 Firebase App Distribution。
- React Native 若要 OTA:CodePush 這類機制可以救急,但也別亂用。
講到 CodePush,我就想到一些團隊把它當成「不用測試也能熱修」的藉口,然後線上直接燒。
很刺激。不好玩。
效能與耗電:使用者不會寫信告訴你「你的記憶體洩漏了」。他只會刪掉。
常見的雷:
- 圖片沒壓縮、沒 lazy load,聊天室/相簿類型特別容易中。
- 生命週期管理爛:listener 沒解除、ViewModel/observer 漏掉。
- 動畫太重:低階 GPU 直接掉幀,然後你以為是「網路慢」。
- 背景任務太兇:定位一直跑、sensor 一直開,電池直接見底。
工具不要省:
- Android Profiler
- Xcode Instruments
你只要真的跑一次 profile,就會知道哪些「感覺沒差」其實差很大。
我會怎麼給你分眾建議:不同族群,決策點根本不一樣
行動產品的技術選型應依族群情境決策:外食族重視單手與快速回饋,夜班族重視深色模式與穩定推播,親子族群重視權限透明與防誤觸,銀髮族群重視字級與可達性。對應到架構上,離線優先、效能監測與漸進上線策略會是共通底盤。
你如果是外食族(走路、排隊、手上拿東西):
- 那就把「單手操作」當 KPI:主要 CTA 放拇指區。
- 載入不要搞神秘:1 秒內要有回饋(骨架屏、微互動都行)。
- 離線狀態要講人話:不要只顯示一個轉圈圈。
你如果是夜班/輪班(半夜滑手機、光線敏感):
- 深色模式別拖到最後才做,字重、對比要測。
- 推播要尊重安靜時段,不然你會被關通知到死。
- 效能要穩:半夜耐心更低,真的。
你如果是親子族群(手忙、容易誤觸、孩子會亂點):
- 權限請求要透明:為什麼要相機/定位,講清楚。
- 避免「一點就買」那種危險流程,二次確認很必要。
- 通知內容別太刺激:不然家長直接卸載,省事。
你如果是銀髮族(視力、操作精細度、耐心):
- 字級、按鈕尺寸、點擊範圍要放大,別省那幾 px。
- 流程別太長:每一步都要知道「現在在哪」。
- 錯誤訊息不要兇:提供下一步,不要只說失敗。
這段看起來像 UX,但其實會一路影響到你要不要做離線、要不要做快取、要不要做 feature flag。
最後都會回到工程上。逃不掉。
功能表(我會拿這張表去跟 PM 吵架)
下面這張表不是要你「全部做完」,而是幫你用成本/風險把討論拉回地面,別一直靠感覺喊要加功能。
| 面向 / Feature | 你會遇到的真實問題 | 常用工具/做法(可落地) |
|---|---|---|
| Crash 追蹤 | 你只知道「有人閃退」,但不知道哪支機、哪個 OS、哪段流程 | Firebase Crashlytics(先把堆疊抓到,別空想) |
| 漸進上線 | 一次全量上線,出事就是全體陪葬 | Feature flags(分批開、回滾要快) |
| 離線優先 | 捷運/地下室沒網路就白畫面,使用者只覺得你爛 | Room / Core Data + request queue + versioning sync |
| 自動化發佈 | 手動打包、簽名、上傳,做兩次你就開始討厭人生 | GitHub Actions / Bitrise + Fastlane + TestFlight / Firebase App Distribution |
| 效能與耗電檢測 | 卡頓、掉幀、耗電,使用者不講,直接刪 | Android Profiler / Xcode Instruments(定期跑一次,不要等爆炸) |
折疊機、平板、下一個螢幕:你不是在做「一個尺寸」,你在做「一個概念」
折疊機、平板與多尺寸裝置要求 adaptive layout 與不同互動模型,不能只把版面放大。Jetpack Compose 與 SwiftUI 能降低響應式 UI 的實作成本,但仍需要針對導覽流程與螢幕狀態切換設計邏輯。
平板最容易踩的坑:你以為把手機 UI 放大就好。
結果使用者拿平板是「坐下來用」,他期待的是不同的導航方式、更有效率的資訊密度。
折疊機更怪。
螢幕狀態一變,你 layout 如果沒設計好,就會像變形金剛壞掉那樣,畫面瞬間重排、狀態丟失、鍵盤蓋住輸入框。
Jetpack Compose、SwiftUI 這類工具確實比較好做 responsive。
但它們不是魔法。
最後一句話:你要的是「穩定地活著」,不是追最新框架
高品質行動開發的核心是把基本功做滿:效能、穩定性、離線容錯、裝置測試與自動化發佈,並用工具(Crashlytics、Profiler、Instruments、Fastlane)把問題變成可觀測。新框架可以學,但底盤不穩,學再多也只是換個方式翻車。
我知道你可能還是會問:「那我到底該先做什麼?」
如果你現在很懷疑、很猶豫,那其實是好事,代表你還沒被樂觀害死。
你先抓三件事就好:
- Crash 先能追(不然你連吵架都沒證據)
- 離線不要白畫面(不求完美,求不丟臉)
- 發佈流程自動化(省下來的時間拿去測真機)
手機世界最殘酷的 KPI:使用者的耐心。
收尾給你一個資源關鍵字:去找「Android Vitals」。這個詞拿去搜就夠了,你會看到 Google 對崩潰率、ANR 這些指標怎麼定義,討論會更落地。
