偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Angular 之父為什么懟 React ?

開(kāi)發(fā) 前端
Resumable的概念源于一次思路的轉(zhuǎn)變。雖然主流前端框架都支持SSR,但不管是React、Vue還是Angular,他們都是CSR(客戶(hù)端渲染)優(yōu)先。

大家好,我卡頌。

前幾天,Angular之父「Mi?ko Hevery」和「Dan」在推上發(fā)生了一段有趣的對(duì)話(huà),對(duì)話(huà)背景大概是:

  1. 傳統(tǒng)SSR(服務(wù)端渲染)場(chǎng)景下使用的技術(shù)叫Hydration,「Mi?ko」曾向「Dan」演示了一個(gè)新技術(shù)概念 —— Resumable。
  2. 「Dan」認(rèn)為這項(xiàng)技術(shù)不可行。

圖片

  1. 「Mi?ko」在Qwik框架中實(shí)現(xiàn)了Resumable。
  2. 「Dan」表示在React中我們之所以沒(méi)有考慮Resumable,并不是因?yàn)榭蚣懿缓媒尤?,而是因?yàn)镽esumable并不是更優(yōu)解。

圖片

  1. 「Mi?ko」表示這是吃不到葡萄說(shuō)葡萄酸。

圖片

那么,Resumable到底是什么技術(shù)?他和React在推進(jìn)的RSC(React Server Component)有什么區(qū)別?「Mi?ko」為什么會(huì)作出上述言論?

讓我們通過(guò)本文了解一下。

Resumable(恢復(fù))是什么

Resumable的概念源于一次思路的轉(zhuǎn)變。

雖然主流前端框架都支持SSR,但不管是React、Vue還是Angular,他們都是CSR(客戶(hù)端渲染)優(yōu)先。

在這些框架中,SSR是在CSR的基礎(chǔ)上附加的新功能。

正是由于傳統(tǒng)前端框架都是「CSR優(yōu)先」的產(chǎn)物,才導(dǎo)致一些常見(jiàn)SSR問(wèn)題,比如:

  • 首屏渲染時(shí),頁(yè)面短時(shí)間無(wú)法響應(yīng)交互,因?yàn)榇藭r(shí)框架還未hydrate完成。
  • 即使僅有部分內(nèi)容需要交互,但整個(gè)頁(yè)面還得全量hydrate。

這些問(wèn)題拉低了SSR場(chǎng)景下的FCP[1](First Contentful Paint)與TTI[2]指標(biāo)(time to interactive)。

下圖展示了SSR場(chǎng)景下hydrate的流程,包括4個(gè)步驟,只有在整個(gè)流程完成后應(yīng)用才能響應(yīng)交互:

  1. 下載HTML。
  2. 下載所有JS文件。
  3. 解析、執(zhí)行JS文件(主要是框架及其依賴(lài),還有業(yè)務(wù)邏輯代碼)。
  4. 綁定事件(即hydrate操作)。

圖片

圖來(lái)自于qwik文檔

在某些應(yīng)用場(chǎng)景(比如電商、博客)下,除了第一步,其他步驟可能不是必須的。

比如,對(duì)于一個(gè)電商商品詳情頁(yè),除了展示商品所需的HTML外,其他都不是首屏渲染所必須的。

這就是Qwik框架中Resumable技術(shù)的設(shè)計(jì)理念 —— HTML優(yōu)先,JS按需下載:

圖片

圖來(lái)自于qwik文檔

要實(shí)現(xiàn)Resumable,需要拋棄傳統(tǒng)框架以CSR為基礎(chǔ)(用JS生成HTML為主)的思路,轉(zhuǎn)而以SSR為基礎(chǔ)(以服務(wù)端生成HTML為主),再在此基礎(chǔ)上附加CSR功能。

為什么叫Resumable?

Resumable的理念概括起來(lái)就是「按需下載、執(zhí)行JS」。

所有JS代碼的下載及運(yùn)行會(huì)延遲到需要的時(shí)候再執(zhí)行。在如下官方示例1[3]中,會(huì)渲染一個(gè)按鈕,「按鈕的點(diǎn)擊回調(diào)對(duì)應(yīng)代碼」不會(huì)在首屏渲染時(shí)下載:

