99精品伊人亚洲|最近国产中文炮友|九草在线视频支援|AV网站大全最新|美女黄片免费观看|国产精品资源视频|精彩无码视频一区|91大神在线后入|伊人终合在线播放|久草综合久久中文

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線(xiàn)課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

前端框架的Signals有何優(yōu)勢(shì)?

OSC開(kāi)源社區(qū) ? 來(lái)源:OSCHINA 社區(qū) ? 2023-10-11 11:04 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

作者|jump--jump

Signals 在目前前端框架的選型中遙遙領(lǐng)先!

國(guó)慶節(jié)前最后一周在 Code Review 新同學(xué)的 React 代碼,發(fā)現(xiàn)他想通過(guò) memo 和 useCallback 只渲染被修改的子組件部分。事實(shí)上該功能在 React 中是難以做到的。因?yàn)?React 狀態(tài)變化后,會(huì)重新執(zhí)行 render 函數(shù)。也就是在組件中調(diào)用 setState 之后,整個(gè)函數(shù)將會(huì)重新執(zhí)行一次。

React 本身做不到。但是基于 Signals 的框架卻不會(huì)這樣,它通過(guò)自動(dòng)狀態(tài)綁定和依賴(lài)跟蹤使得當(dāng)前狀態(tài)變化后僅僅只會(huì)重新執(zhí)行用到該狀態(tài)代碼塊。

個(gè)人當(dāng)時(shí)沒(méi)有過(guò)多的解釋這個(gè)問(wèn)題,只是匆匆解釋了一下 React 的渲染機(jī)制。在這里做一個(gè) Signals 的梳理。

優(yōu)勢(shì)

對(duì)比 React,基于 Signals 的框架狀態(tài)響應(yīng)粒度非常細(xì)。這里以 Solid 為例:

import { createSignal, onCleanup } from "solid-js";

const CountingComponent = () => {
  // 創(chuàng)建一個(gè) signal
  const [count, setCount] = createSignal(0);

  // 創(chuàng)建一個(gè) signal
  const [count2] = createSignal(666);

  // 每一秒遞增 1
  const interval = setInterval(() => {
    setCount((c) => c + 1);
  }, 1000);

  // 組件銷(xiāo)毀時(shí)清除定時(shí)器
  onCleanup(() => clearInterval(interval));

  return (
    
count: {count()} {console.log("count is", count())}
count2: {count2()} {console.log("count2 is", count2())}
); };
上面這段代碼在 count 單獨(dú)變化時(shí),只會(huì)打印 count,壓根不會(huì)打印 count2 數(shù)據(jù)。 控制臺(tái)打印如下所示:

count is 0

count2 is 666

count is 1

count is 2

...

從打印結(jié)果來(lái)看,Solid 只會(huì)在最開(kāi)始執(zhí)行一次渲染函數(shù),后續(xù)僅僅只會(huì)渲染更改過(guò)的 DOM 節(jié)點(diǎn)。這在 React 中是不可能做到的,React 是基于視圖驅(qū)動(dòng)的,狀態(tài)改變會(huì)重新執(zhí)行整個(gè)渲染函數(shù),并且 React 完全無(wú)法識(shí)別狀態(tài)是如何被使用的,開(kāi)發(fā)者甚至可以通過(guò)下面的代碼來(lái)實(shí)現(xiàn) React 的重新渲染。

const [, forceRender] = useReducer((s) => s + 1, 0);

除了更新粒度細(xì)之外,使用 Signals 的框架心智模型也更加簡(jiǎn)單。其中最大的特點(diǎn)是:開(kāi)發(fā)者完全不必在意狀態(tài)在哪定義,也不在意對(duì)應(yīng)狀態(tài)在哪渲染。如下所示:

import { createSignal } from "solid-js";

// 把狀態(tài)從過(guò)組件中提取出來(lái)
const [count, setCount] = createSignal(0);
const [count2] = createSignal(666);

setInterval(() => {
  setCount((c) => c + 1);
}, 1000);

// 子組件依然可以使用 count 函數(shù)
const SubCountingComponent = () => {
  return 
{count()}
; }; const CountingComponent = () => { return (
count: {count()} {console.log("count is", count())}
count2: {count2()} {console.log("count2 is", count2())}
); };

