前言
在過去的一個多月中,為了能夠更深入的學習,使用React,瞭解React內部演算法,資料結構,我自己,從零開始寫了一個玩具框架。
截止今日,終於可以釋出第一個版本,因為就在昨天,我跑通了之前的一個小專案。
真的從零開始嗎?
其實並不是,我並沒有重新把jsx解析器進行造輪子,我用上了官方的解析器去幫助我解析jsx。
在正式開始寫Luy的時候,還是比較盲目和恐懼的,原因如下
- 雖然都知道React是基於虛擬DOM來渲染的,但是虛擬DOM到底是什麼?怎麼運作的
React的setState是非同步的,這個我們都知道。但是他的非同步和setTimeOut的非同步是一樣的嗎?內部是不是用setTimeOut
實現的? - react的事件合成系統。在react官方中,幾萬行程式碼,有差不多40%左右是用於模擬事件的。這部分內容是如何實現的?為什麼這麼做呢?
- React列表中的key為什麼那麼重要?虛擬DOM的優化策略又是什麼?
帶著這些疑問,我要麼是去讀原始碼,要麼去找文章,但是真正弄懂這些知識,可能還得動手自己實踐一次我才會感到安心。
製造這個玩具框架碰到了很多問題嗎?
雖然說現在React-like的框架一大堆,大家都想做出自己的mini 化方案,但是製造一個React-like框架還是超級困難的,可想而知,當初FB工程師們在沒有React的情況下,是如何造出React的,天才。
原始碼解析不多,而且不完備:很多號稱解析React原始碼的文章其實只是非常淺層次的讀一讀,基本上的套路就是,看到哪裡的程式碼,網上一帖就成了一篇文章了,很多知識點還是得親自去打斷電除錯React官方版本才能知道。
好的文章往往只專研了一兩個點,知識點需要慢慢拼湊:網上不乏好文章的,但是好的文章不可能面面俱到。比如有些人研究setState
,有些人研究生命週期函式,有些人還研究了ref,甚至有些人研究了Vdom。這些知識點很散亂,非常難以拼湊在一起,基本要花一兩天才能搞懂一個知識點。
-
虛擬dom演算法
:我說實話,虛擬DOM的演算法其實並不難,也就是樹的遞迴遍歷,在遍歷的同時建立和比對。但是奇妙的就是,市面上有一堆虛擬DOM產品,雖然大致相同,但是在處理某些地方的時候不一樣,後文會講。 -
列表的key
:虛擬DOM演算法最難的地方。對應的實際場景就是如下:
<ReactComponent>
<div key=`1`></div>
<div key=`2`></div>
<div key=`3`></div>
<div key=`4`></div>
<div key=`5`></div>
<div key=`6`></div>
....
</ReactComponent>
這一個部分難就難在「更新」上,這也是每一款虛擬DOM最不一樣的地方。
為什麼inferno.js這麼快?這個回答裡,其實給出了答案。
而Luy
使用的演算法是:vue2原始碼學習開胃菜,速度上來說非常不錯。
當然我不是吹噓自己的框架有多牛逼,只是實現了這個演算法還是非常開心的。
這部分內容給想學習React原始碼的朋友們
首先,閱讀React程式碼是最直接的方案,但是因為react原始碼實在太多了,我們必須另尋出路。有兩個辦法
- 閱讀react程式碼最初版本(非常的老了…
- 閱讀市面上比較成熟的react-mini框架的程式碼
我選擇了第二種方式,可能會有人說哎呀,你水平不夠。我承認,我水平確實不行,讀react原始碼頭有點痛。
我的方法就是先把東西做出來,然後有了基本思路,再看React原始碼你就知道它在幹什麼了。一定要注意的是:框架裡任何一行程式碼都是為了解決某一個或者多個問題而存在的,當你腦海中不能將這些問題和程式碼聯絡在一起的時候,你他嗎根本就是在讀天書。所以,選擇一個程式碼較少的先讀著,理解react的套路。
- @司徒正美 的anujs:一款了不起的mini 化react方案,支援到IE6。程式碼及其好懂和老練,框架如其簽名:javascript魔法師。如果閱讀過anujs的朋友,一定也會發現Luy部分程式碼很像anujs,沒錯,有很多程式碼我都直接抄的,因為 @司徒正美 的程式碼寫的真的很好。RubyLouvre/anu,是世界上最接近react官方的產品了。
- Inferno.js:另外一款出名的react lite框架,Vdom的速度是最高的,一系列的優化方案非常值得學習
- developit/preact:大名鼎鼎的preact,速度快,體積小而著稱。gzip完只有3k,不過對react官方的支援其實非常的差。比較搞笑的是,當你支援react的輪子的時候,使用compact功能時,其效能大大下降!(哈哈哈哈哈哈哈哈哈笑死我了)
- @鬍子大哈 :他寫的React.js 小書,非常的棒,給予了我造react的最基本知識。
- 40 行程式碼內實現一個 React.js: @鬍子大哈 實現的作品
- snabbdom/snabbdom:其實就是vue的vdom了
- preact原始碼學習(1) – 個人文章 – SegmentFault
- preact原始碼學習(2) – 個人文章 – SegmentFault
- preact原始碼學習(3) – 個人文章 – SegmentFault
- preact原始碼學習(4) – 個人文章 – SegmentFault:這幾片文章的作者都是 @司徒正美 ,全面的解析和官方的對比。牛x到了極點。
- Build your own React.js · GitBook:一篇外國的文章,看完你基本可以造出一個可以setState的react了
- Build Your Own React:第一次渲染:本文也很重要,介紹了react component的幾種模式
- @程墨Morgan :《深入淺出react和redux》一書非常的實在,我也推薦過很多次了,對我理解react和redux很有幫助.
當然,還有很多知識點是通過google得到的,一切來之不易。在讀原始碼的過程中,痛苦但是快樂。
這個框架會有未來嗎?
這個專案其實最初的想法只是學習react的內部原理,但是一路走來我的想法也改變了,會盡自己最大的所能,維護下去,並且跟進react官方的變化(說實話createPortal Luy也是支援的!)
畢竟,學習其實就是模仿,創造永遠在模仿的前提下。最近公司準備上一個新的小專案,也是我第一個全權負責的專案,所以我決定上一把我的Luy進行試點(好就好在,Luy更換react其實是無痛的,實在有什麼問題,直接換react上,哈哈哈
最後
程式碼在這裡,框架地址:Luy,總共加起來目前只有1100+行,不多,可以作為「react套路學習版本」