DHH 談混合移動應用開發

暢銷書作家、演說家、賽車手、業余攝影師、顧家好男人
37signals 在2013年2月發布了 Basecamp 的 iPhone app,在此之前我們就使用原生開發(native)還是混合開發(hybrid)做了許多嘗試。在2012年項目啟動的時候,大多數人都傾向于原生開發。
非死book 在2012年發布了他們新的 iOS app,為了獲得更好的用戶體驗,他們放棄了原來的 HTML5 混合開發方式。考慮到2010~2011年的時候,HTML 在移動端的性能確實不盡如人意,這個決定在當時看來也在情理之中。2010年的時候我們覺得 iPhone 3G/3GS 夠眩夠快,但按照現在的標準來看它們就太慢了。因此在為移動應用開發做架構設計時,我們需要考慮新的移動設備的計算能力,而不是那些老的過時的設備。
移動開發架構設計不需要過多考慮設備的性能
我們從一些測試中得出的一個結論是:現在的移動設備計算能力都很強,運行原生應用和 HTML 應用的效果差別不大,而 HTML 開發的成本則要比原生開發小得多。
當然這個結論在某些領域并不太適用。如果你要開發一個 3D 游戲,原生開發方式能夠帶來更好的游戲體驗。但如果你的移動應用象 Basecamp 一樣側重信息處理,為了降低開發成本,你就可以考慮混合開發方式。我們就是如此,下面是我們三代移動產品的發展軌跡:
第一代產品:原生外殼(native shell)+嵌套WebView
這個版本就是一個簡單的原生外殼負責界面導航,嵌套一個 WebView 來顯示 Basecamp Rail application,顯示的基本上都是我們移動網站頁面,再加上一些特殊的樣式。
在移動網站的頁面上嵌套一個原生的殼,聽起來還是 Web 頁面,但實際帶給用戶的體驗確是非常不同。用戶可以在 Apple App Store 找到我們的 app,他們一旦登錄 app 后可以再也不用重新登錄(移動版本的 Safari 似乎會經常清空 cookie,讓你不得不重新登錄)。我們的 app 大受歡迎,用戶評分在4和5之間。
整個 app 由一名程序員和一名設計師開發,成本不高,因為我們可以在已有的移動網站的基礎上開發。
如果我們當初開發完全原生的 app,用10個人的團隊1年半的時間也未必能完成。
第二代產品:原生外殼+原生導航界面
幾個月前發布的 Basecamp Android app 是我們的第二代產品,我們在其中做了大量的改進。
從第一代 iPhone app 中我們感受到了原生導航界面的威力,所以在 Android 版本中,我們由 HTML 頁面導航轉向了原生導航界面。我們從 HTML 頁面生成原生導航界面,用戶體驗更加流暢,原生界面和 HTML 頁面的體驗差別越來越小,甚至很難區分哪些是原生部分,哪些是 HTML 。
Android 版本是由一兩個程序員和一個設計師開發(50%投入)完成的。我們重用了移動站點和 iPhone app 中使用的所有 webview,大大提高了開發效率,同時用戶也很買賬,超過1000名用戶打了4.5~5的高分。
很多公司在抱怨他們的 iOS 移動項目進展緩慢,Android 項目似乎更是如此。或許他們已經習慣了 iOS 項目的開發流程,也許是因為 Android 的屏幕碎片化問題,但是這些對我們來說那都不是事。我們推出的 Android app 表現良好,重用了95%的代碼,開發團隊也一直保持在小規模。
因地制宜地運用原生開發方式
目前我們正在開發第三代產品,發布的平臺暫時保密,不過你應該也不難猜到。在前兩代產品中,我們增加了原生導航界面的使用,同時進一步確定了以 webview 為核心的整體架構。在第三代產品中,我們將因地制宜地選擇需要使用原生開發的功能,好鋼要用在刀刃上。
從之前的100% HTML,到現在的90% HTML +10%原生,我們會選擇最值得做原生開發的那10%的部分,最終目的是讓 app 原生部分和 HTML 部分的體驗沒有太大區別。
混合開發模式使用的技術
混合開發模式在技術很簡單,主要是處理 webview 的集成、Web 頁面的加載,以及原生內容和 HTML 內容之間的交叉鏈接,其實可能比你想像的還要簡單得多。
HTML 方面,我們的 Rails Web 應用支持 Web 和移動兩大平臺,其中 Rails 4.1 feature of variants 起了很大的作用。
這也很大程度上有助于我們發布新功能。設想一下如果我們每次需要更新這么多平臺:Rails desktop app, a Rails API app, a client-side MVC app, a mobile web wrapper app, an Android app, and an iPhone app,像我們這樣只有10個程序員和7個設計師的公司根本無力承擔如此巨大的工作量。
除了工作量的減輕,bug 修復效率也提高了,因為大部分的代碼邏輯是在 Web 服務器端,我們可以隨時修改代碼并發布,不用通過 Apple App Store 的審批流程。所以我們的移動 app 和 Web 應用一樣,也是持續部署。
就如我之前提到的,混合模式開發并不適用于所有情況。在2010年以前,那時手機的處理能力都不強,所以 HTML/JS 的體驗并不好,用戶也不喜歡。但是時過境遷,現在手機的處理能力大大提高了,HTML/JS 的性能也不再是一個問題。
混合開發模式對原生開發模式的挑戰
混合開發模式在降低開發復雜度方面有它的優勢,如果你的產品是以顯示和處理信息為主,我認為都可以不同程度地采用這個模式。
對于小型團隊和公司而言,并不一定需要采用 iOS 原生 app 先行的模式。使用混合模式,不需要你重頭開發一個 app,這樣可以降低維護成本,將來擴展到其他平臺也更為方便。
當然我知道會有很多人質疑這個模式,或許因為他們的 app 中有很多地方需要原生開發(也許僅僅是他們自己這樣認為罷了)。又或許他們已經花了很多時間讓 app 里的 UITableView 看起來非常漂亮,以致如果其他地方不這樣的話顯得不是太完美。再或許大公司就是喜歡耗時耗力的原生開發,有錢就是這么任性。
無論怎樣,混合開發當下應該能夠成為我們移動開發策略的一個選擇。如果你認為這是一個好的選擇,那么恭喜你,盡情愉快地玩耍吧!
原文鏈接:Hybrid sweet spot: Native navigation, web content
下面補充一些 David 答讀者問:
Mike Waite @ 2014-05-08:我很好奇你是如何決定哪些功能要用原生開發?
David @ 2014-05-08:主要靠感覺,這畢竟不是一門科學。如果你感覺你app的某一部分如果用原生開發會更好些,可以嘗試做快速原型(spike)。很多 時候我們通過這種方式證明我們的想法其實是錯的。當然如果你需要使用到手機上的功能如:攝像和其他設備時,HTML目前還不太適用,不過永遠也不要把話說 死。
Mike Parsons @ 2014-05-08:好文。很好奇你們是否使用 PhoneGap 或者 Cordova 這樣的框架,或者你們自己開發了一個?
David @ 2014-05-08:我們沒有使用任何框架。(此處省去xxx字)
Derick @ 2014-05-08:你怎樣解決 Android 瀏覽器渲染速度慢的問題?這也是 Android 平臺上更多人傾向開發原生app得原因。
David @ 2014-05-08:不知道你這個結論是近期的還是以前的?Basecamp 的 Android app 在我的 Nexus 5 和 HTC One 上面運行得非常流暢。
Derick @ 2014-05-08:就是最近。我猜測可能和你使用JavaScript的多少有關系。因為以我個人的經驗,Android 上 JavaScript 的運行速度非常慢。如果你感興趣可以看看下面的文章:https://www.timroes.de/2013/11/23/old-webview-vs-chromium-webview/
David @ 2014-05-08:我們使用了很多JavaScript,當然沒有 Web MVC 客戶端用得那樣多。另外我們使用了 Turbolinks :)