我一直在考虑如何优化React Server端渲染,尤其是我应用程序的瓶颈部分,这是同步的RenterToString调用。因为这是一个阻塞调用,所以具有长函数renderToString的调用会导致我的应用程序的吞吐量遭受相当大的损失。
我碰巧遇到了一个线程(这里是用Google翻译将其从中文翻译成英文),提出了一个假设,可以使用worker_threads卸载renderToString并使它异步。
我想测试此功能,并且似乎存在一个阻止程序,因为无法克隆Symbol不能将其作为数据传递给worker:
DataCloneError: Symbol(react.element) could not be cloned.
以下是用于设置工作线程/服务器呈现逻辑的示例代码:
// asyncRenderer.js
const { Worker, isMainThread, parentPort, workerData } = require('worker_threads');
if (isMainThread) {
module.exports = async function asyncRenderToString(component) {
return new Promise((resolve, reject) => {
const worker = new Worker(__filename, {
workerData: component,
});
worker.on('message', resolve);
worker.on('error', reject);
worker.on('exit', (code) => {
if (code !== 0) {
reject(new Error(`Worker stopped with exit code ${code}`));
}
});
});
};
} else {
const { renderToString } = require('react-dom/server');
const HTML = renderToString(workerData);
parentPort.postMessage(HTML);
}
// server.jsx
const asyncRenderer = require('./asyncRenderer');
...
const html = await renderToString(<App/>);
// Return the html
我很想知道是否可以为此使用worker_threads,如果可以,那么设置渲染器/工作器线程的最佳方法是什么。
答案 0 :(得分:2)
我很想知道是否可以为此使用worker_threads,如果可以,那么设置渲染器/工作器线程的最佳方法是什么。
首先,一般来说worker_threads适用于CPU密集型工作(像这样),在这些工作中并行性和共享内存是有帮助的。
在这种情况下,简单地旋转多个Node.js进程同样有效。
此外,由于ReactDOMServer渲染速度非常慢-您几乎总是必须在React(或Vue或Angular)的服务器端渲染之前放置一个缓存。因此,这是一种提高性能的简便方法。
关于在这里如何使用worker_threads,它失败了,因为您将组件传递给了它。取而代之的是,我将路由或组件名称传递给它,并使其require
成为该组件。
或者,您可以自己序列化组件,然后在另一端进行反序列化。符号需要唯一性,因此在Node.js中的工作人员之间移动内容时,默认情况下不会克隆它们。这是您看到的错误。