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

Angular 之父為什么懟 React ?

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

大家好,我卡頌。

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

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

圖片

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

圖片

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

圖片

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

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

Resumable(恢復)是什么

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

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

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

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

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

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

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

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

圖片

圖來自于qwik文檔

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

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

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

圖片

圖來自于qwik文檔

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

為什么叫Resumable?

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

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

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

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

圖片

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

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

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

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

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

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

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

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

圖片

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

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

與RSC的區(qū)別

同樣是SSR相關技術,React團隊主導的RSC(React Server Component)與Resumable有什么區(qū)別呢?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Mi?ko的想法

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

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

圖片

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

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

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

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

圖片

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

圖片

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

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

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

  • 沒有閉包陷阱
  • 沒有顯式指明依賴的心智負擔

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

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

我想,這也是為什么「Mi?ko」會認為React團隊吃不到葡萄說葡萄酸。

總結(jié)

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

圖片

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

圖片

有意思的是,對于「Dan」的祝福,「Mi?ko」回復道:我們都站在巨人(指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/。

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

2020-09-21 06:10:47

Python lambda匿名函數(shù)

2013-08-12 17:41:42

Angular.jsAngularJS

2014-02-01 21:25:08

Python數(shù)組

2010-11-02 14:31:44

Google Maps

2020-07-08 11:05:52

ReactAnglar前端

2022-07-13 15:23:57

Vue fiberreact前端

2019-04-19 11:56:48

框架AI開發(fā)

2023-02-03 08:36:35

2019-03-01 09:36:25

ReactAngular開發(fā)

2021-03-26 09:00:00

開發(fā)框架React

2022-10-27 20:44:00

開發(fā)前端Angular

2019-10-16 18:00:44

AngularVueReact

2020-01-22 16:53:54

編程語言PythonJava

2020-06-16 16:45:40

Vue前端框架

2023-07-11 08:39:16

React前端

2018-09-28 10:06:21

移動開發(fā)App

2024-02-05 21:48:25

VueReactHooks

2013-12-12 11:20:29

2022-07-01 08:35:50

keyReact前端

2020-03-03 15:31:47

ReactVue前端
點贊
收藏

51CTO技術棧公眾號