jineecode

다크모드 토글 시, 폰트가 깜빡이는 현상 (Feat. Styled-Component) 본문

CSS/css in js

다크모드 토글 시, 폰트가 깜빡이는 현상 (Feat. Styled-Component)

지니코딩 2022. 9. 6. 13:55

1. 사건의 발단

전엔 못 본 거 같은데 다크모드 버튼을 토글할 때, 폰트가 깜빡이는 현상을 목격.

가장 먼저 든 생각은 이게 말로만 듣던 FOUC ('style이 적용되지 않은 내용'이 '깜빡'이는 현상) 인가? 라는 생각에 도달함

그러나 엄밀히 말해, 폰트만 이런 모습을 보이고 있는 것 같아서 FOUT(텍스트가 깜빡여보이는 현상. 즉, 브라우저가 웹 글꼴을 다운로드하기 전에 텍스트가 대체 글꼴로 렌더링되는 현상)으로 추측했음

말로만 듣던 FOUT를 목격하는 건 처음이라 당황스러우면서도 신나게 버그를 해결하기로 결심

 

2. 그럼 해결 방법을 찾아보자!

https://web.dev/avoid-invisible-text/

 

글꼴 로드 중 보이지 않는 텍스트 방지

글꼴은 로드하는 데 시간이 걸리는 대용량 파일인 경우가 많습니다. 이를 처리하기 위해 일부 브라우저는 글꼴이 로드될 때까지 텍스트를 숨깁니다("보이지 않는 텍스트의 깜박임(FOIT)". 성능을

web.dev

해당 글은 font-display를 소개하고 있다.

이 css를 사용하면 글꼴이 준비되지 않았을 경우, 각 브라우저가 어떻게 대응하는지 알려주고 있다. 

차근차근 따라하며 FontFaceObserver도 설치해서 테스트 해보았으나...

해결되지 않았다....

라이브러리로 테스트를 했을 때, 아주 잘 렌더링되고 있었고 여전히 폰트 깜빡임 현상은 남아있었다.

 

3. 폰트 렌더링에 문제가 있을 것이므로, 어떻게 사용자 지정 폰트를 지정해주었는지 확인해본 결과, Styled-Component에서 globalstyle로 font-family를 준 것을 확인할 수 있었다.

 

4. 그럼 styled-component를 잘못 쓰고 있을 지도 모른다는 생각에 구글링을 해보았다. 아니나 다를까!

https://github.com/styled-components/styled-components/issues/1593

 

Dynamic style change causes custom fonts to be re-requested from the server · Issue #1593 · styled-components/styled-component

I couldn't tell if this has anything to do with #1576, but it seems like potentially its own issue. I don't have @media rules, but I do have @font-face rules. System: OS: macOS High Sierra ...

github.com

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
Comments