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

React 渲染的未來(lái),你想知道嗎?

開發(fā) 前端
在本文中,我們將研究 React 當(dāng)前的渲染模式、它們存在的問(wèn)題,以及 React 18 引入的新模式如何是解決這些問(wèn)題的。

大家好,我是 CUGGZ。

在過(guò)去的幾年中,React 的流行度一直在增加,而且還在加速。React 每周的 npm 下載量超過(guò) 1400 萬(wàn)次 ,React Devtools Chrome 擴(kuò)展有超過(guò) 300 萬(wàn) 的周活躍用戶。

然而,在 React 18 之前,React 中的渲染模式幾乎是相同的。在本文中,我們將研究 React 當(dāng)前的渲染模式、它們存在的問(wèn)題,以及 React 18 引入的新模式如何是解決這些問(wèn)題的。

相關(guān)術(shù)語(yǔ)

在深入研究渲染模式之前,讓我們來(lái)看一下將在這篇文章中使用的一些重要術(shù)語(yǔ):

  • Time To First Byte(TTFB) :發(fā)出頁(yè)面請(qǐng)求到接收到應(yīng)答數(shù)據(jù)第一個(gè)字節(jié)所花費(fèi)的時(shí)間。
  • First Paint(FP) :第一個(gè)像素對(duì)用戶可見的時(shí)間。
  • First Contentful Paint(FCP): 第一條內(nèi)容可見所需的時(shí)間。
  • Largest Contentful Paint(LCP) :加載頁(yè)面主要內(nèi)容所需的時(shí)間。
  • Time To Interactive(TTI): 頁(yè)面變?yōu)榻换ゲ⒖煽宽憫?yīng)用戶事件的時(shí)間。

當(dāng)前的渲染模式

目前,我們?cè)?React 中使用的最常見的模式就是客戶端渲染和服務(wù)端渲染,以及由 Next.js等框架提供的一些高級(jí)形式的服務(wù)端渲染,例如靜態(tài)站點(diǎn)生成(SSG)、增量靜態(tài)生成(ISR)。我們將研究其中這其中的每一個(gè),并深入研究 React 18 引入的新模式。

客戶端渲染(CSR)

在 Next.js 和 Remix 等元框架出現(xiàn)之前,客戶端渲染(主要使用 create-react-app 或其他類似的腳手架)是構(gòu)建 React 應(yīng)用程序的默認(rèn)方式。

使用客戶端渲染,服務(wù)端只需要為包含必要<script>和<link>標(biāo)簽的頁(yè)面提供基本 HTML。一旦相關(guān)的 JavaScript 下載到瀏覽器。 React 渲染樹并生成所有 DOM 節(jié)點(diǎn)。 路由和數(shù)據(jù)獲取的所有邏輯也由客戶端 JavaScript 處理。

為了看看 CSR 是如何工作的,我們來(lái)渲染以下應(yīng)用:

<Layout>
<Navbar />
<Sidebar />
<RightPane>
<Post />
<Comments />
</RightPane>
</Layout>

渲染周期如下:

圖片

CSR渲染周期.gif

這是客戶端渲染的 Network 圖:

圖片

因此,CSR 應(yīng)用接收到應(yīng)答數(shù)據(jù)第一個(gè)字節(jié)很快(TTFB),因?yàn)樗鼈冎饕蕾囉陟o態(tài)資源。 但是,在下載相關(guān) JavaScript 之前,用戶必須盯著空白屏幕。 在那之后,由于大多數(shù)應(yīng)用都需要從 API 獲取數(shù)據(jù)并向用戶顯示相關(guān)數(shù)據(jù),這導(dǎo)致加載頁(yè)面主要內(nèi)容所需的時(shí)間(LCP)很長(zhǎng)。

CSR 的優(yōu)點(diǎn)

  • 由于客戶端渲染架構(gòu)包含靜態(tài)文件,因此可以非常輕松地通過(guò) CDN 提供服務(wù)。
  • 所有渲染都是在客戶端完成的,因此 CSR 允許我們?cè)诓凰⑿抡麄€(gè)頁(yè)面的情況下進(jìn)行導(dǎo)航,從而提供良好的用戶體驗(yàn)。
  • TTFB 時(shí)間很快,因此瀏覽器可以立即開始加載字體、CSS 和 JavaScript。

