Geo*_*nov 9 node.js express reactjs server-side-rendering ssr
我正在使用react-boilerplate
(使用react-router,sagas,express.js)作为我的React应用程序,并且在它之上我添加了SSR逻辑,这样一旦它收到HTTP请求,它就会根据URL呈现反应组件到字符串并发送HTML字符串返回客户端.
虽然反应呈现在服务器端发生,但它也fetch
通过传真向一些API(基于URL的最多5个端点)发出请求,以便在组件实际呈现组件之前获取组件的数据.
如果我同时向Node服务器发出几个请求,那么一切都很好,但是一旦我模拟了100多个并发请求的加载并且它开始处理它,那么在某些时候它会崩溃而没有任何异常的迹象.
我在尝试调试应用程序时注意到的是,一旦节点服务器开始处理100多个传入请求,它就会同时向API发送请求,但在停止堆叠这些请求之前不会收到任何实际响应.
用于在服务器端呈现的代码:
async function renderHtmlDocument({ store, renderProps, sagasDone, assets, webpackDllNames }) {
// 1st render phase - triggers the sagas
renderAppToString(store, renderProps);
// send signal to sagas that we're done
store.dispatch(END);
// wait for all tasks to finish
await sagasDone();
// capture the state after the first render
const state = store.getState().toJS();
// prepare style sheet to collect generated css
const styleSheet = new ServerStyleSheet();
// 2nd render phase - the sagas triggered in the first phase are resolved by now
const appMarkup = renderAppToString(store, renderProps, styleSheet);
// capture the generated css
const css = styleSheet.getStyleElement();
const doc = renderToStaticMarkup(
<HtmlDocument
appMarkup={appMarkup}
lang={state.language.locale}
state={state}
head={Helmet.rewind()}
assets={assets}
css={css}
webpackDllNames={webpackDllNames}
/>
);
return `<!DOCTYPE html>\n${doc}`;
}
// The code that's executed by express.js for each request
function renderAppToStringAtLocation(url, { webpackDllNames = [], assets, lang }, callback) {
const memHistory = createMemoryHistory(url);
const store = createStore({}, memHistory);
syncHistoryWithStore(memHistory, store);
const routes = createRoutes(store);
const sagasDone = monitorSagas(store);
store.dispatch(changeLocale(lang));
match({ routes, location: url }, (error, redirectLocation, renderProps) => {
if (error) {
callback({ error });
} else if (renderProps) {
renderHtmlDocument({ store, renderProps, sagasDone, assets, webpackDllNames })
.then((html) => {
callback({ html });
})
.catch((e) => callback({ error: e }));
} else {
callback({ error: new Error('Unknown error') });
}
});
}
Run Code Online (Sandbox Code Playgroud)
所以我的假设是,一旦收到太多的HTTP请求就会出现问题,这反过来又会产生更多的API端点请求以呈现反应组件.
我注意到它renderAppToString()
为每个客户端请求后阻塞事件循环300ms ,所以一旦有100个并发请求,它会阻塞它大约10秒钟.我不确定这是不是正常或坏事.
是否值得尝试限制对节点服务器的同时请求?
我找不到有关SSR + Node崩溃主题的更多信息.因此,如果有人在过去经历过类似的问题,我会感谢任何关于在哪里查看以确定问题或可能的解决方案的建议.
对 的调用renderToString()
是同步的,因此它们在运行时会阻塞线程。因此,当您有 100 多个并发请求时,您的队列将极度阻塞,挂起大约 10 秒,这并不奇怪。
编辑:有人指出,React v16 本身支持流式传输,但您需要使用将renderToNodeStream()
HTML 流式传输到客户端的方法。它应该返回与流式传输完全相同的字符串renderToString()
,因此您不必等待完整的 HTML 呈现后才开始向客户端发送数据。
归档时间: |
|
查看次数: |
1146 次 |
最近记录: |