最近react
团队宣布了一个新特性: server components
目前这个feature
仍然是实验性的,目前没有还没有正式的文档。简单来说server components
就是在服务端渲染的组件,但是状态并没有丢失。
这个有点类似SSR
,但是工作原理有一些差异
SSR 的限制
目前,ssr
方案被普遍用于提高首屏渲染速度。在不使用ssr
的情况下,html
文件内容很简单只有一个祖父节点来挂载整个应用
具体如下:
当使用SSR
的时候,客户端的JS
代码会在服务端运行,从而生成需要首屏渲染的DOM
节点,客户端在请求html
文件的时候,由于所有节点都已经生成,所以就提高了首屏渲染的速度
但是这种方式并没有提高可交互的时间,我们需要等待所有的js
都加载完了。所以ssr
通常用来提高首屏渲染速度
0 打包体积
很多情况,JS
包是非常大的。例如在某个场景需要使用moment.js
,而且这个包只会使用一次。
这个时候对应用的性能会造成一定的影响,因为该库只会使用一次,但是浏览器会下载整个包的内容。
基于这个问题,可以用tree-shaking
来过滤一些我们不需要的代码,但是tree-shaking
无法解决某个库只使用了一次的情况,例如上面的情况需要使用moment.js
进行时间格式化。
server components
可用于解决上面提到的问题:
// NoteWithMarkdown.js
import marked from 'marked' // 35.9k
import sanitizeHtml from 'sanitize-html'; // 206k
function NoteWithMarkdown({text}) {
const html = sanitizeHtml(marked(text))
return (/* render */)
}
复制代码
上面代码中,主要做的就是引入两个库用于渲染Markdown
。但是可以看到这个库sanitize-html
非常大。 此外这里只是提供了渲染的markdown
,这个markdown
并不能进行交互。这个时候引入这个库是否是必要的,因为需要消耗大量时间去拉取资源
使用server component
解决上面问题
// NoteWithMarkdown.server.js
import marked from 'marked' // 35.9k
import sanitizeHtml from 'sanitize-html'; // 206k
function NoteWithMarkdown({text}) {
const html = sanitizeHtml(marked(text))
return (/* render */)
}
复制代码
内容其实没有差异,文件名从NoteWithMarkdown.js
变成了NoteWithMarkdown.server.js
。相比与正常的组件渲染,客户端不会去请求整个markdown
库,客户端只会请求渲染后的jsx
内容
因此,这种方式对于客户端来说减少了请求的包体积,把这部分的内容放在了后端来实现
自动代码分割
在以往我们需要使用React.lazy
这串代码来实现code spliting
// PhotoRenderer.js (before 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 <PhotoRenderer {...props} />;
}
}
复制代码
上面这段代码是只有加载对应的组件的时候才会去加载对应的 js 文件从而达到让客户端请求更少的包资源。 server components
引入了自动代码拆分,把客户端所有的正常导入都视为可能的动态组件。同时他也允许开发者选择需要更早加载的组件
// 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 <PhotoRenderer {...props} />;
}
}
复制代码
具有完整的后端权限
本质上server component
就是运行在后端环境中的组件,所有该组件拥有后端的所有权限,例如能够操作数据,文件系统等等
server component
让组件具有上述功能变得更加简单,react 团队针对实现上面功能提供了几个库: react-pg
、react-fetch
、react-fs
例如在下面组件中,我们调用了操作文件的能力
import fs from 'react-fs';
function Note({id}) {
const note = JSON.parse(fs.readFile(`${id}.json`))
return <NoteWithMarkdown note={note}>
}
复制代码
此外还可以使用react
提供的其他库来操作数据库
总结
本期推送整理了初学者可能会用到的Python资料,含有书籍/视频/在线文档和编辑器/源
代码,关于Python
的安装qun:850973621
要想了解更多,可以参考react
团队搞的demo
这个新feature
提供了对于提高页面性能的一些新思路,不得不佩服facebook
的工程师们。 但是看完这个提案以后以后一些小疑问:
- 目前看来这个
server component
适用于状态不频繁的组件 - 社区工程化需要跟进
- 是不是会带来一些安全问题
- 如何拆分客户端组件和
server component
(因为产品功能是不断叠加的,当初设计是否会一直满足后续的需求)