CSR 的缺點(diǎn)

  • 由于所有內(nèi)容都在客戶端渲染,因此性能受到很大影響,因?yàn)橛脩羰紫刃枰螺d并處理它才能看到頁(yè)面上的內(nèi)容。
  • 客戶端渲染應(yīng)用通常會(huì)在組件掛載時(shí)獲取所需的數(shù)據(jù),這會(huì)導(dǎo)致糟糕的用戶體驗(yàn),因?yàn)樵诔跏柬?yè)面加載時(shí)會(huì)遇到很多 loaders。 此外,如果子組件需要獲取數(shù)據(jù),情況可能會(huì)變得更糟,這樣它們的父組件獲取完所有數(shù)據(jù)后才會(huì)渲染它們,這可能會(huì)導(dǎo)致大量 loaders 和糟糕的 Network Waterfall。
  • SEO 是客戶端渲染應(yīng)用的一個(gè)問(wèn)題,因?yàn)榫W(wǎng)絡(luò)爬蟲可以輕松讀取服務(wù)端渲染的 HTML,但它們可能不會(huì)等待下載完所有 JavaScript 包,執(zhí)行它們并等待客戶端數(shù)據(jù)獲取瀑布流完成 ,這可能會(huì)導(dǎo)致不正確的索引。

服務(wù)端渲染(SSR)

目前,在 React 中服務(wù)端渲染的工作方式如下:

  1. 通過(guò)renderToString 獲取相關(guān)數(shù)據(jù)并在服務(wù)端為頁(yè)面運(yùn)行客戶端 JavaScript,這為我們提供了顯示頁(yè)面所需的所有 HTML。
  2. 將此 HTML 提供給客戶端,從而實(shí)現(xiàn)快速的 First Contentful Paint。
  3. 這時(shí)還沒有完成, 我們?nèi)匀恍枰螺d并執(zhí)行客戶端 JavaScript 以將 JavaScript 邏輯連接到服務(wù)端生成的 HTML 以使頁(yè)面具有交互性(這個(gè)過(guò)程就是“注水”)。

為了更好地理解它是如何工作的,讓我們來(lái)看一下上面例子中使用 SSR 時(shí)的生命周期:

<Layout>
<Navbar />
<Sidebar />
<RightPane>
<Post />
<Comments />
</RightPane>
</Layout>

渲染周期如下:

圖片

SSR渲染周期.gif

這是服務(wù)端渲染的 Network 圖:

圖片

因此,使用 SSR,我們可以獲得良好的 FCP 和 LCP,但 TTFB 會(huì)受到影響,因?yàn)槲覀儽仨氃诜?wù)端獲取數(shù)據(jù),然后將其轉(zhuǎn)換為 HTML 字符串。

現(xiàn)在,你可能會(huì)問(wèn)這和 Next.js 的 SSG/ISR 有啥區(qū)別呢?它們也必須經(jīng)歷上面的過(guò)程。 唯一的區(qū)別是,它們不會(huì)受到 TTFB 時(shí)間較長(zhǎng)的影響。因?yàn)?HTML 要么是在構(gòu)建時(shí)生成的,要么是在請(qǐng)求傳入時(shí)以增量方式生成和緩存的。

圖片

但是,SSG/ISR 更適合公共頁(yè)面。對(duì)于根據(jù)用戶登錄狀態(tài)或?yàn)g覽器上存儲(chǔ)的其他 cookie 更改的頁(yè)面,必須使用 SSR。

SSR 的優(yōu)點(diǎn)

  • 與 CSR 不同,SEO 要好得多,因?yàn)樗?HTML 都是從服務(wù)端預(yù)先生成的,網(wǎng)絡(luò)爬蟲可以毫無(wú)問(wèn)題地爬取它。
  • FCP 和 LCP 非常快。因此,用戶可以很快看到內(nèi)容,而不是像 CSR 應(yīng)用那樣查看空白屏幕。

SSR 的缺點(diǎn)

  • 由于我們?cè)诿看握?qǐng)求時(shí)首先在服務(wù)端渲染頁(yè)面,并且必須等待頁(yè)面的數(shù)據(jù)需求,這可能會(huì)導(dǎo)致 TTFB 速度變慢。這可能是由多種原因?qū)е碌模ㄎ磧?yōu)化的服務(wù)端代碼或者許多并發(fā)的服務(wù)端請(qǐng)求。不過(guò),使用像 Next.js 這樣的框架可以提前生成頁(yè)面并使用 SSG(靜態(tài)站點(diǎn)生成)和 ISR(增量靜態(tài)站點(diǎn)生成)等技術(shù)將它們緩存在服務(wù)端,從而在一定程度上解決了這個(gè)問(wèn)題。
  • 即使初始加載速度很快,用戶仍然需要等待下載頁(yè)面的所有 JavaScript 并對(duì)其進(jìn)行處理,以便頁(yè)面可以重新注水并變得可交互。

