Web前端開發與iOS終端開發的異同

TP_funny發表於2014-12-25


語言
前端和終端作為面向使用者端的程式,有個共同特點:需要依賴使用者機器的執行環境,所以開發語言基本上是沒有選擇的,不像後臺想用什麼就用什麼,iOS 只能用 Objective-C,前端只能 javascript,當然 iOS 還可以用 RubyMotion,前端還能用 GWT/CoffieScript,但不是主流,用的人很少,真正用了也會多出很多麻煩。

這兩者有個有意思的對比:變數/方法命名的風格正好相反。蘋果一直鼓吹使用者體驗,寫程式碼也不例外,程式命名都是用英文全稱並且要多詳細有多詳細,力求看變數和方法名就能知道是幹嘛的,例如 application:didFinishLaunchingWithOptions:。而 js 因為每次都要從網路下載,要力求減少程式碼體積,所以變數方法名是儘量用縮寫,實際上有程式碼壓縮工具,無論變數名寫多長最終上線的效果是一樣的,但大家也都習慣了用短的命名,例如上述 objc 的 application:didFinishLaunchingWithOptions:方法在 js 裡習慣的命名是:$()。

objc 與 js 都是動態語言,使用起來還蠻像,但 objc 是編譯型,速度快,很多錯誤也能在編譯過程中被發現,js 是解釋型,效能依賴於解釋引擎,即使在強勁的 v8 引擎下效能也趕不上編譯型語言,語言太動態,變數完全沒有型別,寫起來爽,debug 起來稍微費點勁。一直感覺 js 輕巧靈活放蕩不羈充滿各種奇技淫巧,objc 中規中矩沒c++ java 那麼嚴肅也沒有 js 那麼靈活。

執行緒
前端開發幾乎不需要執行緒這個概念,瀏覽器實現上頁面 HTML 和 CSS 解析渲染可能與 js 不在同一個執行緒,但所有 js 程式碼只執行在一條執行緒上,不會併發執行,也就不需要考慮各種併發程式設計的問題。在新的 JS 特性中可以建立 worker 任務,這樣的任務是可以另起一條執行緒並行執行的,但由於並不是所有瀏覽器都支援,不同執行緒傳遞資料各個標準定的還不一樣,使用場景也少,似乎沒有大規模用起來。對於資料庫操作/傳送網路請求這樣的任務是在不同於 js 程式碼執行執行緒的,不過這些都由瀏覽器管理,前端無需關心也無法影響這些執行緒,只需接收事件回撥,不需要處理任何併發問題。

終端開發需要大量使用多執行緒,iOS 有一條主執行緒,UI 渲染都在這個執行緒,其他耗時長的邏輯或者資料庫 IO/網路請求都需要自己另開執行緒執行,否則會佔用主執行緒的時間,導致介面無法響應使用者互動事件,或者渲染慢導致滾動卡頓。程式邏輯分佈在多個執行緒裡跑,需要處理好各種程式碼併發執行可能帶來的資料不一致/時序錯亂之類的問題,併發也導致有些 bug 難以排查,一不留神就掉坑,需要適當用一些佇列/鎖保證程式的執行順序。iOS 提供了一套多執行緒管理的方法 GCD,已經把執行緒和佇列封裝得非常簡單易用功能強大,比其他端或後臺是好很多了,但還是會花大量功夫在處理多執行緒問題上。

儲存
終端開發需要大量的資料儲存邏輯,手機 APP 不像瀏覽器,使用者開啟瀏覽器必定是連著網,但開啟一個 APP 時很可能是離線,也很可能處於網路狀況極差的移動 GPRS,所以必須把之前請求回來的資料儲存好。儲存資料後又需要與服務端最新的資料同步,如果全量同步資料量太大,耗流量速度也慢,於是需要增量同步,需要與服務端一起制定實現增量資料返回的方案,需要處理好客戶端與服務端資料一致性的問題。當資料儲存量大結構複雜時,還需要利用好有限的記憶體做 cache,優化各類儲存查詢效能。

前端在桌面端很少需要儲存,除非是 Single Page App,不儲存自然就不需要資料更新的一系列工作,資料都是從後臺取出拼接後直接顯示到頁面上,即使像微博有可以在頁面內不斷載入更多資料,資料也只存在於記憶體,不會持久化儲存,因為桌面端網速穩定,不計流量,所有資料可以直接從後端拿取,客戶端沒必要再做一套儲存。移動端那些做得很像原生 APP 的 Web 應用就跟終端開發一樣了,資料同樣儲存到 SQLite,儲存邏輯以及要處理的問題都差不多。

