[譯] styled-components v3.1.0

原文鏈接:https://medium.com/styled-components/v3-1-0-such-perf-wow-many-streams-c45c434dbd03

image

V3.1.0: 帶來巨大的性能提升和流式服務(wù)器端渲染支持

一種新的 CSS 注入機制意味著在生產(chǎn)環(huán)境中更快的客戶端渲染,同時流式服務(wù)器端渲染使得首字節(jié)時間(TTFB)更快。

在生產(chǎn)環(huán)境中更快捷的CSS注入

CSS注入早就不是什么新鮮事了。早在一年半以前,Sunil Pai就發(fā)現(xiàn)了一個鮮為人知的DOM API: insertRule。它使我們能用JS的方式把CSS快速注入到DOM當中。唯一的缺點是這些樣式不能在瀏覽器的開發(fā)者工具中編輯。

當 Glen 和 Max 第一次寫出styled-components的時候,他們完全是從開發(fā)者的體驗出發(fā)的。對于小型應(yīng)用來說性能問題還不明顯,所以他們決定不再使用insertRule。但是當越來越多的人開始使用,并且使用在大型應(yīng)用程序中時,樣式注入就成了瓶頸,特別對于一些高度動態(tài)的案例來說。

多虧了 Reddit 的前端工程師 Ryan Schwers,styled-components 3.1.0版本在生產(chǎn)環(huán)境中默認使用insertRule。

我們將該版本與之前的版本(3.0.2)做了些對比,結(jié)果遠超預(yù)期:

image

Mount的時間減少了將近10倍,而重新渲染的時間減少了將近20倍!

注意,這樣的比較是基于壓力測試,不一定適用于真實應(yīng)用??赡苣愕膽?yīng)用渲染速度不一定能提升10倍,但是在我們的一個應(yīng)用中,首次渲染時間減少了好幾百毫秒。

下圖是styled-components與其它一些主流的React CSS-in-JS框架的比較(淡紅色是3.0.2版本,深紅色是3.1.0版本):

image

盡管目前styled-components還不是最快的,但比最快的也慢不了多少,至少之前的瓶頸也已經(jīng)不復(fù)存在了。這樣的結(jié)果實在是鼓舞人心,我們也非常希望得到各位用戶的反饋。

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

流式服務(wù)器端渲染的概念實在React V16中引進的。它允許React還在渲染的時候,服務(wù)端仍然能發(fā)送HTML,這使得首字節(jié)時間更快,并且Node服務(wù)器能更容易的處理背壓(Back-pressure)。

這與 CSS-in-JS 不太搭:
通常,我們在React完成渲染后,將所有組件的樣式放在<style>標簽中,然后插入到<head>里面。而在流式情況下,在任何組件都沒被渲染的時候,<head>已經(jīng)發(fā)送給用戶了,這時候我們就無法插入任何東西了。

解決方案就是在渲染組件的時候,把HTML和樣式混在一起,而不是等到最后,一次性的插入所有的組件。但是這樣會使HTML和style標簽都糅雜在一起,所以我們最后還是要在重注入(rehydration)之前把所有的style都合并到head里面。

我們已經(jīng)實現(xiàn)了這一點,你現(xiàn)在可以同時使用流式服務(wù)器端渲染和styled-components。就像這樣:

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>'))

然后在客戶端,我們必須調(diào)用consolidateStreamedStyles()API來為React的重注入(rehydration)做準備:

import ReactDOM from 'react-dom'
import { consolidateStreamedStyles } from 'styled-components'
/* Make sure you call this before ReactDOM.hydrate! */
consolidateStreamedStyles()
ReactDOM.hydrate(<App />, rootElem)

好消息!

如果你使用的是v2或者甚至v1,不用擔心,新版本完全是向后兼容的。并且你也可以無縫的升級至新版本。新版本中有很多的更新,希望你和你的用戶能夠喜歡。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,711評論 19 139
  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標簽?zāi)J的外補...
    _Yfling閱讀 14,204評論 1 92
  • 折磨 我身上的傷口又多了一道,長長的,也紅紅的。而原來的那道,已經(jīng)被縫好。 每次我醒來,...
    光明與歌閱讀 179評論 0 0
  • (一) “我在地府呆了千八百年,頭一次見著比你臉皮還厚的,你開不開心?!?黑無常聽了這話將手中的奪命鎖又握了緊些,...
    顧知涯閱讀 856評論 6 6
  • 今天去幼兒園把交了兒子上學(xué)所需的資料和手續(xù),把書包和被褥領(lǐng)了回來,每次進去都會覺得兒子離我遠了一點,有時候想在家自...
    小四吉閱讀 202評論 0 0

友情鏈接更多精彩內(nèi)容