如何Redis缓存Apollo-getMarkupFromTree?

时间:2019-04-10 11:14:03

标签: reactjs redis stream apollo serverside-rendering

使用Nodejs / express服务器,我设法缓存整个响应,而不仅仅是apollo getMarkupFromTree。 getMarkupFromTree需要很长时间才能完成。我只需要缓存这部分,因为我不想缓存购物车。

内容部分(请参见下面的代码)仅在Redis缓存getMarkupFromTree时呈现/流 footer nav 。 StartHtml,middleHtml,endHtml会完全呈现。

缓存整个网站效果很好。尝试将等待添加到不同的部分,并且所有这些都无需更改。 redisCache.get(...)返回预期结果。 ApolloClientExtract返回预期的结果。

const renderer = async (req, res) => {
  const redisCache = new RedisCache();

  const helmetContext = {};
  // APOLLO
  const client = apolloClient(req);

  // REDUX
  const store = await reduxPersist(req);
  const context = {};

  // STYLED COMPONENTS
  const sheet = new ServerStyleSheet();

  // APPLICATION
  const Root = () => (
    <AppTree
      client={client}
      store={store}
      helmetContext={helmetContext}
      req={req}
      context={context}
      extractor={extractor}
    />
  );

  // REDUX
  const finalState = store.getState();

  // @loadable/server
  extractor.collectChunks(<Root />);
  extractor.getLinkTags();

  // WRITE START HTML
  res.write(startHtml({ extractor }));
  // res.flushHeaders();

  let apolloClientExtract = {};
  let redisApolloExtract = '';
  try {
    redisApolloExtract = await redisCache.get('teuberkohlhoff apolloExtract');
  } catch (err) {
    console.log('Error', err);
  }

  // let markupFromTree = '';
  if (redisApolloExtract) {
    // ADDING getMarkupFromTree here leads to the expected result
    renderToString(<Root />); // needed for @loadable/server
    apolloClientExtract = redisApolloExtract;
  } else {
    // Apollo
    await getMarkupFromTree({
      renderFunction: renderToString,
      tree: <Root />
    });
    apolloClientExtract = serialize(client.extract());
    redisCache.set('teuberkohlhoff apolloExtract', apolloClientExtract);
  }

  // WRITE MIDDLE HTML
  res.write(middleHtml({ helmetContext, scripts }));
  // res.flushHeaders();

  const content = sheet.collectStyles(<Root />); // HERE I think something is wrong

  // PIPE CONTENT
  const stream = sheet.interleaveWithNodeStream(renderToNodeStream(content));
  stream.pipe(
    res,
    { end: false }
  );

  const reduxFinalState = serialize(finalState);

  // WRITE END HTML
  stream.on('end', () => res.end(endHtml({ extractor, apolloClientExtract, reduxFinalState })));
};

getMarkupFromTree如何工作,返回什么?

缓存getMarkupFromTree的正确方法是什么?

0 个答案:

没有答案