上述代碼依然可以正常運(yùn)行。因?yàn)樗腔跔顟B(tài)驅(qū)動(dòng)的。開(kāi)發(fā)者在組件內(nèi)使用 Signal 是本地狀態(tài),在組件外定義 Signal 就是全局狀態(tài)。

Signals 本身不是那么有價(jià)值,但結(jié)合派生狀態(tài)以及副作用就不一樣了。代碼如下所示:

import {
  createSignal,
  onCleanup,
  createMemo,
  createEffect,
  onMount,
} from "solid-js";

const [count, setCount] = createSignal(0);

setInterval(() => {
  setCount((c) => c + 1);
}, 1000);

// 計(jì)算緩存
const doubleCount = createMemo(() => count() * 2);

// 基于當(dāng)前緩存
const quadrupleCount = createMemo(() => doubleCount() * 2);

// 副作用
createEffect(() => {
  // 在 count 變化時(shí)重新執(zhí)行 fetch
  fetch(`/api/${count()}`);
});

const CountingComponent = () => {
  // 掛載組件時(shí)執(zhí)行
  onMount(() => {
    console.log("start");
  });

  // 銷(xiāo)毀組件時(shí)執(zhí)行
  onCleanup(() => {
    console.log("end");
  });

  return (
    
Count value is {count()}
doubleCount value is {doubleCount()}
quadrupleCount value is {quadrupleCount()}
); };
從上述代碼可以看到,派生狀態(tài)和副作用都不需要像 React 一樣填寫(xiě)依賴(lài)項(xiàng),同時(shí)也將副作用與生命周期分開(kāi) (代碼更好閱讀)。

實(shí)現(xiàn)機(jī)制

細(xì)粒度,高性能,同時(shí)還沒(méi)有什么限制。不愧被譽(yù)為前端框架的未來(lái)。那么它究竟是如何實(shí)現(xiàn)的呢? 本質(zhì)上,Signals 是一個(gè)在訪(fǎng)問(wèn)時(shí)跟蹤依賴(lài)、在變更時(shí)觸發(fā)副作用的值容器。 這種基于響應(yīng)性基礎(chǔ)類(lèi)型的范式在前端領(lǐng)域并不是一個(gè)特別新的概念:它可以追溯到十多年前的 Knockout observables 和 Meteor Tracker 等實(shí)現(xiàn)。Vue 的選項(xiàng)式 API 也是同樣的原則,只不過(guò)將基礎(chǔ)類(lèi)型這部分隱藏在了對(duì)象屬性背后。依靠這種范式,Vue2 基本不需要優(yōu)化就有非常不錯(cuò)的性能。

依賴(lài)收集

React useState 返回當(dāng)前狀態(tài)和設(shè)置值函數(shù),而 Solid 的 createSignal 返回兩個(gè)函數(shù)。即:

type useState = (initial: any) => [state, setter];

type createSignal = (initial: any) => [getter, setter];
為什么 createSignal 要傳遞 getter 方法而不是直接傳遞對(duì)應(yīng)的 state 值呢?這是因?yàn)榭蚣転榱司邆漤憫?yīng)能力,Signal 必須要收集誰(shuí)對(duì)它的值感興趣。僅僅傳遞狀態(tài)是無(wú)法提供 Signal 任何信息的。而 getter 方法不但返回對(duì)應(yīng)的數(shù)值,同時(shí)執(zhí)行時(shí)創(chuàng)建一個(gè)訂閱,以便收集所有依賴(lài)信息。

模版編譯

要保證 Signals 框架的高性能,就不得不結(jié)合模版編譯實(shí)現(xiàn)該功能,框架開(kāi)發(fā)者通過(guò)模版編譯實(shí)現(xiàn)動(dòng)靜分離,配合依賴(lài)收集,就可以做到狀態(tài)變量變化時(shí)點(diǎn)對(duì)點(diǎn)的 DOM 更新。所以目前主流的 Signals 框架沒(méi)有使用虛擬 DOM。而基于虛擬 DOM 的 Vue 目前依靠編譯器來(lái)實(shí)現(xiàn)類(lèi)似的優(yōu)化。 下面我們先看看 Solid 的模版編譯:

const CountingComponent = () => {
  const [count, setCount] = createSignal(0);
  const interval = setInterval(() => {
    setCount((c) => c + 1);
  }, 1000);

  onCleanup(() => clearInterval(interval));
  return 
Count value is {count()}
; };

