jineecode
다크모드 토글 시, 폰트가 깜빡이는 현상 (Feat. Styled-Component) 본문
1. 사건의 발단
전엔 못 본 거 같은데 다크모드 버튼을 토글할 때, 폰트가 깜빡이는 현상을 목격.
가장 먼저 든 생각은 이게 말로만 듣던 FOUC ('style이 적용되지 않은 내용'이 '깜빡'이는 현상) 인가? 라는 생각에 도달함
그러나 엄밀히 말해, 폰트만 이런 모습을 보이고 있는 것 같아서 FOUT(텍스트가 깜빡여보이는 현상. 즉, 브라우저가 웹 글꼴을 다운로드하기 전에 텍스트가 대체 글꼴로 렌더링되는 현상)으로 추측했음
말로만 듣던 FOUT를 목격하는 건 처음이라 당황스러우면서도 신나게 버그를 해결하기로 결심
2. 그럼 해결 방법을 찾아보자!
https://web.dev/avoid-invisible-text/
해당 글은 font-display를 소개하고 있다.
이 css를 사용하면 글꼴이 준비되지 않았을 경우, 각 브라우저가 어떻게 대응하는지 알려주고 있다.
차근차근 따라하며 FontFaceObserver도 설치해서 테스트 해보았으나...
해결되지 않았다....
라이브러리로 테스트를 했을 때, 아주 잘 렌더링되고 있었고 여전히 폰트 깜빡임 현상은 남아있었다.
3. 폰트 렌더링에 문제가 있을 것이므로, 어떻게 사용자 지정 폰트를 지정해주었는지 확인해본 결과, Styled-Component에서 globalstyle로 font-family를 준 것을 확인할 수 있었다.
4. 그럼 styled-component를 잘못 쓰고 있을 지도 모른다는 생각에 구글링을 해보았다. 아니나 다를까!
https://github.com/styled-components/styled-components/issues/1593
Styled-Components는 스타일이 Render 될 때 마다 head 태그의 style 태그를 변경한다. 새로운 스타일이 등장할 때마다 폰트를 재요청하는 현상이 나타난 것
아래는 다크모드를 토글할 때마다 style에 변화가 일어나는 것을 확인한 태그이다.
head 아래 style에 담겨있었다.
network/font 탭에서도 토글할 때마다 폰트가 계속 담기는 것을 확인할 수 있었다.
5. 빛이 보인다. 그래서 해결 방법은?
@font-face를 globalStyle에 넣지 말고 쏙 빼내서 css로 다루면 된다.
6. 참고로 이 프로젝트는 NextJS로 만들어져서, 글로벌 css에 대한 규칙도 정해져 있다.
마음대로 css를 import 할 경우 Global CSS Must Be in Your Custom \<App> 에러를 직면하게 될 것이다...
7. 전체 코드
// pages/_app.tsx
import '../src/styles/font.css';
function MyApp({ Component, pageProps }: AppProps) {
return (
<>
<GlobalStyle />
<Component {...pageProps} />
</>
);
}
export default MyApp;
// src/styles/font.css
@font-face {
font-family: 'Pretendard-Regular';
font-display: swap;
src: url('/fonts/PretendardVariable.ttf') format('woff');
font-weight: 400;
font-style: normal;
}
// src/styles/globalStyle.ts
import { createGlobalStyle } from 'styled-components';
const GlobalStyle = createGlobalStyle`
html,
body {
font-family: Pretendard-Regular, -apple-system, sans-serif;
}
`
오랜만에 통신 에러가 아닌 성능 에러를 마주하니 재미있었다 ㅠㅠ...
'CSS > css in js' 카테고리의 다른 글
styled-components 이중 extends 해주기 (0) | 2022.02.24 |
---|