2022 年,React 團(tuán)隊(duì)在做什么?
上個月中,React 團(tuán)隊(duì)發(fā)了一篇文章 React Labs: What We've Been Working On – June 2022 講了一下最近他們在做的事情,社區(qū)沒有看到中文翻譯,這里簡單解讀下原文,我發(fā)現(xiàn)如果不常浸泡在技術(shù)英文的語境里,有些句子還挺難懂的。
原文鏈接: https://reactjs.org/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022.html
2022 年 6 月 15 日,作者:Andrew Clark、Dan Abramov、Jan Kassens、Joseph Savona、Josh Story、Lauren Tan、Luna Ruan、Mengdi Chen、Rick Hanlon、Robert Zhang、Sathya Gunasekaran、Sebastian Markb?ge和 黃玄 。
React 18已經(jīng)醞釀多年,它為 React 團(tuán)隊(duì)帶來了寶貴的經(jīng)驗(yàn)。它的發(fā)布是多年研究和探索多種途徑的結(jié)果。其中一些路徑是成功的;更多的是導(dǎo)致新見解的死胡同。我們學(xué)到的一個教訓(xùn)是,社區(qū)等待新功能卻沒有深入了解我們正在探索的這些路徑是令人沮喪的。
我們通常在任何時候都有許多項(xiàng)目正在進(jìn)行,從更具實(shí)驗(yàn)性的到明確定義的。展望未來,我們希望開始定期分享更多關(guān)于我們在這些項(xiàng)目中與社區(qū)合作的內(nèi)容。
為了設(shè)定期望,這不是一個有明確時間表的路線圖。其中許多項(xiàng)目正在積極研究中,很難確定具體的發(fā)布日期。根據(jù)我們目前的評估,應(yīng)該不會在當(dāng)前的迭代中發(fā)布。相反,我們想與您分享我們正在積極思考哪些問題,以及我們迄今為止有所認(rèn)識的東西。
解讀:這個開場白,解答了為什么外界總覺得 React 的更新太慢了。不是 React 團(tuán)隊(duì)不干事,是做了很多探索性的工作,有些沒啥結(jié)果,沒有對外說而已,其實(shí)忙的很。按照我的理解,像 React 這種前端基礎(chǔ)設(shè)施,變化太快不見得是一件好事,比如 React-Router 變化快,兼容性也差,當(dāng)然還有 AngularJS。React 的 API 算是延續(xù)性非常好的了,而且相當(dāng)穩(wěn)定。
服務(wù)器組件 Server Components
我們于 2020 年 12 月宣布了 React 服務(wù)器組件 (RSC) 的實(shí)驗(yàn)性方案(https://reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html)。
從那時起,我們一直在 React 18 支持的部分,并致力于根據(jù)實(shí)驗(yàn)反饋進(jìn)行改進(jìn)。
特別是,我們放棄了使用 fork I/O libraries(例如 react-fetch)的想法,而是采用 async/await 模型以獲得更好的兼容性。這在技術(shù)上并不會 block RSC 的發(fā)布,因?yàn)槟€可以使用 routers 來獲取數(shù)據(jù)。另一個變化是我們已經(jīng)不用文件擴(kuò)展名這種方式,轉(zhuǎn)而支持 注釋邊界(annotating boundaries)。
我們正在與 Vercel (一個網(wǎng)站托管平臺)和 Shopify 合作,統(tǒng)一捆綁程序(unify bundler)對 Webpack 和 Vite 中共享語義(shared semantics)的支持。在發(fā)布之前,我們希望確保 RSC 的語義在整個 React 生態(tài)系統(tǒng)中是相同的。這是達(dá)到穩(wěn)定的主要障礙。
解讀:React Server Component 對我來說是比較陌生的,我平時也沒有使用過。看 React 團(tuán)隊(duì)的意思,也不希望我們用這種底層特性,而是讓 Vercel、Shopify、webpack、 Vite 這些周邊生態(tài)的庫來支持,我們直接用這個庫就好了。
資產(chǎn)加載 Asset Loading
目前,腳本、外部樣式、字體和圖像等資產(chǎn)通常是使用外部系統(tǒng)預(yù)加載和加載的。這會使跨新環(huán)境(如流、服務(wù)器組件等)進(jìn)行協(xié)調(diào)變得很棘手。我們正在考慮通過適用于所有 React 環(huán)境的 React API 添加 API 以預(yù)加載和加載去重的外部資產(chǎn)。
我們也在考慮讓這些支持 Suspense,這樣您就可以讓圖像、CSS 和字體在加載之前阻止顯示,但不會阻止流式傳輸和并發(fā)渲染。這有助于避免在視覺效果和布局發(fā)生變化時出現(xiàn)“爆米花” (popcorning)。
解讀:這里解釋下“爆米花”這個詞,大家開發(fā)的時候應(yīng)該經(jīng)常看到一個頁面在數(shù)據(jù)加載完成前后,所占的空間大小是差距是非常大的,這就導(dǎo)致頁面瞬間有個爆炸的效果。尤其是頁面上圖片較多的時候。React 團(tuán)隊(duì)正在開發(fā)一個通用的請求外部資源的 API,來解決這個問題。這塊還是挺期待的,希望能早點(diǎn)體驗(yàn)下。
靜態(tài)服務(wù)器渲染優(yōu)化 Static Server Rendering Optimizations
靜態(tài)站點(diǎn)生成 (SSG) 和增量靜態(tài)重新生成 (ISR) 是獲得可緩存頁面性能的好方法,但我們認(rèn)為我們可以添加功能來提高動態(tài)服務(wù)器端渲染 (SSR) 的性能 - 特別是當(dāng)大多數(shù)但不是全部內(nèi)容是可緩存的。我們正在探索利用編譯和靜態(tài)通道優(yōu)化服務(wù)器渲染的方法。
解讀:服務(wù)端渲染,我了解的不多,這個應(yīng)該是一些性能的優(yōu)化。
React 優(yōu)化編譯器 React Optimizing Compiler
我們在 React Conf 2021 上對 React Forget 進(jìn)行了 預(yù)告useMemo。它是一個編譯器,可以自動生成等價的和useCallback調(diào)用以最小化重新渲染的成本,同時保留 React 的編程模型。
最近,我們完成了對編譯器的重寫,使其更加可靠和強(qiáng)大。這種新架構(gòu)使我們能夠分析和記憶更復(fù)雜的模式,例如使用局部突變,并開辟了許多新的編譯時優(yōu)化機(jī)會,而不僅僅是與緩存掛鉤。
我們還在開發(fā)一個用于探索編譯器許多方面的 Playground 。雖然 Playground 的目標(biāo)是使編譯器的開發(fā)更容易,但我們認(rèn)為它將更容易嘗試并為編譯器的功能建立直覺。它揭示了它如何在后臺工作的各種見解,并在您鍵入時實(shí)時呈現(xiàn)編譯器的輸出。這將在發(fā)布時與編譯器一起提供。
解讀:從去年底,黃玄介紹了 React Forget ,可以通過編譯時優(yōu)化 React 代碼的性能。半年過去了,中間做了很多事情,主要是兩件事,一是對編譯器本身的開發(fā),另一個是 Playground 的開發(fā)。Playground 的意思是游樂場,其實(shí)就是可以在線上修改代碼并看到運(yùn)行結(jié)果的一個工具。
離屏 Offscreen
今天,如果你想隱藏和顯示一個組件,你有兩個選擇。一種是從樹中完全添加或刪除它。這種方法的問題在于,每次卸載時 UI 的狀態(tài)都會丟失,包括存儲在 DOM 中的狀態(tài),例如滾動位置。
另一種選擇是保持組件安裝并使用 CSS 直觀地切換外觀。這會保留 UI 的狀態(tài),但會以性能為代價,因?yàn)?React 必須在收到新更新時不斷渲染隱藏組件及其所有子組件。
Offscreen 引入了第三種選擇:在視覺上隱藏 UI,但降低其內(nèi)容的優(yōu)先級。這個想法在本質(zhì)上類似于 content-visibility CSS 屬性:當(dāng)內(nèi)容被隱藏時,它不需要與 UI 的其余部分保持同步。React 可以推遲渲染工作,直到應(yīng)用程序的其余部分空閑,或者直到內(nèi)容再次可見。
Offscreen 只是一個小技巧,他的目的是解鎖更高級的功能。與 React 的其他并發(fā)特性類似 startTransition,在大多數(shù)情況下,您不會直接與 Offscreen API 交互,而是通過一個完善的框架來實(shí)現(xiàn)以下模式:
即時過渡( Instant transitions ):一些路由框架已經(jīng)預(yù)取數(shù)據(jù)以加速后續(xù)導(dǎo)航,例如懸停在鏈接上時。使用 Offscreen,他們還可以在后臺預(yù)渲染下一個屏幕。
可重用狀態(tài)( Reusable state ):同樣,在路線或選項(xiàng)卡之間導(dǎo)航時,您可以使用 Offscreen 來保留前一個屏幕的狀態(tài),以便您可以切換回來并從中斷處繼續(xù)。
虛擬化列表渲染( Virtualized list rendering ):顯示大型項(xiàng)目列表時,虛擬化列表框架將預(yù)呈現(xiàn)比當(dāng)前可見的更多行。您可以使用 Offscreen 以低于列表中可見項(xiàng)目的優(yōu)先級預(yù)呈現(xiàn)隱藏行。
背景內(nèi)容( Backgrounded content ):我們還在探索一項(xiàng)相關(guān)功能,用于在不隱藏背景的情況下降低內(nèi)容的優(yōu)先級,例如在顯示模式疊加層時。
解讀:這個 Offscreen 可是太有用了,通過這個新的 API ,我們可以控制組件的顯示和隱藏,但不同于 {isShow && }和 <div style={{ display: isShow ? 'block':'none' }} 這兩種方式,他是類似 CSS 的 content-visibility 的屬性,Chromium 85 開始有了 content-visibility 屬性,這可能是對于提升頁面加載性能提升最有效的CSS屬性,content-visibility 讓用戶代理正常情況下跳過元素渲染工作(包括 layout 和 painting ),除非需要的時候進(jìn)行渲染工作。
如果頁面有大量離屏(off-screen)的內(nèi)容,借助 content-visibility 屬性可以跳過離屏內(nèi)容的渲染,加快用戶首屏渲染時間,可以做到減少的頁面可交互的等待時間。React 后面要提供的這個 API,也不希望開發(fā)者直接使用,而是通過使用像 React-Router 這種庫來實(shí)現(xiàn),或許不久以后我們就有類似 Vue 里的 Keep-Alive 的功能可用了。
過渡跟蹤 Transition Tracing
目前,React 有兩個分析工具。Original Profiler顯示了分析會話中所有提交的概覽。對于每次提交,它還顯示所有渲染的組件以及渲染它們所花費(fèi)的時間。我們還有一個在 React 18 中引入的 Timeline Profiler的 beta 版本,它顯示組件何時安排更新以及 React 何時處理這些更新。這兩個分析器都可以幫助開發(fā)人員識別代碼中的性能問題。
我們已經(jīng)意識到,開發(fā)人員并沒有發(fā)現(xiàn)了解單個緩慢提交或脫離上下文的組件是很有用的。了解導(dǎo)致緩慢提交的真正原因會更有用。并且開發(fā)人員希望能夠跟蹤特定的交互(例如按鈕單擊、初始加載或頁面導(dǎo)航)以觀察性能回歸并了解交互緩慢的原因以及如何修復(fù)它。
我們之前嘗試通過創(chuàng)建交互跟蹤 API來解決這個問題,但它存在一些基本的設(shè)計缺陷,降低了跟蹤交互為何緩慢的準(zhǔn)確性,有時會導(dǎo)致交互永無止境。由于這些問題,我們最終刪除了這個 API 。
我們正在開發(fā)一個新版本的交互跟蹤 API(暫時稱為轉(zhuǎn)換跟蹤,因?yàn)樗峭ㄟ^ 啟動的startTransition)來解決這些問題。
解讀:React 的性能分析工具很好用,后面還會新增一種時間線的分析工具,Time Profiler ,來分析并發(fā)更新時的調(diào)度情況。它可以做到當(dāng)發(fā)現(xiàn)某次更新比較緩慢時,可以跟蹤這次交互的完整過程,分析性能瓶頸。
新的 React 文檔 New React Docs
去年,我們宣布了新的 React 文檔網(wǎng)站的 beta 版本。新的學(xué)習(xí)材料首先教授 Hooks,并有新的圖表、插圖以及許多交互式示例和挑戰(zhàn)。之前我們暫停了這項(xiàng)工作,因?yàn)橐獙W⒂?React 18 版本的開發(fā),但現(xiàn)在 React 18 已經(jīng)發(fā)布,我們正在積極努力完成和發(fā)布新文檔。
我們目前正在寫一個關(guān)于 effects 的詳細(xì)部分,因?yàn)槲覀兟犝f對于新的和有經(jīng)驗(yàn)的 React 用戶來說,這都是更具挑戰(zhàn)性的主題之一。Synchronizing with Effects是該系列中的第一篇文章,接下來幾周還會發(fā)布更多內(nèi)容。當(dāng)我們第一次開始編寫有關(guān) effects 的詳細(xì)部分時,我們已經(jīng)意識到可以通過向 React 添加新的原始 API 來簡化許多常見的 effects 模式。我們在 useEvent RFC中分享了一些初步想法。它目前處于早期研究階段,我們?nèi)栽诘@個想法。我們感謝社區(qū)迄今為止對 RFC 的評論,以及對正在進(jìn)行的文檔重寫的反饋和貢獻(xiàn)。我們要特別感謝 Harish Kumar(在一家印度金融科技公司工作的印度小哥)提交并審查了對新網(wǎng)站實(shí)施的許多改進(jìn)。
解讀:新的 React 文章還是有很多變化,他從 2020年10月開始寫的,老文檔的問題是原來的文檔是以 Class Component 為主線的,但是新的 React 設(shè)計思路和發(fā)展已經(jīng)跟之前有了較大的變化,開發(fā)者如果還是按照之前的設(shè)計思想來理解 React ,就不能快速的獲得 React 的真諦,而且目前 Hooks 已經(jīng)成為 React 最重要的部分,但老的文檔里對這部分的介紹優(yōu)先級比較低,所以新的文檔有以下幾個變化:
- 以 HOOKS 為主線,串起所有 React 的相關(guān)知識,尤其是性能優(yōu)化部分。
- 介紹 React 新的設(shè)計模式,思路和哲學(xué)。
- 增強(qiáng)了互動學(xué)習(xí)的部分,開發(fā)者可以在網(wǎng)站上互動的查看示例,和更有意思的 challengesa 幫助你更好的學(xué)習(xí)。
- 暗夜模式,可以切換黑夜和白天,對于熬夜黨很友好。
新的文檔到現(xiàn)在已經(jīng) 1 年多了,很多吐槽一個文檔都要寫這么久,其實(shí)大家細(xì)心看這個文檔,就會發(fā)現(xiàn)是非常考究的,就像一本教科書,極力用通俗的語言把知識點(diǎn)說明白。這也是 Dan 和 Rachel 的強(qiáng)項(xiàng)。