新的渲染模式

上面,我們介紹了 React 中當(dāng)前的渲染模式是什么以及它們存在什么問(wèn)題。 總結(jié)一下:

  • 在 CSR 應(yīng)用中,用戶必須下載所有必要的 JavaScript 并執(zhí)行它以查看/與頁(yè)面交互。
  • 在 SSR 應(yīng)用中,我們通過(guò)在服務(wù)端生成 HTML 來(lái)解決了其中的一些問(wèn)題。然而這并不是最優(yōu)的,因?yàn)槭紫任覀儽仨毜却?wù)端獲取所有數(shù)據(jù)并生成 HTML。 然后客戶端必須下載整個(gè)頁(yè)面的 JavaScript。 最后,我們必須執(zhí)行 JavaScript 以連接服務(wù)端生成的 HTML 和 JavaScript 邏輯,以便頁(yè)面可以交互。 所以主要問(wèn)題是我們必須要等待每一步完成,然后才能開始下一步。

React 團(tuán)隊(duì)正在研究一些旨在解決這些問(wèn)題的新模式。

流式 SSR

瀏覽器可以通過(guò) HTTP 流接收 HTML。流式傳輸允許 Web 服務(wù)端通過(guò)單個(gè) HTTP 連接將數(shù)據(jù)發(fā)送到客戶端,該連接可以無(wú)限期保持打開狀態(tài)。因此,我們可以通過(guò)網(wǎng)絡(luò)以多個(gè)塊的形式在瀏覽器上加載數(shù)據(jù),這些數(shù)據(jù)在渲染時(shí)按順序加載。

(1)React 18 之前的流式渲染

流式渲染并不是 React 18 中全新的東西。事實(shí)上,它從 React 16 開始就存在了。React 16 有一個(gè)名為 renderToNodeStream 的方法,與 renderToString 不同,它將前端渲染為瀏覽器的 HTTP 流。

這允許在渲染它的同時(shí)以塊的形式發(fā)送 HTML,從而為用戶提供更快的 TTFB 和 LCP,因?yàn)槌跏?HTML 更快地到達(dá)瀏覽器。

圖片

(2)React 18 中的流式 SSR

React 18 棄用了 renderToNodeStream API,取而代之的是一個(gè)名為 renderToPipeableStream 的新 API,它通過(guò) Suspense 解鎖了一些新功能,允許將應(yīng)用分解為更小的獨(dú)立單元,這些單元可以獨(dú)立完成我們?cè)?SSR 中看到的步驟。這是因?yàn)?Suspense 添加了兩個(gè)主要功能:

  • 服務(wù)端流式渲染。
  • 客戶端選擇性注水。

① 服務(wù)端流式渲染

如上所述,React 18 之前的 SSR 是一種全有或全無(wú)的方法。 首先,需要獲取頁(yè)面所需的數(shù)據(jù),并生成 HTML,然后將其發(fā)送到客戶端。 由于 HTTP 流,情況不再如此。

在 React 18 中想要使用這種方式,可以包裝可能需要較長(zhǎng)時(shí)間才能加載且在 Suspense 中不需要立即顯示在屏幕上的組件。

為了了解它的工作原理,假設(shè) Comments API 很慢,所以我們將 Comments 組件包裝在Suspense 中:

<Layout>
<NavBar />
<Sidebar />
<RightPane>
<Post />
<Suspense fallback={<Spinner />}>
<Comments />
</Suspense>
</RightPane>
</Layout>

這樣,初始 HTML 中就不存在 Comments,返回的只有占位的 Spinner:

<main>
<nav>
<!--NavBar -->
<a href="/">Home</a>
</nav>
<aside>
<!-- Sidebar -->
<a href="/profile">Profile</a>
</aside>
<article>
<!-- Post -->
<p>Hello world</p>
</article>
<section id="comments-spinner">
<!-- Spinner -->
<img width=400 src="spinner.gif" alt="Loading..." />
</section>
</main>