對(duì)應(yīng)編譯后的的組件代碼。

const _tmpl$ = /*#__PURE__*/ _$template(`
Count value is `); const CountingComponent = () => { const [count, setCount] = createSignal(0); const interval = setInterval(() => { setCount((c) => c + 1); }, 1000); onCleanup(() => clearInterval(interval)); return (() => { const _el$ = _tmpl$(), _el$2 = _el$.firstChild; _$insert(_el$, count, null); return _el$; })(); };

執(zhí)行 _tmpl$ 函數(shù),獲取對(duì)應(yīng)組件的靜態(tài)模版

提取組件中的 count 函數(shù),通過(guò) _$insert 將狀態(tài)函數(shù)和對(duì)應(yīng)模版位置進(jìn)行綁定

調(diào)用 setCount 函數(shù)更新時(shí),比對(duì)一下對(duì)應(yīng)的 count,然后修改對(duì)應(yīng)的 _el$ 對(duì)應(yīng)數(shù)據(jù)

其他

大家可以看一看使用 Signals 的主流框架:

Vue Ref

Angular Signals

Preact Signals

Solid Signals

Qwik Signals

Svelte 5 (即將推出)

不過(guò)目前來(lái)看 React 團(tuán)隊(duì)可能不會(huì)使用 Signals。

Signals 性能很好,但不是編寫(xiě) UI 代碼的好方式

計(jì)劃通過(guò)編譯器來(lái)提升性能

可能會(huì)添加類(lèi)似 Signals 的原語(yǔ)

PREACT 作者編寫(xiě)了@preact/signals-react 為 React 提供了 Signals。不過(guò)個(gè)人不建議在生產(chǎn)環(huán)境使用。

編輯:黃飛

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • API
    API
    +關(guān)注

    關(guān)注

    2

    文章

    1620

    瀏覽量

    64059
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4381

    瀏覽量

    64897
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4900

    瀏覽量

    70756
  • Signals
    +關(guān)注

    關(guān)注

    0

    文章

    2

    瀏覽量

    1143

原文標(biāo)題:聊聊前端框架的未來(lái)Signals

