일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- Critical Rendering Path
- Babel
- async
- vanilla-extract
- 비동기
- 컴포넌트
- thread
- MSW
- react server component
- 캐쉬
- Cache
- next hydration
- CSS-in-JS
- 기초
- 리액트쿼리
- 리액트네이티브
- amplify
- mock service worker
- front-end mocking
- Concurrent Mode
- react-native
- 자바스크립트
- 최적화
- 리액트
- 기본
- mockoon
- React
- 아키텍처
- next.js
- Basic
- 동기
- 개발자
- 목킹
- JavaScript
- SWC
- styled-component
- react-query
- link
- sprinkles
- 쓰레드
- Today
- Total
Don’t worry about failures
css-in-js를 떠나 보내야하나? 본문
해당 글은 다른 아티클을 보면서, 편향된 개인적인 생각일 수 있다.
이전 사이드프로젝트를 리팩토링하는 새로운 나만의 프로젝트를 하면서 고민되는 사항이 생겼다.
내가 평소 즐겨쓰던 Styled-component를 현재의 프런트엔드 개발 흐름과 잘어울리까? 에대한 고민이다.
일단, 내가 왜 Styled-component를 즐겨썼을까?
개발자 경험이 가장 크다고 생각했다.
<div className='container'/>
<Container/>
위의 코드를 봤을 때 개인적으로는 div로 표현하기보다는 Container으로 표현하는게 내 눈에는 더 파악하가기가 쉽다고 생각했다.
이 외에도 다른 장점들을 살펴보면,
1. 지역 스코프
스타일드 컴포넌트의 동작 방식을 보면,
styled.div에 대한 고유 ID와 style을 적용한 css를 기반으로 해시를 생성하고 생성된 값은 className으로써 사용이된다.
const [generatedClassName, setGeneratedClassName] = useState(className);
생성된 className은 상태로써 관리가 되고 변경되면 리렌더링이 발생된다.
이 className은 css와 함께 stylis와 같은 라이브러리를 활용하여 sytyle sheet로 변환이 된다.
const styleSheet = stylis(`.${generatedClassName}`, evaluatedCSS);
생성된 스타일 시트이 적용되어 스타일이 반영 된다.
이와 같이 유니크한 값을 가지고 생성이 되기 때문에 className이 중복되는 문제를 가릴 수 있다.
2. 자바스크립트 변수
자바스크립트의 변수를 손쉬게 styled-component에 넘겨서 동적으로 적용하여 사용할 수 있다. 해당 부분은 생각보다 다루기가 편하다.
단점을 봐보자.
1. 오버헤드
장점에서 살펴봤다싶이 className이 동적으로 생성되어 스타일이 반영이된다. 이러한 동작들은 모두 런타임에 발생된다는 것이다. 이에 따라 런타입 오버헤드가 존재하게 된다.
2. 성능
해당 성능에 있어서 18에서 제공된 훅을 통해 이슈를 제거
useInsertionEffect

