成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Angular 之父為什么懟 React ?

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

大家好,我卡頌。

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

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

圖片

  1. 「Mi?ko」在Qwik框架中實現(xiàn)了Resumable。
  2. 「Dan」表示在React中我們之所以沒有考慮Resumable,并不是因為框架不好接入,而是因為Resumable并不是更優(yōu)解。

圖片

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

圖片

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

讓我們通過本文了解一下。

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

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

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

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

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

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

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

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

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

圖片

圖來自于qwik文檔

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

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

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

圖片

圖來自于qwik文檔

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

為什么叫Resumable?

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

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

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

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

圖片

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

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

這項技術(shù)之所以叫Resumable(恢復(fù)),是因為它與傳統(tǒng)Hydration技術(shù)在首屏渲染時客戶端邏輯的區(qū)別。

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

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

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

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

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

圖片

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

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

與RSC的區(qū)別

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

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

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

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

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

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

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

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

在Resumable技術(shù)下,SSR時會將大量數(shù)據(jù)序列化為HTML屬性或注釋,比如:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Mi?ko的想法

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

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

圖片

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

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

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

作為Angular的作者,「Mi?ko」對這種后果再清楚不過了。

圖片

但是,React團(tuán)隊卻認(rèn)為 —— React之所以沒有采用這些技術(shù),是因為自身的技術(shù)路線更優(yōu)秀。

圖片

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

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

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

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

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

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

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

總結(jié)

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

圖片

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

圖片

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

圖片

這是不是說,我還是比巨人要高呢?

參考資料

[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é)任編輯:姜華 來源: 魔術(shù)師卡頌
相關(guān)推薦

2020-09-21 06:10:47

Python lambda匿名函數(shù)

2013-08-12 17:41:42

Angular.jsAngularJS

2010-11-02 14:31:44

Google Maps

2014-02-01 21:25:08

Python數(shù)組

2020-07-08 11:05:52

ReactAnglar前端

2022-07-13 15:23:57

Vue fiberreact前端

2023-02-03 08:36:35

2019-04-19 11:56:48

框架AI開發(fā)

2019-03-01 09:36:25

ReactAngular開發(fā)

2021-03-26 09:00:00

開發(fā)框架React

2020-01-22 16:53:54

編程語言PythonJava

2019-10-16 18:00:44

AngularVueReact

2022-10-27 20:44:00

開發(fā)前端Angular

2020-06-16 16:45:40

Vue前端框架

2024-02-05 21:48:25

VueReactHooks

2018-09-28 10:06:21

移動開發(fā)App

2023-07-11 08:39:16

React前端

2013-12-12 11:20:29

2022-07-05 11:28:03

AI軟件

2020-03-03 15:31:47

ReactVue前端
點贊
收藏

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

主站蜘蛛池模板: 色狠狠桃花综合 | 99久久久国产精品 | 91国自视频 | 欧美视频一区二区三区 | 日韩成人影院 | 欧美free性| 第四色狠狠| 久久综合影院 | 国产美女高潮 | 亚洲国产一区二区视频 | 亚洲第一天堂 | 午夜在线 | 免费一区 | 欧美精品欧美精品系列 | 日韩精品一区二区三区中文在线 | av性色全交蜜桃成熟时 | 国产电影一区二区三区爱妃记 | 欧美片网站免费 | 欧美成人a∨高清免费观看 欧美日韩中 | 在线观看视频h | 成人免费视频在线观看 | 91在线精品一区二区 | 久久日韩粉嫩一区二区三区 | 国产精品视频久久 | 成人性视频在线播放 | 欧美精品欧美精品系列 | 久草新在线 | 国产良家自拍 | 男女爱爱网站 | 亚洲成人免费视频在线 | 成人黄页在线观看 | 免费在线观看成年人视频 | 日本超碰| 91玖玖| 欧美一级黄色片免费观看 | 欧美色性 | 国产成人99久久亚洲综合精品 | 天堂一区二区三区四区 | 精品一级| 国产精品免费在线 | 久久久久免费精品国产小说色大师 |