也許,DOM不是答案
有一個詞"手機網站"(mobile web),指供手機瀏覽的網站,但它是不存在的。
人們提到"移動互聯網"的時候,其實專指另外一樣東西:手機 App。
一、Web App vs. Native App
比起手機 App,網站有一些明顯的優點。
- 跨平臺:所有系統都能運行
- 免安裝:打開瀏覽器,就能使用
- 快速部署:升級只需在服務器更新代碼
- 超鏈接:可以與其他網站互連,可以被搜索引擎檢索
但是,現實是怎樣呢?
(1)體驗差。手機 App 的操作流暢性,遠超網站。
(2)業界不支持。所有公司的移動端開發重點,幾乎都是原生 app。
(3)用戶不在乎。大多數用戶都選擇使用手機 app,而不是網站。
如果將來有一天,Web app 會成為主流,一定有一個前提,那就是它的性能可以趕上 Native app。
二、為什么 Web app 有性能瓶頸?
Web app 輸給 Native app 的地方,不是界面(UI),而是操作性能。主要是互動(interaction)和動畫(animation)這兩方面,會出現卡頓(jank),用戶會感覺到明顯的時滯,有時簡直慢得難以忍受。
Web app 的性能瓶頸,主要有以下原因。
(1)Web 基于 DOM,而 DOM 很慢。瀏覽器打開網頁時,需要解析文檔,在內存中生成 DOM 結構,如果遇到復雜的文檔,這個過程是很慢的。可以想象一下,如果網頁上有上萬個、甚至幾十萬個形狀(不管是圖片或 CSS),生成 DOM 需要多久?更不要提與其中某一個形狀互動了。
(2)DOM 拖慢 JavaScript。所有的 DOM 操作都是同步的,會堵塞瀏覽器。JavaScript 操作 DOM 時,必須等前一個操作結束,才能執行后一個操作。只要一個操作有卡頓,整個網頁就會短暫失去響應。瀏覽器重繪網頁的頻率是 60FPS(即 16 毫秒/幀),JavaScript 做不到在 16 毫秒內完成 DOM 操作,因此產生了跳幀。用戶體驗上的不流暢、不連貫就源于此。
(3)網頁是單線程的。現在的瀏覽器對于每個網頁,只用一個線程處理。所有工作都在這一個線程上完成,包括布局、渲染、JavaScript 執行、圖像解碼等等,怎么可能不慢?
(4)網頁沒有硬件加速。網頁都是由 CPU 處理的,沒用 GPU 進行圖形加速。
上面這些原因,對于 PC 還不至于造成嚴重的性能問題,但是手機的硬件資源相對有限,用戶互動又相對頻繁,結果跟 Native app 一比,就完全落在了下風。
三、FlipBoard 的解決方案
FlipBoard 原本是一個手機 App,最近開始部署 Web 版本,結果就遇到了上面的問題:Web 版的體驗不佳。
上周,他們將解決方案公布在網站上,結果引起了業界轟動,因為這是一個史無前例的解決方案:
---- 他們沒有使用 DOM,而是將整個網站用 canvas 輸出!
你可以用手機打開 flipboard.com,體驗一下,看看跟 Native app 有沒有差別。如果你沒有帳號,可以直接打開這里或這里。
這個方案的出發點是這樣的:如果將網頁變成了一個個 canvas,用戶就等于在跟圖片互動,這樣就繞開了 DOM,降低了操作時滯。而且,canvas 可以被硬件加速,這樣就提高了性能。具體的技術細節,可以參考原文。canvas 的轉化基于 React 框架實現,FlipBoard 開發了一個專門的庫 React-canvas,已經開源。
這個方案引發了很多爭議(這里和這里), 主要是 canvas 只是一個位圖,本身沒有語義,如果要在它上面實現 UI,等于 HTML 語言已有的東西都要再發明一遍,比如如何實現超鏈接、如何實現 CSS 效果等等。一些最簡單的東西都變得很麻煩,因為 canvas 不是自適應的(responsive),文字在哪里斷行,都要自己計算,而且用戶也無法選中文本。另外,怎么讓搜索引擎檢索網頁,解決起來也不是很容易。
但是不管怎樣,這是一個有意義的嘗試。
四、未來的路
James Long 對 FlipBoard 的嘗試,寫了一篇評論《Radical Statements about the Mobile Web》。本文就受到了那篇文章的啟發。
在文中,James Long 對未來的 Web app 提出了幾點預測,我認為很值得分享。
(1)多線程瀏覽器。每個網頁應該由多個線程進行處理,主線程只負責布局和渲染,而且應該在 16 毫秒內完成,JavaScript 由 worker 線程執行,這樣就不會發生堵塞了。Mozilla 正在開發的 Servo 就是這樣一個項目。
(2)DOM 的異步操作。JavaScript 對 DOM 的操作不再是同步的,而是觸發后,交給 Event Loop 機制進行監聽。
(3)非 DOM 方案。瀏覽器不再將網頁處理成 DOM 結構,而是變為其他結構。React 的 Virtual DOM 方案就是這一類的嘗試,還有更激進的方案,比如用數據庫取代 DOM。
(完)