거의 알고리즘 일기장

nextjs 사용시 FOUC 문제 해결 (html에 style이 먹지않아 깜빡이는 문제) with antd, styled-component 본문

web

nextjs 사용시 FOUC 문제 해결 (html에 style이 먹지않아 깜빡이는 문제) with antd, styled-component

건우권 2023. 2. 15. 19:57

nextjs를 처음 사용해보는 권모씨 평소와 같이 antd, styled-component를 사용하던중 문제를 발견하는데...

아씨.. 왜이리 스타일이 늦게 먹는것 같지?.. 나는 react처럼 똑같이 세팅하고 그라는디.. ㅠ

 

이유가 무엇일까??...

이유는 바로 nextjs의 랜더링 방식에 있다!! 

nextjs는 (default인 ssg 기준으로) HTML을 빌드 타임에 각 페이지별로 생성하고 해당 페이지로 요청이 올 경우 이미 생성된 HTML 문서를 먼저 보낸다.

 

이때, 미리 빌드타임에 생성된 html 문서에 스타일링이 먹히지 않아서 FOUC(flash of unstyled content) 문제가 생기는것이다.

(styled-component는 css-in-js 방식이므로 js파일에 있다. antd도 5.x 이후부터는 css in js 방식으로 스타일링을 한다.)

 

자 이제 이유는 알았다. 그렇다면 어떻게 해결해야할까??

 

해결은 저 위의 이유에 대해 알았다면 간단한 일이다!

빌드타임에 만들어놓은 html에 스타일에 대한 데이터도 같이 보내주면 될일!

 

근디.. 어떻게함?..


다행히도 next에는 server에서 랜더링을 custom 할수있는 방법을 제공한다!

https://nextjs.org/docs/advanced-features/custom-document

 

Advanced Features: Custom `Document` | Next.js

Extend the default document markup added by Next.js.

nextjs.org

이걸 만들고 여기다가 styled-component, antd의 style data를 추가해준다. 어떻게 하는지는 코드로 대신하겠다!!

문제가 하나 또 남았다!

styled-component의 주요 feature 중에 이런게 있다!

 

  • No class name bugs: styled-components generates unique class names for your styles. You never have to worry about duplication, overlap or misspellings.

그렇다! styled-component는 매번 unique한 classname을 만들어준다. 이로인해 server와 client에서의 다른 classname 생성으로 인해 checksum mismatch가 생길수 있다. 이를 방지하기 위한 작업을 해주어야한다!

 

babel plugin중에  babel-plugin-styled-components  을 사용하면 된다.

https://styled-components.com/docs/tooling#babel-plugin

 

styled-components: Tooling

Additional Tools for styled-components, babel and TypeScript plugins, testing

styled-components.com

 

지금 nextjs compiler에 이식중인거 같은데, 사용가능하지만 몇개의 feature는 진행중인듯하다.

https://nextjs.org/docs/advanced-features/compiler#styled-components

 

Advanced Features: Next.js Compiler | Next.js

Learn about the Next.js Compiler, written in Rust, which transforms and minifies your Next.js application.

nextjs.org

minify, transpileTemplateLiterals and pure are not yet implemented. You can follow the progress here. ssr and displayName transforms are the main requirement for using styled-components in Next.js.

다 했으면 html 파일에 스타일링이 같이 먹힌 상태로 내려옴이 확인 가능하다!!

완료


번외로 궁금해서 찾아본 사항!

1. streaming ssr의 경우 어케함?  

streaming ssr 문제는 nextjs에서는 이 기능이 beta(app directory 방식)이라서 아직 신경안써도 될거 같음
https://nextjs.org/docs/advanced-features/react-18/streaming

 

React 18: Streaming SSR | Next.js

Streaming SSR Streaming allows you to incrementally render parts of your UI to the client. In Next.js 13, you can start using the app/ directory (beta) to take advantage of streaming server-rendering. Learn more by reading the app/ directory (beta) documen

nextjs.org

 

그리구 styled-component의 docs에 streaming api에 대해서 어떻게 해야할지 문서가 적혀있긴 한데.. (.renderToNodeStream()이 예시로) react 문서에서는 renderToNodeStream 이 deprecated라 이게 뭐 다른 streaming api도 유효한 대응인지, nextjs는 streaming을 할때 renderToNodeStream을 쓰는건지 다른 api를 쓰는건지.. 뭐 이런거에 따라 달라질거 같다.

일단, 뭐 지금은 알 필요없으니 이정도로만 서칭해봤다.
https://styled-components.com/docs/advanced#server-side-rendering

 

styled-components: Advanced Usage

Theming, refs, Security, Existing CSS, Tagged Template Literals, Server-Side Rendering and Style Objects

styled-components.com

반응형
Comments