如何看待 React 的替代框架 Preact?

由 React License 引發的換框架問題迫在眉睫。

缺少了 Synthetic Events 的 Preact 是一個合適的備胎么?

Fast 3kb React alternative with the same ES6 API. Components Virtual DOM.

相關問題:

如何看待百度要求內部全面停止使用React / React Native?

阿里還會使用react嗎?


我也來說一下吧

preact與react的差異點

首先, 虛擬DOM樹結構不一樣,在preact中, children在props中永遠是數組,但是在react中可能是字元串,數字,null, undefined數組或單個虛擬DOM。因此react可以這樣用, `a.props.children.props.children`.而preact只能a.props.children[0].props.children. 在antd有大量這樣的用法。

其次,ref機制有react有點差異,反正有些組件,替換了preact後,http://this.refs.xxx就為undefined。

再次, Children.map實現也不對,官方是對原來的虛擬DOM進行複製,並修改或添加上一個新的key值,而不是直接用舊的虛擬DOM。這在做ListView時就可能出錯。

沒有處理游標與選區的丟失,這會在富文本編輯器或表單格式化上遇到大坑。

還有, 對一個虛擬DOM子樹是否繼續更新下去,如果它們的type, props, key都一樣,或者它們的引用也一樣,可能也會繼續diff,官方還會比較context!!!!這個許多react-like沒有考慮到。React-Router就非常依賴context對象進行多層的組件間傳遞。

事件系統更不用說,我做mouseenter/mouseleave也費了很大勁,這與jQuery給出的方案也不太一樣,是用到了 LCA。react的事件系統 是基於冒泡的,不像preact那樣簡單綁在元素節點上。在事件觸發過程,用所有更新會截留,放在dirtyComponent中,然後再排序調用。這樣做可以進行一些state 合併。

diff演算法沒有考慮到children出現相同key的情況 ,假如說,children裡面有兩個數組,將它們扁平化後就可能出問題。

setState與forceUpdate的回調會不斷推遲。比如在更新過程中,子組件在componentWillReciveProps再調用了父節點的setState,這裡可能不一樣。

我這裡有一個比較表,可以看一下

RubyLouvre/anu

以後我會單獨寫文章介紹


不邀自來。

已經研究Preact有一段時間,並且阿里內部已經有部分業務開始試點Preact。初次關注Preact是在今年年初,為了配合Fusion(不了解Fusion,可以看這篇文章,阿里巴巴的Fusion Design是如何運作的?)在前台場景落地的載入性能問題,開始在社區尋找React的替代品,然後關注到了Preact,Gzip後3kb的大小確實很吸引人,然後當時star數量在7k左右,覺得應該還可以,便入坑了,配合preact-compat這個包兼容性還可以,但是也遇到了一些問題。

第一部分便是實現兼容性問題, 已經解決的就不說了,下面說一些官方還沒有解決的兼容性問題:

  1. props.children在reRender的時候會丟失的問題 Children is lost when component reRender. · Issue #660 · developit/preact
  2. setState的回調的時機問題 Callback of `setState` is called at not expected time. · Issue #556 · developit/preact(這塊React 16.x 會變動)
  3. renderSubtreeIntoContainer的元素的didMount的生命周期問題。舉個例子: 假設組件Gateway在didMount的時候使用了renderSubtreeIntoContainer的方法渲染了Content,Content裡面包含組件Test, Overlay使用了Gateway作為children,React的didMount順序是`Gateway -&> Test -&> Content -&> Overlay`, 而Preact則是`Gateway -&> Overlay -&> Test -&> Content `.
  4. ReRender error when using dangerouslySetInnerHTML · Issue #855 · developit/preact
  5. 沒有使用事件委託的方式進行事件綁定,這會導致現在大多數組件庫的彈層的點擊文檔消失的特性不能正常工作。而且沒有合成事件,一些比較偏門的事件可能會有兼容性問題,這部分我們沒有提PR,原因是作者對庫的大小要求比較嚴格,提PR十有八九不會被接受,而且這是一個非兼容性變更。
  6. diff演算法的問題。由於體積較小,所以Preact僅僅實現了一些常見的diff場景,一些優化的措施沒有,比如沒有key的節點處理問題等,還有就是Preact將一些屬性緩存到DOM節點上,拿真實的DOM節點與VNode進行diff,這與React的處理機制也是不同的。