最后,當(dāng)數(shù)據(jù)準(zhǔn)備好用于服務(wù)端的 Comments 時(shí),React 將發(fā)送最少的 HTML 到帶有內(nèi)聯(lián)<script>標(biāo)簽的同一流中,以將 HTML 放在正確的位置:

<div hidden id="comments">
<!-- Comments -->
<p>First comment</p>
<p>Second comment</p>
</div>
<script>
// 簡(jiǎn)化了實(shí)現(xiàn)
document.getElementById('sections-spinner').replaceChildren(
document.getElementById('comments')
);
</script>

因此,這解決了第一個(gè)問(wèn)題,因?yàn)楝F(xiàn)在不需要等待服務(wù)端獲取所有數(shù)據(jù),瀏覽器可以開始渲染應(yīng)用的其余部分,即使某些部分尚未準(zhǔn)備好。

② 客戶端選擇性注水

即使 HTML 被流式傳輸,頁(yè)面也不會(huì)可交互的,除非頁(yè)面的整個(gè) JavaScript 被下載完。這就是選擇性注水的用武之地。

在客戶端渲染期間避免頁(yè)面上出現(xiàn)大型包的一種方法就是通過(guò) React.lazy 進(jìn)行代碼拆分。 它指定了應(yīng)用的某個(gè)特定部分不需要同步加載,并且打包工具會(huì)將其拆分為單獨(dú)的<script>標(biāo)簽。

React.lazy 的限制是它不適用于服務(wù)端渲染。但在 React 18 中,<Suspense> 除了允許流式傳輸 HTML 之外,它還可以為應(yīng)用的其余部分注水。

所以,現(xiàn)在 React.lazy 在服務(wù)端開箱即用。 當(dāng)你將 lazy 組件包裹在 <Suspense> 中時(shí),不僅告訴 React 你希望它被流式傳輸,而且即使包裹在 <Suspense> 中的組件仍在被流式傳輸,也允許其余部分注水。這也解決了我們?cè)趥鹘y(tǒng)服務(wù)端渲染中看到的第二個(gè)問(wèn)題。在開始注水之前,不再需要等待所有 JavaScript 下載完畢。

下面,我們把 Comments 包含在 Suspense 中,并使用新的 Suspense 架構(gòu),來(lái)看看應(yīng)用的生命周期:

<Layout>
<NavBar />
<Sidebar />
<RightPane>
<Post />
<Suspense fallback={<Spinner />}>
<Comments />
</Suspense>
</RightPane>
</Layout>

渲染周期如下:

圖片

流式 SSR 渲染周期.gif

這就產(chǎn)生了像下面這樣的 Network 圖:

圖片

這個(gè)例子想說(shuō)明的是,對(duì)于 Suspense,很多連續(xù)發(fā)生的事情現(xiàn)在可以并行發(fā)生。

這不僅有助于我們?cè)?HTML 被流式傳輸后更快地 TTFB,而且用戶不必等待所有 JavaScript 被下載才能開始與應(yīng)用交互。 除此之外,它還有助于在頁(yè)面開始流式傳輸時(shí)立即加載其他資源(CSS、JavaScript、字體等),有助于并行更多請(qǐng)求。

另外,如果有多個(gè)組件包裹在 Suspense 中并且還沒有在客戶端上注水,但是用戶開始與其中一個(gè)交互,React 將優(yōu)先考慮給該組件注水。

Server components (Alpha)

上面,我們介紹了如何通過(guò)將應(yīng)用分解為更小的單元并分別對(duì)它們進(jìn)行流式處理和選擇性注水來(lái)提高服務(wù)端渲染性能。 但是,如果有一種方法可以完全不需要對(duì)應(yīng)用的某些部分進(jìn)行注水呢?

這就是全新的 Server Components RFC 的用武之地。它旨在補(bǔ)充服務(wù)端渲染,允許擁有僅在服務(wù)端渲染且沒有交互性的組件。

它們的工作方式就是可以使用 .server.js/jsx/ts/tsx 擴(kuò)展創(chuàng)建非交互式服務(wù)端組件,然后它們可以無(wú)縫集成并將 props 傳遞給客戶端組件(使用 .client.js/jsx/ts/tsx 擴(kuò)展),它可以處理頁(yè)面的交互部分。以下是它提供的功能的:

(1)不影響客戶端包