框架
在第三方框架上 Web 前端和 iOS 開發完全相反,Web 原生弱小又十分開放,讓大量第三方框架和類庫可以施展拳腳,而 iOS 原生強大又十分封閉,導致第三方框架沒有多少生存空間。

瀏覽器一開始只為內容型的網頁而設計,js 也只是這個網頁上能加點小特效的指令碼語言,在 Web 應用時代跟不上發展,需要很多第三方庫和框架輔助,再加上前端開發是完全開放的領域,導致庫和框架百花齊放多如牛毛,在初期多數庫的作用集中在封裝 dom 操作,大家不斷重複造 dom 操作基礎庫的輪子,在一段時間百家爭鳴後獨尊 jQuery,在有使用庫的網站中 90% 以上使用 jq,幾乎成了個標準基礎庫。後期大家已經不再重複造這個基礎庫的輪子了,多了一些程式碼組織和前端架構的框架,例如一些幫助專案模組化的框架 require.js,MVC 框架 backbone/angular.js 等。

iOS 開發蘋果已提供了完整的開發框架 cocoa,而這框架在每一代系統中都在升級優化和添磚加瓦,開發模式也已經定型,第三方框架沒有多少生存空間,大量流行的開源專案是一些通用元件和庫,像網路請求庫 AFNetworking,資料庫操作庫 FMDB。而一些大的框架像 beeFramework/ReactiveCocoa 較難流行起來。

相容
前端開發需要相容大——量的瀏覽器,桌面的 chrome,safari,ie6-ie10,firefox,以及各種套殼獵豹 360 等瀏覽器,移動端 iOS/Android 各自的瀏覽器,以及無限的不同的螢幕尺寸。看起來挺可怕,實際上也沒那麼難搞,只是拿出來嚇唬下人。桌面端 chrome/safari 以及各種套殼的極速模式用的都是 Webkit,差異很小,firefox 也大體遵從標準實現,與 Webkit 差別不大,舊的 ie6/7 就需要特別照顧,不過很多網站都不支援 ie6 了,移動端更是一家親,全是 Webkit,除了新特性上的支援程度不一,其他差異不大。對於不同的螢幕尺寸,高階點的會用響應式佈局,針對不同螢幕尺寸自適應到不同佈局,一般點的桌面端定死寬度,移動端拉伸自適應寬度就搞定。

終端開發也需要相容各種不同的系統版本和手機尺寸,Android 不用說,iOS 也有 3.5/4/4.7/5.5/9.7 英寸這些尺寸,不過相容起來跟 Web 一樣挺容易,就是自適應寬度,iOS 的 UIKit 把這些都處理好了,還有 autolayout,sizeClass 等高階特性可用,在尺寸上並不用花太多功夫。系統版本上 iOS7 為分水嶺,iOS7 前後版本 UI 上差異比較大,需要做一些功夫相容,不過 iOS 使用者更新換代很快,預計再過一兩年 iOS7 以下使用者就可以忽略了。

效能
終端和前端都是面向使用者的,效能優化目的都是儘快呈現內容,以及讓程式在使用者操作下流暢執行。終端主要關注的是儲存/渲染效能。當一個 APP 儲存資料量大,資料關係複雜時,資料查詢很容易成為效能瓶頸,需要不斷優化資料存取的效率,規劃資料 IO 執行緒,設計記憶體 cache,利用好終端裝置有限的記憶體,渲染上避免重複渲染,儘可能複用檢視,尋找最高效的渲染方案。

前端關注頁面載入速度,由於 Web 頁面的結構/樣式/程式/資源圖片都是實時請求的,要讓頁面更快呈現內容,就要優化這些請求,讓這些資源以最快速度載入下來,包括合併圖片/合併程式碼減少請求數,壓縮程式碼,並行請求,根據版本號快取程式碼請求,gzip 壓縮,模組/圖片懶載入等。此外跟終端一樣也關注渲染效能,遵從一些規則避免頁面 reflow,避免使用 CSS 陰影這樣耗效能的特效,用 CSS3 動畫代替 js 等。