第二部分是周邊的生態問題。我們知道對於生產環境而言,質量是非常重要的,但是遷移到Preact後,你會發現沒有很好的辦法來寫單元測試,因為Fusion採用的是Enzyme作為測試方案,所以我們又為Preact編寫了與Enzyme的兼容包來進行單元測試的編寫,唯一不足的是只能支持mount模式。還有就是社區的大部分組件庫使用Preact不一定完全兼容,這部分就有點尷尬。

上面問題僅僅是我們在使用過程當中遇到的一些問題,並不代表後續不會存在其他的問題,為了能快速的解決上述作者可能不會接受PR的問題,Fusion項目組內部Fork了一份Preact進行維護,目前已經在業務上開始跑起來,也剛好碰到了React的專利問題,剛好可以派上用場。

總結下來就是可以用,但是做好入坑的準備,遇到非兼容性問題的幾率和項目的複雜度成正比。


經過本人這幾天的使用,目前來看 Preact 是最適合做為 React 的替代框架。當然前提是你真的需要替換的情況下。

首先 Preact 的介紹中就表明它的定位是非常明確的:

Fast 3kb React alternative with the same ES6 API

就憑 same 這個詞就可以秒掉大部分同類框架,比如 inferno,而且inferno的作者trueadm已經跳巢到React團隊,現在交給了別人維護,動作慢了很多。

React本身只是做View,對外API很輕,複雜都藏在內部實現。這也造成了它比較容易被替代。

React生態非常的繁榮,慶幸的是Preact能夠支持大部分React生態中的框架,而且作者對此事也比較上心,如對 redux, react-router 支持比較好。阿里內部的 fusion 據說也已經支持 preact。像 ant-design 目前部分還有一些問題,不過大部分組件已經可以用了。

對於 React 常被人不明覺厲的 Synthetic Events,我覺得有點過度設計,油管上有個視頻分析 React Event 代碼 https://www.youtube.com/watch?v=dRo_egw7tBct=1211s,當時把 Dan 都搞懵了。React 通過在 document 上監聽所有事件,然後內部重新實現了一套事件處理機制來抹平瀏覽器對不同事件API的不同,這樣確實性能上確實會提升,不過也會有一些 bug,如綁定多個不同事件時觸發順序不能保證問題,還有調試棧非常深。Preact 則使用簡單粗暴型方案,直接綁定到元素上,目前瀏覽器API逐漸一致,就不需要再做各種兼容。而且調試時調用棧更淺,且可以使用 getEventListeners 清晰看到DOM到底綁定了哪些事件。

最後,Preact 官方一直在維護一份 react 遷移的文檔 https://preactjs.com/guide/switching-to-preact 對於小型項目直接用就可以了。如果遇到解決不了的問題,可以給我留言。


我們內部的產品在調研切換我們自研的類 React DSL 的框架 alibaba/rax 。我們目前在考慮的問題是 React 的協議僅限於 React.js 還是 React DSL,如果是後者,遷移到 preact、rax 這些,仍然逃不了協議的限制。。。


缺少 Synthetic Events 是個好事,因為這個機制fb有申請專利,參見我的另一個提問中一位答主的回答。


preact對react的兼容性不如inferno好


謝邀。

我為Preact寫過一個專欄文章《Preact: 可作React的備胎》,可以作為參考。

由 React License 引發的換框架問題迫在眉睫。

呵呵,迫在眉睫,反正我沒覺得迫在眉睫。


使用過preact,確實可作為react的替代品,但是react的防禦性條款並沒有想像中那麼可怕,絕大多數公司的體量facebook根本瞧不上


大公司都不用了,還替代preact?自己拿來娛樂玩玩吧!


總體來說 Preact 真心不錯,3KB的大小也相當吸引人。稍有美中不足的是在事件處理方面的兼容性可能沒 React 那麼好。另外想吐槽一下它的源碼,運算符跟表達式之間沒空格,而且有些變數命名用單個字母。本來想閱讀它的代碼研究一下,但實在是看著費眼(放棄了)。


不建議用 建議回歸web本真 別效果做不到原生 對ios api了解不如ios開發 對安卓api了解不如安卓開發 還拋棄了自身該用


推薦閱讀:

如何評價性能大幅提升的Chrome 53?
安卓工程師轉做前端,有什麼好的框架推薦?
Markdown編輯器 做成 WYSIWYG(所見即所得)形式會不會有什麼弊端?
閉包(closure)在非同步請求處理中有哪些優勢?
如何用 TypeScript 提高 JS 工程的健壯性?

TAG:前端開發 | JavaScript | 前端框架 | React |