리액트 훅의 flow를 보면 위와 같다. 컴포넌트가 업데이트가 되면 layoutEffect -> paint -> effect 순으로 발생된다. 근데 만약에 paint가 끝난 후에 css-in-js가 동적으로 css를 변경한다하면 다시 작업이 일어나야하기 때문에 성능에 있어 문제가 된다.
이를 위해 useInsertionEffect와 같은 훅을 18에서 나오게 됐다. css-in-js를 위해 나온 훅이다. 가장 먼저 trigger가 되어 먼저 작업되도록한다. 즉, insertEffect -> layoutEffect -> paint -> effect
이와 같이 css-in-js를 사용하게 되면, 해당 부분과 같이 관리 포인트가 더 생기는 것에 대한 단점을 볼 수 있다.
3. 서버사이드렌더링
요즘이라고 하기엔 오래되긴 했지만 지속적으로 서버에서 렌더링을 추구하고 있고, Next와 같은 프레임워크가 이를 도와줌으로써 점차 서버사이드 렌더링을 추구하고자한다.
이에 더해 리액트18 이후에는 서버 컴포넌트까지 나오게 됐다.
css-in-js는 서버사이드 렌더링에서 어떻게 사용을 해야할까?
Next.js, styled-component를 기준으로 코드를 살펴보면, styled sheet를 collectStyles를 통해 style을 수집하여 서버단에서 생성하여 기입해준다.
// https://github.com/vercel/next.js/blob/canary/examples/with-styled-components-babel/pages/_document.tsx
import type { DocumentContext, DocumentInitialProps } from "next/document";
import Document from "next/document";
import { ServerStyleSheet } from "styled-components";
export default class MyDocument extends Document {
static async getInitialProps(
ctx: DocumentContext,
): Promise<DocumentInitialProps> {
const sheet = new ServerStyleSheet();
const originalRenderPage = ctx.renderPage;
try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) =>
sheet.collectStyles(<App {...props} />),
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
),
};
} finally {
sheet.seal();
}
}
}
하지만 이는 css-in-js와는 맞지 않는다는 것이다. 서버사이드렌더링이든 서버 컴포넌트든 서버에서 작업이 되는 것을 추구하는데 css-in-js는 클라이언트에서 런타임 때 작업이 이루어진다.
위의 next에서 소개해준 것처럼 작업을 통해 styled-component를 계속해서 사용할 수는 있지만, 개념적으로 봤을 때는 그렇게 잘 어울리지 않는 선택일거같다고 생각이 든다.
css-in-js의 라이브러리 중 하나인 stitches.js의 경우에도 18이 나온 이후로 업데이트가 느려지며, 지속적인 업데이트가 불투명하다고 issue에 올라왔다.
https://github.com/stitchesjs/stitches/issues/1144
Hey y'all, I wanted to chat with everyone on the best route for the future of Stitches.
Obviously, things have been very slow lately. Here's the situation: most of the team that created Stitches is no longer available to work on it. And with React 18, the ecosystem has changed and made the future for runtime injection pretty murky.
If you're currently using stitches for SPAs, the React 18 changes don't really matter to you and you can continue using stitches without making any changes. But looking forward, the best route for the library – as far as I can tell – is to use static extraction. For stitches, that means a major rewrite of the styling engine.
So, given all of that, I think the right thing to do is to open it up to the community to have a chance to drive it forward. I'm chatting with a few very qualified people who have volunteered to take over the reins on Stitches. I'd love to see a great maintainer emerge who can help with the small features and daily triage and also drive toward the next major version for React 18+.
I'd LOVE to see the Stitches API with a static extraction engine. I think there's a huge opportunity here to be the perfect styling lib in the React ecosystem.
Let me know what you think of this path and if you'd like to nominate or volunteer as a lead maintainer. 🖤
Next.js 또한 CSS Modules와 Tailwind CSS를 공식문서에서 추천을 하고 있다.
이 뿐만 아니라 css-in-js의 장점을 가져가면서 zero runtime을 제공해주는 vanilla-extract 을 사용하기도 한다.
이와 같은 단점도 존재하며, 가장 크게는 프런트엔드의 방향이 서버를 활용한 렌더링을 추구하고자 하는데 이와는 어울리지 않을거같다고 생각하기 때문에 css-in-js이 사용에 대해 고민을 해보는 것도 좋을거같다.
참고자료:
(번역) 우리가 CSS-in-JS와 헤어지는 이유
원문: https://dev.to/srmagura/why-were-breaking-up-wiht-css-in-js-4g9b
junghan92.medium.com
https://shiwoo.dev/posts/next-13-and-css-in-js
CSS-in-JS와 서버 컴포넌트
CSS-in-JS와 서버 컴포넌트는 왜 공존하기 어려운지 알아보고, 이를 해결하기 위해 styled-components를 Tailwind CSS로 마이그레이션한 경험을 공유합니다.
shiwoo.dev
https://bundlephobia.com/package/styled-components@6.1.8
styled-components ❘ Bundlephobia
Find the size of javascript package styled-components. Bundlephobia helps you find the performance impact of npm packages.
bundlephobia.com
'React' 카테고리의 다른 글
리액트 서버 컴포넌트 (0) | 2024.04.04 |
---|---|
MSW에 대해 (0) | 2024.03.26 |
전역 상태관리에 대해 (0) | 2024.03.25 |
Hydrate에 대해 (0) | 2024.03.22 |
React StrictMode에 대해 (0) | 2024.03.21 |