服務(wù)端組件僅在服務(wù)端渲染,不需要注水。它允許我們?cè)诜?wù)端渲染靜態(tài)內(nèi)容,同時(shí)對(duì)客戶端包大小沒有影響。 如果使用的是繁重的庫(kù)并且沒有交互性,這可能特別有用,并且它可以完全渲染在服務(wù)端,而不會(huì)影響客戶端包。 RFC 中的 Notes 預(yù)覽就是一個(gè)很好的例子:

// NoteWithMarkdown.js
// 在 Server Components 之前

import marked from 'marked'; // 35.9K (11.2K gzipped)
import sanitizeHtml from 'sanitize-html'; // 206K (63.3K gzipped)

function NoteWithMarkdown({text}) {
const html = sanitizeHtml(marked(text));
return (/* render */);
}
// NoteWithMarkdown.server.js - Server Component === 包大小為0

import marked from 'marked'; // 包大小為0
import sanitizeHtml from 'sanitize-html'; // 包大小為0

function NoteWithMarkdown({text}) {
const html = sanitizeHtml(marked(text));
return (/* render */);
}

(2)服務(wù)端組件不具有交互性,但可以與客戶端組件組合

由于它們只在服務(wù)端渲染,它們只是接收 props 并渲染視圖的 React 組件。 因此,它們不能像常規(guī)客戶端組件中那樣擁有狀態(tài)、effects 和事件處理程序之類的東西。

盡管它們可以導(dǎo)入具有交互性的客戶端組件,并且在客戶端上渲染時(shí)注水,正如我們?cè)谄胀?SSR 中看到的那樣。 客戶端組件與服務(wù)端組件類似,使用 .client.jsx 或 .client.tsx 后綴定義。

這種可組合性使開發(fā)人員在頁(yè)面上節(jié)省大量的包大小,例如具有大部分靜態(tài)內(nèi)容和很少交互元素的詳情頁(yè)。 例如:

// Post.server.js

import { parseISO, format } from 'date-fns';
import marked from 'marked';
import sanitizeHtml from 'sanitize-html';

import Comments from '../Comments.server.jsx'
// 導(dǎo)入客戶端組件
import AddComment from '../AddComment.client.jsx';

function Post({ content, created_at, title, slug }) {
const html = sanitizeHtml(marked(content));
const formattedDate = format(parseISO(created_at), 'dd/MM/yyyy')

return (
<main>
<h1>{title}</h1>
<span>Posted on {formattedDate}</span>
{content}
<AddComment slug={slug} />
<Comments slug={slug} />
</main>
)
}
// AddComment.client.js

function AddComment({ hasUpvoted, postSlug }) {

const [comment, setComment] = useState('');

function handleCommentChange(event) {
setComment(event.target.value);
}

function handleSubmit() {
// ...
}

return (
<form onSubmit={handleSubmit}>
<textarea name="comment" onChange={handleCommentChange} value={comment}/>
<button type="submit">
Comment
</button>
</form>
)
}

上面的代碼是服務(wù)端組件如何與客戶端組件組合的示例。 讓我們來(lái)分解一下:

  • Post 服務(wù)端組件主要包含靜態(tài)數(shù)據(jù),包括文章標(biāo)題、內(nèi)容和發(fā)布日期。
  • 由于服務(wù)端組件不能有任何交互性,我們導(dǎo)入了一個(gè)名為 AddComment 的客戶端組件,它允許用戶添加評(píng)論。

這里,我們?cè)诜?wù)端組件中導(dǎo)入的所有日期和 markdown 解析庫(kù)都不會(huì)在客戶端下載。我們?cè)诳蛻舳讼螺d的唯一 JavaScript 就是 AddComment 組件。

(3)服務(wù)端組件可以直接訪問(wèn)后端

由于它們僅在服務(wù)端渲染,因此可以使用它們直接從組件訪問(wèn)數(shù)據(jù)庫(kù)和其他僅限后端的數(shù)據(jù)源,如下所示:

// Post.server.js

import { parseISO, format } from 'date-fns';
import marked from 'marked';
import sanitizeHtml from 'sanitize-html';

import db from 'db.server';

// 導(dǎo)入客戶端組件
import Upvote from '../Upvote.client.js';

