javascript - 是否可以使用 worker_threads 制作异步 renderToString?

标签 javascript node.js reactjs react-dom

我一直在思考如何优化 React 服务器端渲染,尤其是我应用程序中的瓶颈部分,即同步 renterToString 调用。因为这是一个阻塞调用,所以长函数 renderToString 调用会导致我的应用程序的吞吐量受到相当大的影响。

我碰巧看到一个线程(这里用谷歌翻译从中文翻译成英文)提出了一个假设使用 worker_threads卸载 renderToString 并使其异步。

https://translate.google.com/translate?hl=en&sl=zh-CN&u=https://cnodejs.org/topic/5b2e596557137f22415c4e63&prev=search

我想测试这个功能,似乎有一个障碍,因为 Symbol 不能作为数据传递给工作人员,因为它不能被克隆:

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,如果可以,设置渲染器/工作线程的最佳方法是什么。

最佳答案

I'd love to hear if it is possible to use worker_threads for this purpose, and if so, what the best approach for setting up the renderer/worker threads would be.

首先,一般来说,worker_threads 适用于 CPU 密集型工作(像这样),其中并行性和共享内存很有帮助。

在这种特殊情况下,简单地旋转多个 Node.js 进程同样有效。

此外,由于 ReactDOMServer 渲染速度非常慢 - 在 React(或 Vue 或 Angular)中,您几乎总是必须在服务器端渲染之前放置一个缓存。因此,这是一种更容易提高性能的方法。

至于如何在这里使用 worker_threads,它会失败,因为您将组件传递给它。相反,我会将路由或组件名称传递给它,并让它 require 该组件。

或者,您可以自己序列化组件并在另一端反序列化。符号需要唯一性,因此在 Node.js 中的工作人员之间移动事物时,默认情况下我们不会克隆它们。这是您看到的错误。

关于javascript - 是否可以使用 worker_threads 制作异步 renderToString?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55854890/

相关文章:

javascript - this.name 在 javascript 中返回 undefined

Node.js OpsWorks Layer 控制台日志

node.js - 文件读取器:readAsArrayBuffer() 与 readAsBinaryString()

javascript - React.addons.classSet 不是 React js 的函数

reactjs - Uncaught Error : useNavigate() may be used only in the context of a <Router> component in cypress unit testcases

javascript - 如何将后端(Express JS)提供的静态文件显示到React页面中?

javascript - 在成功安装 sqlite3 后尝试运行代码时如何修复此 "module not found error"?

javascript - 在 Highcharts 中使用带堆叠列的网格图

javascript - 查看:after pseudo class中WebElement是否有具体内容

node.js - ReactJS 路由器问题