導航:首頁 > 源碼編譯 > react源碼有多長

react源碼有多長

發布時間:2024-05-08 05:47:19

㈠ Hermes源碼分析(二)——解析位元組碼

前面一節 講到位元組碼序列化為二進制是有固定的格式的,這里我們分析一下源碼裡面是怎麼處理的

這里可以看到首先寫入的是魔數,他的值為

對應的二進制見下圖,注意是小端位元組序

第二項是位元組碼的版本,筆者的版本是74,也即 上圖中的4a00 0000
第三項是源碼的hash,這里採用的是SHA1演算法,生成的哈希值是160位,因此佔用了20個位元組

第四項是文件長度,這個欄位是32位的,也就是下圖中的為0aa030,轉換成十進制就是696368,實際文件大小也是這么多

後面的欄位類似,就不一一分析了,頭部所有欄位的類型都可以在 BytecodeFileHeader.h 中看到,Hermes按照既定的內存布局把欄位寫入後再序列化,就得到了我們看到的位元組碼文件。

這里寫入的數據很多,以函數頭的寫入為例,我們調用了visitFunctionHeader方法,並通過byteCodeMole拿到函數的簽名,將其寫入函數表(存疑,在實際的文件中並沒有看到這一部分)。注意這些數據必須按順序寫入,因為讀出的時候也是按對應順序來的。

我們知道react-native 在載入位元組碼的時候需要調用hermes的prepareJavaScript方法, 那這個方法做了些什麼事呢?

這里做了兩件事情:
1. 判斷是否是位元組碼,如果是則調用createBCProviderFromBuffer,否則調用createBCProviderFromSrc,我們這里只關注createBCProviderFromBuffer
2.通過BCProviderFromBuffer的構造方法得到文件頭和函數頭的信息(populateFromBuffer方法),下面是這個方法的實現。

BytecodeFileFields的populateFromBuffer方法也是一個模版方法,注意這里調用populateFromBuffer方法的是一個 ConstBytecodeFileFields對象,他代表的是不可變的位元組碼欄位。

細心的讀者會發現這里也有visitFunctionHeaders方法, 這里主要為了復用visitBytecodeSegmentsInOrder的邏輯,把populator當作一個visitor來按順序讀取buffer的內容,並提前載入到BytecodeFileFields裡面,以減少後面執行位元組碼時解析的時間。

Hermes引擎在讀取了位元組碼之後會通過解析BytecodeFileHeader這個結構體中的欄位來獲取一些關鍵信息,例如bundle是否是位元組碼格式,是否包含了函數,位元組碼的版本是否匹配等。注意這里我們只是解析了頭部,沒有解析整個位元組碼,後面執行位元組碼時才會解析剩餘的部分。

evaluatePreparedJavaScript這個方法,主要是調用了HermesRuntime的 runBytecode方法,這里hermesPrep時上一步解析頭部時獲取的BCProviderFromBuffer實例。

runBytecode這個方法比較長,主要做了幾件事情:

這里說明一下,Domain是用於垃圾回收的運行時模塊的代理, Domain被創建時是空的,並跟隨著運行時模塊進行傳播, 在運行時模塊的整個生命周期內都一直存在。在某個Domain下創建的所有函數都會保持著對這個Domain的強引用。當Domain被回收的時候,這個Domain下的所有函數都不能使用。

未完待續。。。

㈡ 深入理解React16之:(一).Fiber架構

React16雖然出了一陣子了。剛出來的時候,粗略看了一遍更新文檔。以為沒什麼大的改動,也聽說項目從react15-16的升級過度可以很平滑,再加上項目改版上線一直比較頻繁,所以一直還用的15.6的版本。
偶然在知乎看到@程墨Morgan大神的live,便抱著好奇心和學習的心態報名了,受益良多。

我理解的Fiber架構:

在我之前的一篇文章有簡單介紹, 閱讀react源碼--記錄:1.1 問題記錄
下面從一個具體實例理解一下,再加上我畫了圖,應該很好理解啦~(圖畫的有點渣)

假如有A,B,C,D組件,層級結構為:

我們知道組件的生命周期為:
掛載階段:

那麼在掛載階段,A,B,C,D的生命周期渲染順序是如何的呢?

以render()函數為分界線。從頂層組件開始,一直往下,直至最底層子組件。然後再往上。

組件update階段同理。

————————
前面是react16以前的組建渲染方式。這就存在一個問題,

好似一個潛水員,當它一頭扎進水裡,就要往最底層一直游,直到找到最底層的組件,然後他再上岸。在這期間, 岸上發生的任何事,都不能對他進行干擾,如果有更重要的事情需要他去做(如用戶操作),也必須得等他上岸

看一下fiber架構 組建的渲染順序

潛水員會每隔一段時間就上岸,看是否有更重要的事情要做。

