我一直在考虑如何优化反应服务器端渲染,特别是我的应用程序的瓶颈部分,即同步renterToString调用。因为这是一个阻塞调用,所以具有长函数renderToString调用会导致我的应用程序的吞吐量受到相当大的影响。
我碰巧遇到了一个帖子(这里用谷歌翻译从中文翻译成英文),提出假设使用worker_threads卸载renderToString并使其异步。
我想测试这个功能,似乎有一个阻止因素,因为无法克隆符号,因此无法将符号作为数据传递给工作者:
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,如果是这样,设置渲染器/工作线程的最佳方法是什么。
我很想知道是否有可能为此目的使用worker_threads,如果是这样,设置渲染器/工作线程的最佳方法是什么。
首先,通常,worker_threads适用于CPU密集型工作(如此),其中并行性和共享内存是有用的。
在这种特殊情况下,简单地旋转多个Node.js进程同样有效。
此外,由于ReactDOMServer渲染速度非常慢 - 您几乎总是必须在React(或Vue或Angular)中将服务器端渲染放在缓存之前。因此,这是一种更容易提高性能的方法。
至于你如何在这里使用worker_threads,它失败了,因为你将组件传递给它。相反,我会将路径或组件名称传递给它,并将require
替换为该组件。
或者,您可以自己序列化组件并在另一侧对其进行去病毒化。符号需要唯一性,因此我们不会在Node.js中的工作符之间移动时默认克隆它们。这是你看到的错误。