찰나의 시간동안 스타일이 전혀 입혀지지 않은 plain text들이 화면에 표시되는 것이 문제였습니다.
SSR과 코드스프리팅의 특성상 첫 화면을 렌더링하고 동적임포트 한 chunk된 javascript들이 hydrate 되는데요, hydrate 되기 이전에 첫 렌더링 될때도 스타일이 입혀지는 것이 제가 기대했던 결과물이었습니다.
만약 위와 같이 굴러가지 않는다면 User Experience에 정말 안 좋은 영향을 미치게 될 것입니다.
1.babel-plugin-styled-components 추가 및 옵션 설정,
2.babel.config.js 및 webpack.config 관련 파일 수정
3. styled-component 문서 리서치
개발환경 구축 시 webpack 설정에 시행착오가 많았어서 이번 문제 역시 webpack 관련 설정을 잘못해서 일어났겠거니 했는데요, 문제는 서버쪽 코드에 있었습니다.
styled-component 모듈에서 제공하는 ServerStyleSheet 클래스가 있습니다.
해당 클래스의 getStyleTags 함수를 이용해 서버쪽에서 보내는 jsx의 style을 추출하여
index.html에 집어넣어줘야 합니다.
코드로 보여드리는게 더 명확할 것 같은데요,
import { ServerStyleSheet } from 'styled-components';
import { ChunkExtractor } from '@loadable/server';
...
const webExtractor = new ChunkExtractor('./loadable-stats.json');
const jsx = webExtractor.collectChunks(
<StaticRouter location={req.url} context={context}>
<App/>
</StaticRouter>
);
const html = renderToString(sheet.collectStyles(jsx));
const helmet = Helmet.renderStatic();
const styles = sheet.getStyleTags();
res.send(
`
<!DOCTYPE html>
<head>
...
${webExtractor.getStyleTags() + styles}
...
</head>
<body>
<div id="root">${html}</div>
</body>
...
`
)