加入fiber的react將組件更新分為兩個時期

這兩個時期以render為分界,

phase1的生命周期是可以被打斷的,每隔一段時間它會跳出當前渲染進程,去確定是否有其他更重要的任務。此過程,React 在 workingProgressTree (並不是真實的virtualDomTree)上復用 current 上的 Fiber 數據結構來一步地(通過requestIdleCallback)來構建新的 tree,標記處需要更新的節點,放入隊列中。

phase2的生命周期是不可被打斷的,React 將其所有的變更一次性更新到DOM上。

這里最重要的是phase1這是時期所做的事。因此我們需要具體了解phase1的機制。

這樣的話,就和react16版本之前有很大區別了,因為可能會被執行多次,那麼我們最好就得保證phase1的生命周期 每一次執行的結果都是一樣的 ,否則就會有問題,因此, 最好都是純函數。

對了,程墨大神還提到一個問題,飢餓問題,即如果高優先順序的任務一直存在,那麼低優先順序的任務則永遠無法進行,組件永遠無法繼續渲染。這個問題facebook目前好像還沒解決,但以後會解決~

所以,facebook在react16增加fiber結構,其實並不是為了減少組件的渲染時間,事實上也並不會減少,最重要的是現在可以使得一些更高優先順序的任務,如用戶的操作能夠優先執行,提高用戶的體驗,至少用戶不會感覺到卡頓~

㈢ create-react-app build 打包隱藏源碼

在使用 create-react-app 時,打包生產環境 npm run build ,瀏覽器打開後仍然是可以看到源碼的。

在這里以新建一個默認項目為例:

項目根目錄新建 .env.proction 文件,內容如下:

然後重新打包,瀏覽器打開後就看不到源碼啦。

為了探究原理,執行 eject 後,可以看到webpack配置中有這么一段

這里的 process.env.GENERATE_SOURCEMAP 控制著是否捎帶源碼。所以我們可以配置環境變數 GENERATE_SOURCEMAP=false 即可。

當執行 build 時,將按順序優先尋找 .env.proction.local , .env.proction , .env.local , .env 文件來配置環境變數,所以就有了上面的操作。

更多關於環境變數的信息可查看 Adding Custom Environment Variables 。

㈣ 如何用reactjs構建一個完整的前端頁面

用reactjs構建一個完整的前端頁面的步驟:

准備:React 的安裝包,建議去官網下載安裝

1、使用 React 的網頁源碼,結構大致如下:

<!DOCTYPE html><html><head> <script src="../build/react.js"></script> <script src="../build/react-dom.js"></script> <script src="../build/browser.min.js"></script></head><body> <div id="example"></div> <script type="text/babel"> // **用戶代碼 ** </script></body></html>

上面代碼有兩個地方需要注意。

首先,最後一個<script>標簽的type屬性為text/babel。這是因為 React 獨有的 JSX 語法,跟 JavaScript 不兼容。凡是使用 JSX 的地方,都要加上type="text/babel"。

其次,上面代碼一共用了三個庫:react.js、react-dom.js和Browser.js,它們必須首先載入。其中,react.js是 React 的核心庫,react-dom.js是提供與 DOM 相關的功能,Browser.js的作用是將 JSX 語法轉為 JavaScript 語法,這一步很消耗時間,實際上線的時候,應該將它放到伺服器完成。

2、將src子目錄的js文件進行語法轉換,轉碼後的文件全部放在build子目錄。

$ babel src --out-dir build

3、渲染轉換成html節點,以方便操作dom:

ReactDOM.render 是 React 的最基本方法,用於將模板轉為 HTML 語言,並插入指定的 DOM 節點。

這里以插入hello world為例來說明

ReactDOM.render(<h1>Hello, world!</h1>,document.getElementById('example'));

4、運行結果如下:

閱讀全文

與react源碼有多長相關的資料

熱點內容
emerson伺服器怎麼短接啟動 瀏覽:559
工控編程人員工資 瀏覽:397
速成義大利語pdf 瀏覽:250
連續加減乘除法的演算法 瀏覽:652
用mfc編程實現dda演算法 瀏覽:41
linux命令打開應用 瀏覽:146
改造後的程序員 瀏覽:270
數控編程變數 瀏覽:785
江門哪裡有plc編程系統 瀏覽:378
安卓手機如何下載外服b站 瀏覽:700
pythonetree庫 瀏覽:759
數據插值演算法 瀏覽:723
澳大利亞加密貨幣逃稅 瀏覽:484
pdf文檔如何壓縮 瀏覽:329
java單例模式線程安全 瀏覽:646
特種pdf 瀏覽:160
加油什麼app劃算 瀏覽:715
開服要什麼樣的伺服器 瀏覽:33
pdf文件太大怎麼壓縮 瀏覽:29
UK開票顯示文件夾不存在 瀏覽:668