何為與為何React


React 是什麼

一個當紅的名詞 - "React 一套用於建立使用者介面的Javascript函式庫"。

沖著Facebook響亮的招牌,很多人好奇這是什麼東西?函式庫?有什麼新功能?用在什麼地方?

網路上談及React的新聞與教學如雨後春筍般紛紛出現,但很多並未在真正的重點說明,有可能只是一小段程式碼的試作,有的是某個應用的教學,有的則是談談其中的一些功能特色。

這篇文章,主要在談論React是個什麼東西,也是對我內心的許多問題的解答追尋,把它摘錄與寫下來。這篇文章裡面沒半行程式碼,也不是在討論程式碼的。

MVC的"V"

這大概是React一開始公布時過不久的其中一場公開研討會,是由React核心小組之一的Pete Hunt,在2013年10月的JSConf.Asia 2013所講演的:

-Pete Hunt: React - Rethinking Best Practices - JSConf.Asia 2013

其中有有提出幾個關鍵的功能特性和問題回答。

React是個樣版函式庫?

在React的官方網站有一段寫到:

“Many people choose to think of React as the V in MVC”(許多人選擇認定React是在MVC中的V)

我們通常認為MVC的V是個樣版(template)類的函式庫,類似像知名的mustache.js。但"許多人選擇認定…"這聽起來似乎有點不止是的感覺,在Pete Hunt的一篇在Quora的回答文章:Facebook's React vs AngularJS: A Closer Look他一開始結論是:

React components are far more powerful than Angular templates; they should be compared with Angular's directives instead.

React元件遠遠強過Angular樣版;它們應該是要拿Angular的指示(directives)來比較才對。

在另一篇部落格Why did we build React?其中就很明確的講了:

React doesn't use templates. ... React approaches building user interfaces differently by breaking them into components. This means React uses a real, full featured programming language to render views, which we see as an advantage over templates for a few reasons...

React沒有使用樣版. … React用不同的方式來著手處理建立使用者介面,就是把它們打破成一個個元件。這代表React使用真實的、全功能的程式語言來渲染視圖,從幾個理由我們可以看到它會比樣版優秀的地方…

好吧,從說法來看,的確不是樣版類的函式庫,比那個還優秀的東西。應該要拿來比的是Angular的指示(directives),Angular的指示(directives)是什麼,其實是Angular中自定義的DOM元素的標記,這篇What are Directives?有定義說明。

另外從這些文章和最近的實況結合:

  • React只是函式庫,不是個完整的框架,它也不純粹只是個樣版類的函式庫。
  • React使用了元件的概念來處理使用者介面
  • React誕生的時間,剛好是Angular 1很火紅的時間,兩大網路公司的出品,會拿來作比較是一定的。不過React只是個函式庫,Angular則是完整的框架,就像一塊雞排比上排骨便當一樣很難比較,不過要來比幾行程式碼、要學多少東西不太有意義,甚至兩個可以一起使用也可以。

Angular目前已經發展至2版本,架構和1不一樣,整個架構還在測試中。

直指核心 - Virtual DOM

在React問世後,網路上有很多人在討論它的核心特性 - Virtual DOM,這也是React的的一大功能賣點。

DOM的處理在像jQuery這些的函式庫出現後,變得容易許多,但具有愈來愈多資料的應用程式網站,單頁式應用程式(Single Page Application, SPA),整個網頁的DOM結構變得愈來愈複雜而且龐大,一個大概的統計資料(向下滑動幾分鐘後…):

  • twitter.com 有 30k+ 節點
  • facebook.com 有 17k+ 節點

由我們來直接處理DOM,當然是針對會需要的更新或新增的節點來設計。那我們要如何知道DOM發生改變,或是有需要改變?如果還是用老方法,先判斷是否有改變,然後有需要加以更動。那麼如果在很複雜的DOM裡面,加上更多的事件和改變的地方呢?就很需要花費更多的資源來作這些事情。