function Post({ slug }) {
// 直接從數(shù)據(jù)庫(kù)中讀取數(shù)據(jù)
const { content, created_at, title } = db.posts.get(slug);
const html = sanitizeHtml(marked(content));
const formattedDate = format(parseISO(created_at), 'dd/MM/yyyy');

return (
<main>
<h1>{title}</h1>
<span>Posted on {formattedDate}</span>
{content}
<AddComment slug={slug} />
<Comments slug={slug} />
</main>
);
}

現(xiàn)在你可能會(huì)說(shuō),在傳統(tǒng)的服務(wù)端渲染中也可以實(shí)現(xiàn)這一點(diǎn)。 例如,Next.js 可以直接在 getServerSideProps 和 getStaticProps 中訪問(wèn)服務(wù)端數(shù)據(jù)。 沒錯(cuò),但區(qū)別在于,傳統(tǒng)的 SSR 是一種全有或全無(wú)的方法,只能在頂級(jí)頁(yè)面上完成,但服務(wù)端組件可以在每個(gè)組件的基礎(chǔ)上執(zhí)行此操作。

(4)自動(dòng)代碼拆分

代碼拆分是一個(gè)概念,它允許將應(yīng)用分成更小的塊,向客戶端發(fā)送更少的代碼。對(duì)應(yīng)用進(jìn)行代碼拆分的最常見方式就是按路由進(jìn)行拆分。這也是 Next.js 等框架默認(rèn)拆分包的方式。

除了自動(dòng)代碼拆分之外,React 還允許使用 React.lazy API 在運(yùn)行時(shí)延遲加載不同的模塊。 這又是一個(gè)來(lái)自 RFC 的很好的例子,說(shuō)明這可能特別有用:

// PhotoRenderer.js
// 在 Server Components 之前

import React from 'react';
const OldPhotoRenderer = React.lazy(() import('./OldPhotoRenderer.js'));
const NewPhotoRenderer = React.lazy(() import('./NewPhotoRenderer.js'));

function Photo(props) {
if (FeatureFlags.useNewPhotoRenderer) {
return <NewPhotoRenderer {...props} />;
} else {
return <OldPhotoRenderer {...props} />;
}
}

這種技術(shù)通過(guò)在運(yùn)行時(shí)只動(dòng)態(tài)導(dǎo)入需要的組件來(lái)提高性能,但它確實(shí)有一些問(wèn)題。 例如,這種方法會(huì)延遲應(yīng)用開始加載代碼的時(shí)間,從而抵消了加載更少代碼的好處。

正如我們之前在客戶端組件如何與服務(wù)器組件組合中看到的那樣,它們通過(guò)將所有客戶端組件導(dǎo)入視為潛在的代碼拆分點(diǎn),并允許開發(fā)人員選擇要在服務(wù)端更早渲染的內(nèi)容,從而使客戶端能夠更早下載。 下面是 RFC 中使用服務(wù)端組件的相同 PhotoRenderer 示例:

// PhotoRenderer.server.js - Server Component

import React from 'react';
import OldPhotoRenderer from './OldPhotoRenderer.client.js';
import NewPhotoRenderer from './NewPhotoRenderer.client.js';

function Photo(props) {
if (FeatureFlags.useNewPhotoRenderer) {
return <NewPhotoRenderer {...props} />;
} else {
return <OldPhotoRenderer {...props} />;
}
}

服務(wù)端組件可以在保留客戶端狀態(tài)的同時(shí)重新加載:我們可以隨時(shí)從客戶端重新獲取服務(wù)端樹,以從服務(wù)端獲取更新的狀態(tài),而不會(huì)破壞本地客戶端狀態(tài)、焦點(diǎn)甚至正在進(jìn)行的動(dòng)畫。

這是可能的,因?yàn)榻邮盏降?UI 描述是數(shù)據(jù)而不是純 HTML,這允許 React 將數(shù)據(jù)合并到現(xiàn)有組件中,從而使客戶端狀態(tài)不會(huì)被破壞。

(5)服務(wù)端組件與 Suspense 集成

服務(wù)器組件可以通過(guò) <Suspense> 逐步流式傳輸,正如在上面中看到的那樣,這允許我們?cè)诘却?yè)面剩余部分加載時(shí)創(chuàng)建加載狀態(tài)并快速顯示重要內(nèi)容。

接下來(lái)看看上面的例子在使用 React 服務(wù)端組件時(shí)是什么樣的。 這次 Sidebar 和 Post 是服務(wù)端組件,而 Navbar 和 Comments 是客戶端組件。 我們也將 Post 包裹在 Suspense 中。