export default component$(() => {
  return (
    <button
      onClick$={() => {
        // 這部分代碼不會(huì)在首屏渲染時(shí)下載
        console.log('click');
        const div = document.querySelector('#container')! as HTMLElement;
        div.style.background = 'yellow';
      }}
    >
      執(zhí)行
    </button>
  );
});

只有在點(diǎn)擊按鈕時(shí),對(duì)應(yīng)代碼才會(huì)被下載并執(zhí)行:

圖片

這就使得首屏渲染時(shí)需要下載及執(zhí)行的JS文件大大減少,提高了FCP及TTI指標(biāo)。

實(shí)際上,如果以Chrome lighthouse的評(píng)分作為評(píng)判依據(jù),其他框架確實(shí)都難以望Qwik的項(xiàng)背

這項(xiàng)技術(shù)之所以叫Resumable(恢復(fù)),是因?yàn)樗c傳統(tǒng)Hydration技術(shù)在首屏渲染時(shí)客戶(hù)端邏輯的區(qū)別。

傳統(tǒng)Hydration技術(shù)在首屏渲染時(shí),客戶(hù)端(比如瀏覽器)會(huì)全量執(zhí)行框架代碼與業(yè)務(wù)邏輯代碼,并在此過(guò)程中完成:

  • 框架組件對(duì)應(yīng)的樹(shù)狀數(shù)據(jù)結(jié)構(gòu)初始化(比如在React中叫Fiber樹(shù),在Vue中叫VNode樹(shù))
  • 組件內(nèi)狀態(tài)初始化
  • 事件綁定

而以上過(guò)程在Resumable技術(shù)中是發(fā)生在服務(wù)端的。比如,對(duì)于上述按鈕的例子,點(diǎn)擊回調(diào)對(duì)應(yīng)的下述代碼會(huì)在服務(wù)端生成HTML時(shí)完成序列化:

onClick$={() => {
  console.log('click');
  const div = document.querySelector('#container')! as HTMLElement;
  div.style.background = 'yellow';
}}

序列化后的數(shù)據(jù)會(huì)以HTML屬性的形式存在:

圖片

當(dāng)點(diǎn)擊事件發(fā)生后,框架的前端部分會(huì)根據(jù)HTML屬性(示例中的on:click屬性)向后端請(qǐng)求具體的JS代碼(即點(diǎn)擊回調(diào)對(duì)應(yīng)的代碼)并執(zhí)行。

一句話(huà)總結(jié)就是 —— 在Resumable技術(shù)中,一切以SSR為主,部分在SSR時(shí)未完成的操作(比如交互邏輯對(duì)應(yīng)代碼)會(huì)在需要觸發(fā)時(shí)(比如交互發(fā)生時(shí))再「恢復(fù)」執(zhí)行,所以這一技術(shù)叫Resumable(恢復(fù))。

與RSC的區(qū)別

同樣是SSR相關(guān)技術(shù),React團(tuán)隊(duì)主導(dǎo)的RSC(React Server Component)與Resumable有什么區(qū)別呢?

在講解他們的區(qū)別前,我們要先了解一個(gè)背景知識(shí):React是「CSR優(yōu)先」的框架,而且他已經(jīng)出現(xiàn)很多年了(13年問(wèn)世)。

雖然這些年出現(xiàn)了很多優(yōu)秀的框架技術(shù)(比如Signal、AOT),但React一直堅(jiān)持這套「重客戶(hù)端運(yùn)行時(shí)」技術(shù)架構(gòu)。

在發(fā)布React Hooks后,React團(tuán)隊(duì)逐漸將重心轉(zhuǎn)移向服務(wù)端。由于其技術(shù)架構(gòu)偏向客戶(hù)端運(yùn)行時(shí),所以將React直接改造為「SSR優(yōu)先」顯然不現(xiàn)實(shí)。

為此,React團(tuán)隊(duì)的策略是 —— 提供SSR能力,再讓其他「SSR優(yōu)先」框架接入(主要是Next.js)。

所以,Resumable與RSC的主要區(qū)別其實(shí)體現(xiàn)在框架底層實(shí)現(xiàn)層面。

區(qū)別1:序列化方式