文章出處:【微信號(hào):OSC開(kāi)源社區(qū),微信公眾號(hào):OSC開(kāi)源社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    賽靈思基于FPGA平臺(tái)的PFM電機(jī)控制方案優(yōu)勢(shì)?

    PFM為什么是一種比PWM更好的電機(jī)控制算法?賽靈思基于PFM算法的電機(jī)控制方案到底優(yōu)勢(shì)?詳見(jiàn)本文分析...
    發(fā)表于 07-23 10:18 ?2466次閱讀

    ARM-based相比ARM cortex優(yōu)勢(shì)?

    你看好ARM-based架構(gòu)嗎 相比ARM cortex優(yōu)勢(shì) ARM其他還有什么架構(gòu)啊,感覺(jué)曝光的好少。。
    發(fā)表于 04-24 06:55

    主流web前端技術(shù)框架

    BootstrapBootstrap是一款很受歡迎的前端框架,基于HTML、CSS、JavaScript設(shè)計(jì)的,簡(jiǎn)單靈活,使得Web開(kāi)發(fā)更加快捷,Bootstrap中包含了豐富的Web組件和13個(gè)jquery插件
    發(fā)表于 03-28 16:56

    labview操作者框架有什么優(yōu)勢(shì)

    labview操作者框架采用的面向?qū)ο缶幊?,到?b class='flag-5'>有什么優(yōu)勢(shì)呢?目前不知道這個(gè)框架優(yōu)勢(shì)
    發(fā)表于 05-21 14:45

    請(qǐng)問(wèn)如何看待svelte這個(gè)前端框架?

    如何看待 svelte 這個(gè)前端框架?看了下。十分精簡(jiǎn)。思路也很獨(dú)特。
    發(fā)表于 06-01 05:55

    微內(nèi)核什么時(shí)候發(fā)布?微內(nèi)核優(yōu)勢(shì)?

    想了解下微內(nèi)核什么時(shí)候發(fā)布的?微內(nèi)核優(yōu)勢(shì)?
    發(fā)表于 10-10 10:09

    學(xué)好前端必須要弄懂的框架

    間過(guò)度框架,對(duì)“新手”極其友好,學(xué)習(xí)了jQuery框架的思想,再開(kāi)始學(xué)習(xí)Vue 和 React就簡(jiǎn)單了。為了讓更多同學(xué)能輕松學(xué)會(huì)前端框架,信盈達(dá)小編給大家分享一個(gè)jQuery
    發(fā)表于 06-30 16:57

    學(xué)好前端必須要弄懂的框架!

    間過(guò)度框架,對(duì)“新手”極其友好,學(xué)習(xí)了jQuery框架的思想,再開(kāi)始學(xué)習(xí)Vue 和 React就簡(jiǎn)單了。為了讓更多同學(xué)能輕松學(xué)會(huì)前端框架,信盈達(dá)小編給大家分享一個(gè)jQuery
    發(fā)表于 07-06 11:18

    網(wǎng)表仿真與RTL仿真相比優(yōu)勢(shì)

    網(wǎng)表仿真與RTL仿真相比優(yōu)勢(shì)?“線(xiàn)與”邏輯是什么?
    發(fā)表于 11-04 06:23

    目前流行的前端開(kāi)發(fā)框架是什么

    00. 目錄文章目錄00. 目錄01. 概述02. 跨多平臺(tái)開(kāi)發(fā)框架03. 移動(dòng)端混合開(kāi)發(fā)框架04. 前端開(kāi)發(fā)框架05. 附錄01. 概述作為前端
    發(fā)表于 11-08 06:52

    Android框架里的相關(guān)默認(rèn)權(quán)限操作作用

    Android框架里的相關(guān)默認(rèn)權(quán)限操作作用?
    發(fā)表于 02-17 06:23

    前端開(kāi)發(fā)】一篇文章概括目前流行的前端開(kāi)發(fā)框架

    00. 目錄文章目錄00. 目錄01. 概述02. 跨多平臺(tái)開(kāi)發(fā)框架03. 移動(dòng)端混合開(kāi)發(fā)框架04. 前端開(kāi)發(fā)框架05. 附錄01. 概述作為前端
    發(fā)表于 11-03 11:36 ?25次下載
    【<b class='flag-5'>前端</b>開(kāi)發(fā)】一篇文章概括目前流行的<b class='flag-5'>前端</b>開(kāi)發(fā)<b class='flag-5'>框架</b>

    騰訊開(kāi)源的前端框架介紹

    ? 今天推薦兩個(gè)騰訊開(kāi)源的前端框架,分別是 wujie(無(wú)界)和 Omi。 wujie(無(wú)界) 無(wú)界微前端是一款基于 Web Components + iframe 微前端
    的頭像 發(fā)表于 06-17 14:44 ?2737次閱讀
    騰訊開(kāi)源的<b class='flag-5'>前端</b><b class='flag-5'>框架</b>介紹

    四線(xiàn)制測(cè)電阻優(yōu)勢(shì)?與二線(xiàn)制測(cè)電阻區(qū)別?

    前言四線(xiàn)測(cè)試法被認(rèn)為是目前為止最好的消除引線(xiàn)電阻引入誤差(或?qū)⑵浣抵磷钚〉模┑臏y(cè)試方案。那么,四線(xiàn)測(cè)試法優(yōu)勢(shì)?它的原理是什么?與二線(xiàn)制測(cè)電阻
    的頭像 發(fā)表于 05-12 09:43 ?2.5w次閱讀
    四線(xiàn)制測(cè)電阻<b class='flag-5'>有</b><b class='flag-5'>何</b><b class='flag-5'>優(yōu)勢(shì)</b>?與二線(xiàn)制測(cè)電阻<b class='flag-5'>有</b><b class='flag-5'>何</b>區(qū)別?

    熱門(mén)前端框架:引領(lǐng)現(xiàn)代 Web 開(kāi)發(fā)的潮流

    在當(dāng)今快速發(fā)展的前端開(kāi)發(fā)領(lǐng)域,熱門(mén)前端框架如 React、Vue 和 Angular 等,成為了開(kāi)發(fā)者構(gòu)建高效、高性能 Web 應(yīng)用的得力工具。它們各自具有獨(dú)特的特點(diǎn)和優(yōu)勢(shì),引領(lǐng)著現(xiàn)代
    的頭像 發(fā)表于 01-22 10:08 ?467次閱讀