<Layout>
<NavBar />
<SidebarServerComponent />
<RightPane>
<Suspense fallback={<Spinner />}>
<PostServerComponent />
</Suspense>
<Suspense fallback={<Spinner />}>
<Comments />
</Suspense>
</RightPane>
</Layout>

渲染周期如下:

圖片

Server components  渲染周期.gif

它的 Network 圖與使用 Suspense 的流式渲染非常相似,但 JavaScript 更少。因此,服務(wù)端組件甚至是解決我們一開始的問(wèn)題的進(jìn)一步措施,它不僅可以下載更少的 JavaScript,而且還顯著改善了開發(fā)者體驗(yàn)。

React 團(tuán)隊(duì)還在 RFC 常見問(wèn)題解答中提到,他們?cè)?Facebook 的單個(gè)頁(yè)面上對(duì)少數(shù)用戶進(jìn)行了實(shí)驗(yàn),產(chǎn)品代碼大小減少了約 30%。

什么時(shí)候可以開始使用這些功能?

目前,服務(wù)端組件仍處于 alpha 階段,而具有新 Suspense 架構(gòu)的流式 SSR 所需的用于數(shù)據(jù)獲取的 Suspense 還沒有正式發(fā)布,將在 React 18 的小更新中發(fā)布。

相關(guān)演示

在這里查看 React 團(tuán)隊(duì)和 Next.js 團(tuán)隊(duì)的演示:

  • 使用新的 Suspense 架構(gòu)演示流式傳輸 SSR:https://codesandbox.io/s/kind-sammet-j56ro。
  • 服務(wù)端組件演示:https://github.com/reactjs/server-components-demo。
  • Next.js 服務(wù)端組件演示:https://github.com/vercel/next-react-server-components。
責(zé)任編輯:姜華 來(lái)源: 前端充電寶
相關(guān)推薦

2024-04-22 08:02:34

kafka消息隊(duì)列高可用

2022-12-21 08:04:19

socket圖解網(wǎng)絡(luò)

2022-07-20 11:32:09

人工智能人工智能算法

2018-03-16 10:59:28

筆記本屏幕電腦

2015-04-13 16:13:11

2017-09-01 14:18:50

前端React組件

2024-09-27 09:53:22

Rust標(biāo)準(zhǔn)庫(kù)優(yōu)化

2011-07-14 16:21:34

WPS Online

2025-06-16 09:36:18

2017-08-08 16:35:26

Python爆紅原因

2024-12-11 08:19:34

2019-10-29 15:28:40

Refs組件前端

2011-08-12 09:39:14

Office 15

2018-10-22 11:25:01

Photoshop工具移動(dòng)

2024-03-26 10:17:49

開發(fā)緩存key

2024-06-11 09:02:30

2020-09-14 09:39:41

華為/鴻蒙

2021-06-17 13:40:47

區(qū)塊鏈比特幣公有鏈

2023-09-11 08:51:23

LinkedList雙向鏈表線程

2024-03-18 08:56:12

ReactVuejQuery
點(diǎn)贊
收藏

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

主站蜘蛛池模板: 亚洲欧美日韩在线一区二区 | 欧美色欧美亚洲另类七区 | 国产9 9在线 | 中文 | 一区二区三区视频 | 国产精品久久久久久久久久久久 | 第一区在线观看免费国语入口 | 亚洲一区av| 成人午夜免费网站 | 国产精品美女久久久久aⅴ国产馆 | 国产精品一区视频 | av网站免费看 | 久久se精品一区精品二区 | 天堂网中文字幕在线观看 | 色偷偷人人澡人人爽人人模 | 色伊人网 | 日本不卡一区 | 亚洲国产精品久久人人爱 | 国产精品视频在线播放 | 日韩一区二区三区在线看 | 蜜桃精品视频在线 | 色秀网站 | 在线观看国产视频 | 精品久久电影 | 亚洲欧美一区二区三区国产精品 | 亚洲视频免费观看 | 在线观看亚洲专区 | 国产色网站 | 久久综合一区 | 成人国产一区二区三区精品麻豆 | 亚洲区视频 | 观看av | 亚洲精品一区二区三区 | 三级黄色大片网站 | 欧一区二区| 国产ts人妖系列高潮 | 天天爽网站 | 国产一区久久久 | 色视频网站 | 岛国二区 | 亚洲精品不卡 | 自拍 亚洲 欧美 老师 丝袜 |