編譯
終端開發需要編譯的過程,把程式編譯成機器語言,再與各種庫連結後生成平臺對應的可執行檔案,最後由作業系統排程執行。在 iOS 終端開發中編譯和連結的規則蘋果已經在 xcode 這個開發工具上封裝好,一般開發可以不用關心,但有深層需求時還是需要跟編譯打很多交道,例如用編譯前端 Clang 自定義靜態程式碼檢測規則,寫編譯指令碼做自動化編譯和持續整合,打包生成靜態庫,根據連結後的可執行檔案的組成優化 APP 體積等。

前端開發的程式則不需要編譯過程,只需要把程式碼扔給瀏覽器,瀏覽器邊解析程式碼邊執行。雖然 js/css 程式碼寫完無需做任何事情瀏覽器就可以解析執行,但為了上面說的效能優化,前端程式碼上線前會對所有程式碼和資原始檔進行處理,這些處理包括:壓縮合並 js/css,合併 css sprite 圖,處理模組依賴,處理程式碼資源版本號,處理資源定位等。這個過程很像傳統程式的編譯,把給人看的程式碼優化處理成給機器看的,並解決一些依賴關係,可以算是前端的編譯過程。像 grunt.js/fis 這些工具可以幫助完成這個編譯過程,通常前端編譯跟上線部署結合在一起,作為上線系統的一部分。

安全
前端和終端的安全性問題上雖然不需要像後端考慮得那麼多,但還是有些需要注意。在請求的安全上,終端和前端都一樣,使用者向後端傳送的請求都需要經過層層路由,不知道在哪裡就被截獲篡改或回放了,於是需要做一些措施防禦這些情況,最常見的就是身份驗證,多是採用會過期的 token 形式代替使用者名稱密碼,防止被抓包後黑客可以永遠登陸這個賬號。資料安全要求高的會用加密傳輸,或者使用 https,另外還需要看情況處理一些 DNS 劫持,運營商廣告植入等問題。

其他安全問題終端很少考慮,在未越獄的 iOS 機器上系統已經幫忙保證了整個 APP 執行環境的安全,而在越獄的機器下惡意程式擁有 root 許可權可以做任何事情,APP 也難以防範。前端方面瀏覽器的特性使前端開發有幾個安全隱患,一是 Web 頁面上任意位置都可以動態插入 js 程式碼,瀏覽器會無區別地執行這些程式碼,二是身份驗證資訊都統一儲存在 cookie 裡,三是頁面上可以隨意通過 iframe 嵌入其他網站的頁面。造成 XSS、CSRF、cookie 劫持這些攻擊手段,所以前端寫程式碼時都需要考慮還這些安全問題,做好相應的防範,最簡單和重要的防範就是對所有使用者輸入輸出的內容做完整的過濾,避免頁面內被嵌入惡意程式碼。

互動/開發
最後說下對這兩個領域在互動和開發上的個人感觸。以前在做 Web 前端時,感覺 Web 讓人機互動倒退了十年,互動都是硬邦邦的點選—啪一下出來結果,滾動是一格格地重新整理,很多人當時在鼓吹 html5 可以做出多麼炫的效果時,實際上 FLASH 在十年前就可以做出來了,還比最現代的瀏覽器更流暢。iPhone 流行後,人機互動終於恢復了應有的水平,體驗上比 Web 流暢太多,指尖互動/流暢的動畫/便捷的滑動手勢/無限制的實現,主流終於恢復或超越了十年前 Flash 的水平。

但人機互動提升了,開發方式卻大倒退,Web 的開發方式非常先進,使用者用到的都是最新版本,發現 bug 可以馬上上線秒修復,特別適用於網際網路環境下的快速迭代,而終端 APP 不行,撇開 iPhone 的稽核不說,Android 也無法做到保證使用者用的是最新的程式,用的都是傳統的客戶端更新的方式,bug 的修復版無法及時給到使用者,無法一天上線幾十次,需要維護很多舊版本,開發方式倒退回 Web 時代以前。這都是因為行動網路不穩定以及流量有限造成的,移動端無法像桌面端瀏覽器那樣完全依賴網路,所以在行動網路穩定流量免費之前,開發方式都不會有多大變化。

另外並不看好 HTML5,網路上說它可以取代 APP 說了三四年,到現在也沒什麼戰績,我看不到它的優勢,原生 APP 可以獲得更多的系統資源,更流暢的人機互動體驗,HTML5 在這方面永遠比不上,而它在移動端網路和流量的限制下也無法發揮 Web 的開發優勢,所以它不會成為主流,只適合做一些輕量的小東西。
來自:部落格園
相關閱讀
評論(1)

相關文章