最大的區(qū)別體現(xiàn)在「序列化數(shù)據(jù)」方式的不同。

在Resumable技術(shù)下,SSR時(shí)會(huì)將大量數(shù)據(jù)序列化為HTML屬性或注釋?zhuān)热纾?/p>

  • DOM與Qwik組件的關(guān)系。
  • 狀態(tài)(是的,狀態(tài)都會(huì)在服務(wù)端序列化為HTML屬性,再在客戶(hù)端恢復(fù))。
  • 代碼邏輯(比如上述示例中的點(diǎn)擊回調(diào)邏輯)。

服務(wù)端完成了大部分工作,客戶(hù)端需要做的僅僅是按需反序列化數(shù)據(jù),并執(zhí)行對(duì)應(yīng)邏輯。

在RSC中,服務(wù)端組件會(huì)被序列化為一種自定義JSX協(xié)議,并被流式傳輸。之所以沒(méi)有被序列化為HTML字符串(就像Resumable那樣),是因?yàn)閿?shù)據(jù)被反序列化后并不直接是HTML,而是JSX,JSX經(jīng)由React處理后才會(huì)映射到HTML,這么做能保持服務(wù)端組件的子孫客戶(hù)端組件不丟失狀態(tài)。

比如如下RSC,根據(jù)id props從數(shù)據(jù)庫(kù)取不同數(shù)據(jù),再將數(shù)據(jù)傳遞給子組件(客戶(hù)端組件):

function ServerCpn({id}) {
  const data = db.get(id);
  return <ClicentCpn {...data} />;
}

當(dāng)id props變化后,ClicentCpn組件內(nèi)的狀態(tài)并不會(huì)丟失。就是因?yàn)榉?wù)端傳輸來(lái)的ServerCpn是一種自定義JSX協(xié)議,而不是HTML字符串。

區(qū)別2:變化監(jiān)測(cè)方式

通過(guò)區(qū)別1可以發(fā)現(xiàn),RSC中序列化的數(shù)據(jù)描述的是組件級(jí)別的內(nèi)容(JSX描述組件)。

而Resumable中序列化的數(shù)據(jù)粒度更細(xì)(比如描述點(diǎn)擊事件的回調(diào)邏輯,或者某個(gè)狀態(tài))。之所以會(huì)有這種區(qū)別,是因?yàn)閮蓚€(gè)框架采用不同的變化監(jiān)測(cè)方式。

當(dāng)狀態(tài)變化后,React需要遍歷完整的組件樹(shù)才能計(jì)算出「狀態(tài)變化產(chǎn)生的影響」。所以序列化數(shù)據(jù)只需要描述組件級(jí)別的內(nèi)容就行。

而Qwik(實(shí)現(xiàn)Resumable技術(shù)的框架)使用Signal監(jiān)聽(tīng)狀態(tài)變化,這使得他能精確定位「狀態(tài)變化所產(chǎn)生的影響」,即精確定位狀態(tài)變化需要反序列化哪些數(shù)據(jù)。

區(qū)別3:后續(xù)的發(fā)展

由于React是重客戶(hù)端運(yùn)行時(shí)的框架,所以雖然RSC是SSR技術(shù),他的后續(xù)發(fā)展還是會(huì)與重客戶(hù)端運(yùn)行時(shí)的技術(shù)綁定(比如Suspense、Selective Hydration)。

Resumable是重服務(wù)端技術(shù),所以后續(xù)發(fā)展應(yīng)該會(huì)圍繞服務(wù)端展開(kāi),比如:

  • 支持更多類(lèi)型數(shù)據(jù)的序列化(當(dāng)前不支持class序列化)。
  • 支持序列化數(shù)據(jù)的流式傳輸。
  • 支持對(duì)「是否序列化數(shù)據(jù)」更精細(xì)的控制。

Mi?ko的想法

了解了這些技術(shù)細(xì)節(jié),讓我們回到開(kāi)篇,為什么「Mi?ko」會(huì)懟React呢?

實(shí)際上,這并不是「Mi?ko」第一次對(duì)React發(fā)表看法。之前「Mi?ko」就曾表示:即使React Forget Compiler成功問(wèn)世,他也沒(méi)法解決props下鉆場(chǎng)景下的性能問(wèn)題,并以此論證Signal技術(shù)的優(yōu)越性:

