Skip to content

Latest commit

 

History

History
90 lines (56 loc) · 6.77 KB

v3-1-0-such-perf-wow-many-streams.md

File metadata and controls

90 lines (56 loc) · 6.77 KB

v3.1.0:大幅性能提升并支持服务端流式渲染

在生产环境,一种新的 CSS 注入机制意味着更快的客户端渲染。 🔥 服务端流式渲染可以加快首屏渲染时间! 🔥🔥

在生产环境更快的 CSS 注入

这个补丁出来很久了,并有很长的历史。差不多一年半前 (!)Sunil Pai 发现一个新的,却广泛未知的 DOM API: [insertRule](https://twitter.com/threepointone/status/758095395482324992)。它允许人们以惊人的速度将 CSS 从 JavaScript 插入到 DOM 中;唯一的缺点就是样式不能使用浏览器开发者工具进行编辑。

GlenMax 首次构建样式化组件时,他们重点 关注的是开发人员的体验。性能问题对于较小的应用来说是很稀少的,所以他们决定并不使用 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 为这篇文章提供了参考。


掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOS前端后端区块链产品设计人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