事實是要處理這麼多的節點的DOM,使用傳統的處理方式根本無法有效率,而且因為資料愈來愈複雜與愈多,不得不要使用新的方法。這時候Virtual DOM就因應而生。

Pete Hunt在演講影片中,拿Doom 3遊戲的背後運作模式來比對React,因為我個人沒設計過遊戲很難理解。不過我可以用一個簡單例子來理解它的設計理念:

無人駕駛車

你可以把Virtual DOM視為一台"無人駕駛車",除了你告訴它要去哪之外,或是大概要怎麼走,之後就不關你的事了,它自然會計算出最理想的路徑(最佳化路徑),以及最安全的方式,到達你要到的地方。相較於無人駕駛車,Virtual DOM會使用另一份DOM的拷貝,用diff algorithm運算出最佳的子節點更新的方式,然後使用有效率的批次處理(讀/寫)DOM節點。

無人駕駛車的使用概念,和由我們開車是完全不同的,我們把開車的工作交給了車子,車子除了要具備原本的性能外,也要有智慧型的自動行駛功能,當然我們也需要拋棄手動開車的"樂趣"。

註:React中不只有Virtual DOM的應用,連Event的處理也是用委託(delegation)的方式

要很深入的了解Virtual DOM到底是怎麼作的,這是一個很不容易的議題,這裡面涉及了更多的技術、數學、演算法等等。首先我們要知道的是,我們怎麼用它能作到什麼,以及能幫助我們什麼,才是目前最重要的。

效能/維護

由Facebook推出React,並實際應用在Facebook網站上的許多功能上,以及幾乎所有的Instagram網站上的功能,成了最強力的客戶實例。這証明Virtual DOM不只是在效能上相較於傳統作法出色許多,也提供了可維護性。網路上有很多關於效能測試的文章,想知道可以google一下。

vs Shadow DOM

常常有聽到Shadow DOM,其實這兩個東西的確是不一樣的東西,Shadow DOM是Web Component的其中一個功能特性,Shadow DOM會在網頁的原始碼中產生DOM的結構,但是是"附著"在DOM子樹結構(subtree),它的功能是"封裝DOM子樹與相關聯的CSS",因為Shadow DOM還是非常新的一種功能,目前只有Chrome、Opera瀏覽器預設直接支援。更多資訊參考以下的說明:

現況(至2015底)

Javascript界的發展幾乎是無止盡的,很多相關的應用,不論是函式庫、框架都很多,這短短的一段時間,有太多可以學的東西,但這些東西很多都是實驗性質的、不穩定的,還有很多問題。

React-Native

一套使用React來建立原生App的框架。可以使用React加上這個框架來開發iOS與Android上的App,由Facebook在2015年初正式對外發佈。Github函式庫在這裡,目前超過2萬5千個星,是很非常熱門的開放原始碼專案。

Framework

  • Flux: 繼React後,Facebook又發佈了這個框架。
  • Redux: 這是另一套框架。由Flux演變,參考了Elm的啟發,目前生態圈發展得很好。有非常多的學習資源和工具。

Virtual DOM的其他函式庫或框架

React起了一個頭,這是一個新的革命性的發展,現在開始有很多Virtual DOM的延申函式庫或應用出現。例如:

  • Virtual DOM:由React啟發的函式庫
  • Elm-html:Blazing Fast HTML
  • Mercury: A truly modular frontend framework
  • Om: A ClojureScript interface to Facebook's React.
  • Mithril: A Javascript Framework for Building Brilliant Applications
  • Ractive: Next-generation DOM manipulation

註:這上面除了virtual-dom外,其他都是框架(Framework)。

誰在使用React

  • Instagram.com: 100%使用React建置
  • Facebook.com
  • Khan Academy
  • Sberbank
  • The New York Times’s 2014 Red Carpet Project

React也在2015初舉辦了研討會,所有的現場影片可以上網觀看:

這裡面也出現了很多新的使用客戶:Netflix、Codecademy

參考資料