圖片

在這里我們不比較技術(shù)優(yōu)劣。只是說(shuō)單純用腳投票,除了React外,確實(shí)有很多框架都使用了Signal相關(guān)技術(shù),比如:

  • Vue
  • Preact
  • Qwik
  • 新版Angular
  • Solid.js

在「Mi?ko」看來(lái),React團(tuán)隊(duì)之所以不采用更優(yōu)秀的技術(shù),是由于一旦采用新技術(shù),就沒(méi)法完美的向后兼容,勢(shì)必造成社區(qū)生態(tài)的割裂。

作為Angular的作者,「Mi?ko」對(duì)這種后果再清楚不過(guò)了。

圖片

但是,React團(tuán)隊(duì)卻認(rèn)為 —— React之所以沒(méi)有采用這些技術(shù),是因?yàn)樽陨淼募夹g(shù)路線更優(yōu)秀。

圖片

這里「Dan」舉出的例子是Hooks和RSC。

本文已經(jīng)做過(guò)RSC與Resumable的比較。在筆者看來(lái),兩者是不同技術(shù)路線(CSR優(yōu)先還是SSR優(yōu)先)下的優(yōu)秀代表。

但就Hooks而言,筆者認(rèn)為Hooks優(yōu)秀在其理念,而不是實(shí)現(xiàn)。同樣基于Hooks理念實(shí)現(xiàn)的Vue Composition API在使用體驗(yàn)上比React Hooks更佳,比如:

  • 沒(méi)有閉包陷阱
  • 沒(méi)有顯式指明依賴(lài)的心智負(fù)擔(dān)

之所以同樣理念的不同實(shí)現(xiàn)使用體驗(yàn)不同,完全是由于底層的技術(shù)實(shí)現(xiàn)區(qū)別造成的(這里指「底層變化監(jiān)測(cè)方式」)。

所以,從這個(gè)角度想,筆者并不贊同React團(tuán)隊(duì)的說(shuō)法。

我想,這也是為什么「Mi?ko」會(huì)認(rèn)為React團(tuán)隊(duì)吃不到葡萄說(shuō)葡萄酸。

總結(jié)

大佬們的討論總是理性、互相尊重且克制的?!窶i?ko」在后續(xù)也表示了自己對(duì)React的誤判。

圖片

在Qwik v1.0發(fā)布時(shí),「Dan」第一時(shí)間送上祝福。

圖片

有意思的是,對(duì)于「Dan」的祝福,「Mi?ko」回復(fù)道:我們都站在巨人(指React)的肩膀上。

圖片

這是不是說(shuō),我還是比巨人要高呢?

參考資料

[1]FCP:https://web.dev/fcp/。

[2]TTI:https://developer.chrome.com/docs/lighthouse/performance/interactive/。

[3]官方示例1:https://qwik.builder.io/examples/introduction/runtime-less/。

責(zé)任編輯:姜華 來(lái)源: 魔術(shù)師卡頌
相關(guān)推薦

2020-09-21 06:10:47

Python lambda匿名函數(shù)

2013-08-12 17:41:42

Angular.jsAngularJS

2025-09-11 10:01:45

2014-02-01 21:25:08

Python數(shù)組

2010-11-02 14:31:44

Google Maps

2020-07-08 11:05:52

ReactAnglar前端

2019-04-19 11:56:48

框架AI開(kāi)發(fā)

2022-07-13 15:23:57

Vue fiberreact前端

2025-09-03 01:55:00

2023-02-03 08:36:35

2019-03-01 09:36:25

ReactAngular開(kāi)發(fā)

2021-03-26 09:00:00

開(kāi)發(fā)框架React

2020-01-22 16:53:54

編程語(yǔ)言PythonJava

2022-10-27 20:44:00

開(kāi)發(fā)前端Angular

2019-10-16 18:00:44

AngularVueReact

2020-06-16 16:45:40

Vue前端框架

2024-02-05 21:48:25

VueReactHooks

2023-07-11 08:39:16

React前端

2018-09-28 10:06:21

移動(dòng)開(kāi)發(fā)App

2013-12-12 11:20:29

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)