v3.1.0:大幅效能提升並支援服務端流式渲染
在生產環境,一種新的 CSS 注入機制意味著更快的客戶端渲染。 ? 服務端流式渲染可以加快首屏渲染時間! ??
在生產環境更快的 CSS 注入
這個補丁出來很久了,並有很長的歷史。差不多一年半前 Sunil Pai 發現一個新的,卻廣泛未知的 DOM API: insertRule。它允許人們以驚人的速度將 CSS 從 JavaScript 插入到 DOM 中;唯一的缺點就是樣式不能使用瀏覽器開發者工具進行編輯。
當 Glen 和 Max 首次構建樣式化元件時,他們重點 關注的是開發人員的體驗。效能問題對於較小的應用來說是很稀少的,所以他們決定並不使用 insertRule
。隨著採用量不斷增加,人們在更大的應用程式中使用樣式元件,在變化頻率較高的元件中樣式注入成為了效能瓶頸。
感謝 Reddit 的一名前端工程師 Ryan Schwers,樣式元件 v3.1.0 現在預設在生產環境使用 insertRule
。
我們將前一個版本 (v3.0.2) 和使用了 insertRule
的新版本的進行了一些對比測試,結果甚至比我們的預期(已經很高的期望)還要高:
測試應用程式的初始掛載時間較之前減少了約 10 倍,重渲染的時間減少了約 20 倍!
請注意,測試結果是壓力測試的結果,並不代表真實的應用程式。雖然你的應用程式掛載時間(可能)不會減少 10 倍,但在我們的一個生產環境下的應用程式中,首次互動時間會下降數百毫秒!
在這些基準測試中,樣式元件與其他主流的 React CSS-in-JS 框架相比,效果如何:
樣式元件與所有其他主流的 React CSS-in-JS 框架相比(淺紅色是:v3.0.2;深紅色是:v3.1.0)
在更細緻測試中,雖然它不是(還不是)最快的 CSS-in-JS 框架,但它只比那些最快的框架慢少許 —— 關鍵的是它不再是瓶頸。現實的使用結果是最鼓舞人心的,我們已迫不及待的等你們都來報告你們的發現了!
服務端流式渲染
在 React v16 中有介紹服務端流式渲染。在 React 還在渲染的時候,它允許應用程式伺服器傳送部分 HTML 作為可用頁面,這有助於 更快的首屏渲染(TTFB),也允許你的 Node 伺服器***更容易***處理後端壓力。
但不能和 CSS-in-JS 相容:傳統上,在 React 完成渲染後,我們會在所有元件樣式的 <head>
中注入一個 <style>
標籤。然而,在流式傳輸的情況下,在所有元件渲染前,<head>
就已傳送到使用者端,所以我們不能再注入樣式。
解決方案是在元件被渲染的時候,插入帶 **<style>**
的 HTML,而不是等到再一次性注入所有元件。由於那樣會在客戶端上造成 ReactDOM 混亂( React 不再對現在的 HTML 負責),所以我們在客戶端再重構前將所有這些 style
標籤重新合併到 <head>
中。
我們已經實現了這一點;你可以在樣式元件中使用服務端流式渲染 以下是使用方法:
import { renderToNodeStream } from 'react-dom/server'
import styled, { ServerStyleSheet } from 'styled-components'
res.write('<!DOCTYPE html><html><head><title>My Title</title></head><body><div id="root">')
const sheet = new ServerStyleSheet()
const jsx = sheet.collectStyles(<App />)
// Interleave the HTML stream with <style> tags
const stream = sheet.interleaveWithNodeStream(
renderToNodeStream(jsx)
)
stream.pipe(res, { end: false })
stream.on('end', () => res.end('</div></body></html>'))
複製程式碼
稍後在客戶端,我們必須呼叫 consolidateStreamedStyles()
API 為 React 的再重構階段做準備:
import ReactDOM from 'react-dom'
import { consolidateStreamedStyles } from 'styled-components'
/* Make sure you call this before ReactDOM.hydrate! */
consolidateStreamedStyles()
ReactDOM.hydrate(<App />, rootElem)
複製程式碼
這裡就是它的所有了!?(檢視流式文件瞭解更多資訊)
v3:無縫更新
好訊息!如果你使用的是 v2 版本(或者甚至是 v1 版本),新版本是向後相容的,應該是無縫升級。這些新版本已加入了許多改進,所有請看一看,我們希望你和你的訪客能夠享受它們!
有關 v3.0.0 和 v3.1.0 發行版更多的資訊,請參閱更新日誌。
緊隨潮流! ?
感謝 Gregory Shehet 提出的 CSS-in-JS benchmarks 為這篇文章提供了參考。
掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。