Я думал о том, как оптимизировать реагирующий серверный рендеринг, особенно ту часть моего приложения, которая является узким местом, а именно синхронный вызов renterToString. Поскольку это блокирующий вызов, длительные вызовы функции renderToString приводят к значительному снижению пропускной способности моего приложения.
Я наткнулся на поток (здесь он переведен с китайского на английский с google translate), который выдвигает гипотетическую гипотезу использования worker_threads для разгрузки renderToString и его асинхронности.
https://translate.google.com/translate?hl=en&sl=zh-CN&u=https://cnodejs.org/topic/5b2e596557137f22415c4e63&prev=search
Я хотел проверить эту функциональность, и похоже, что существует блокировщик, в котором символ не может быть передан в качестве данных работнику, поскольку его нельзя клонировать:
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, и если да, то каким будет наилучший подход к настройке потоков рендерера / рабочего.