自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

SolidJS硬氣的說:我比React還react

開發(fā) 前端
本文會比較SolidJS與React的異同,闡述他的獨特優(yōu)勢,看完后不知道你會不會和我發(fā)出同樣的感嘆:這簡直比React還react(react譯為響應)。

[[408771]]

大家好,我是卡頌。

最近刷推時,有個老哥經(jīng)常出現(xiàn)在「前端框架」相關推文下。

[[408772]]

一副憨厚的樣貌 

我想:“老哥你哪位?”

一查,原來是個框架作者,作品叫SolidJS[1]

[[408773]]

翻翻框架介紹,這句話成功吸引我的注意:

  • 支持現(xiàn)代前端特性,例如:JSX, Fragments, Context, Portals, Suspense, Streaming SSR, Progressive Hydration, Error Boundaries和Concurrent Rendering

我琢磨您不會是React在逃公主吧?這不能說和React類似,只能說完全一樣吧?

作為傳統(tǒng)中國人,秉承「來都來了」思想,我試用了一天,又看了下源碼,結果發(fā)現(xiàn)這個框架真是個寶藏框架。

本文會比較SolidJS與React的異同,闡述他的獨特優(yōu)勢,看完后不知道你會不會和我發(fā)出同樣的感嘆:

  • 這簡直比React還react(react譯為響應)

相信看完本文后,不僅能認識一個新框架,還能對React有更深的認識。

開整!

初看很相似

讓我們從一個「計數(shù)器」的例子看看與React語法的差異:

  1. import { render } from "solid-js/web"
  2. import { createSignal } from "solid-js"
  3.  
  4. function Counter() { 
  5.   const [count, setCount] = createSignal(0); 
  6.    
  7.   const increment = () => setCount(count() + 1); 
  8.  
  9.   return ( 
  10.     <button type="button" onClick={increment}> 
  11.       {count()} 
  12.     </button> 
  13.   ); 
  14.  
  15. render(() => <Counter />, document.getElementById("app")); 

和React不同的地方:

  • useState改名成createSignal
  • 獲取count狀態(tài)從React中直接使用count變?yōu)橥ㄟ^方法調用,即:count()

難道僅僅是一個類React框架?

別急,讓我們從「編譯時」、「運行時」、「響應原理」三方面來看看。

編譯時大不同

React的編譯時很「薄」,基本只是編譯JSX語法。

而SolidJS則采用了類似Svelte的方案:在編譯時,將狀態(tài)更新編譯為獨立的DOM操作方法。

這樣做有什么好處?主要有兩點。

一定條件下的體積優(yōu)勢

  • 你不需要為你沒使用的代碼付出代價

使用React時,即使沒有用到Hooks,其代碼也會出現(xiàn)在最終編譯后的代碼中。

而在SolidJS中,未使用的功能不會出現(xiàn)在編譯后的代碼中。

舉個例子,上面計時器的例子中,編譯后的代碼有一行是這樣:

  1. delegateEvents(["click"]); 

這行代碼的目的是在document上注冊click事件代理。

如果在計時器中沒有使用onClick,那么編譯后代碼中就不會有這一行。

有熱心網(wǎng)友對比了類似編譯時方案的Svelte與React之間「源代碼」與「編譯后代碼」的體積差異。

其中橫軸代表源代碼體積,縱軸代表編譯后代碼體積,紅色線條代表Svelte,藍色代表React:

可見,在臨界值(業(yè)務源代碼體積達到120kb)之前,編譯時方案有一定體積優(yōu)勢。

由于SolidJS使用JSX描述視圖,比Svelte使用類似Vue的模版語法更靈活,所以在編譯時沒法做到Svelte一樣的極致編譯優(yōu)化,使得其相比Svelte運行時更重一點。

這為他帶來了額外的好處:在真實項目(>120kb)中,SolidJS的代碼體積比Svelte小25%左右。

還真是,因禍得福?

更快的更新速度

我們知道,在React與Vue中存在一層「虛擬DOM」(React中叫Fiber樹)。

每當發(fā)生更新,「虛擬DOM」會進行比較(Diff算法),比較的結果會執(zhí)行不同的DOM操作(增、刪、改)。

而SolidJS與Svelte在發(fā)生更新時,可以直接調用編譯好的DOM操作方法,省去了「虛擬DOM比較」這一步所消耗的時間。

舉個例子,上文的計時器,當點擊后,從觸發(fā)更新到視圖變化的調用棧如下:

觸發(fā)事件,更新狀態(tài),更新視圖,一路調用走到底,清晰明了。

同樣的例子放到React中,調用棧如下:

左中右紅、綠、藍框調用棧分別對應:

  • 處理事件
  • 對比并生成Fiber樹
  • 根據(jù)對比結果執(zhí)行DOM操作

可見,SolidJS的更新路徑比React短很多。

你問憑什么?這還得從其特殊的「響應原理」聊起。

響應原理

假設有個狀態(tài)name,初始值為KaSong。我們希望根據(jù)name渲染一個div。

SolidJS編譯后的代碼類似:

  1. const [name, setName] = createSignal("KaSong"); 
  2.  
  3. const el = document.createElement("div"); 
  4. createEffect(() => el.textContent = name()); 

其中createEffect類似React的useEffect。

由于其回調內依賴了name,所以當name改變后會觸發(fā)createEffect回調,改變el.textContent,造成DOM更新。

類似React的:

  1. useEffect(() => { 
  2.   el.textContent = name
  3. }, [name]) 

首屏渲染結果:

  1. <div>KaSong</div> 

 接下來,觸發(fā)更新:

  1. setName("XiaoMing")  

更新后結果:

  1. <div>XiaoMing</div> 

 為什么更新name后會觸發(fā)createEffect?

這里也沒有什么黑魔法,就是「訂閱發(fā)布」。

createEffect回調依賴name,所以會訂閱name的變化。

由于篇幅有限,實現(xiàn)細節(jié)咱下回細聊。

這里的關鍵在于,SolidJS的狀態(tài)具有「原子性」。

即狀態(tài)互相之間有依賴關系,他們形成局部的依賴圖。當改變一個狀態(tài)后,依賴圖中的其他狀態(tài)也會改變。

createEffect中如果使用了這些依賴,就會訂閱他們的變化。

當狀態(tài)改變后,createEffect回調會執(zhí)行,進而執(zhí)行具體的DOM方法,更新視圖。

「真」?!疙憫礁隆?,指哪打哪,李云龍直呼內行。

有同學會問,React不是這樣么?

那我問你個問題:

為什么Hooks會有調用順序不能變的要求?

為什么useEffect回調會有閉包問題?

答案已經(jīng)呼之欲出了:React只有在這些限制下才能實現(xiàn)「響應式」。

辛勞苦干React

有一個可能反直覺的知識:React并不關心哪個組件觸發(fā)了更新。

在React中,任何一個組件觸發(fā)更新(如調用this.setState),所有組件都會重新走一遍流程。因為需要構建一棵新的Fiber樹。

為了減少無意義的render,React內部有些優(yōu)化策略用來判斷組件是否可以復用上次更新的Fiber節(jié)點(從而跳過render)。

同時,也提供了很多API(比如:useMemo、PureComponent...),讓開發(fā)者告訴他哪些組件可以跳過render。

如果說,SolidJS的更新流程像一個畫家,畫面中哪兒需要更新就往哪兒畫幾筆。

那么React的更新流程像是一個人拿相機拍一張照片,再拿這張照片和上次拍的照片找不同,最后把不同的地方更新了。

總結

今天,我們聊了SolidJS與React的差異,主要體現(xiàn)在三方面:

  • 編譯時
  • 運行時
  • 響應原理

不知道你喜歡這款:沒有Hooks順序限制、沒有useEffect閉包問題、沒有Fiber樹、比React更react的框架么?

如果你問我選哪個?當然,哪個給工資高我用哪個。

考資料

[1]SolidJS:

https://github.com/solidjs/solid

 

責任編輯:姜華 來源: 魔術師卡頌
相關推薦

2022-05-16 08:00:55

ReactReact 18數(shù)組

2023-03-14 07:23:48

ReactJSX語法

2022-07-06 08:30:36

vuereactvdom

2022-03-16 17:01:35

React18并發(fā)的React組件render

2024-05-20 08:49:07

ArkUI鴻蒙應用開發(fā)

2022-12-01 17:17:09

React開發(fā)

2021-05-11 08:48:23

React Hooks前端

2020-11-26 15:30:05

VueReac前端

2021-04-26 06:03:07

Reacterror前端

2019-04-19 11:56:48

框架AI開發(fā)

2023-04-20 10:15:57

React組件Render

2024-03-06 11:14:13

ViteReact微前端

2023-07-30 14:56:42

ReactJavaScript開發(fā)

2023-07-07 08:02:48

TypeScript編譯器文檔

2022-03-27 09:06:04

React類型定義前端

2022-09-05 19:00:53

低代碼平臺React

2016-03-17 09:45:17

react雙向綁定插件

2025-04-07 08:25:01

React復合組件組件模式

2023-02-02 08:41:14

React團隊Vite

2022-09-05 10:01:19

VueReact
點贊
收藏

51CTO技術棧公眾號