FOUC와 해결방안

FOUC는 외부의 css를 불러오기 전에 스타일이 적용되지 않은 웹페이지가 나타나는 현상이다.
즉 브라우저의 CRP에서 Render Tree가 노출된 후 css와 js로 인해 DOM이 변경되면 변경사항을 적용하기 전 화면이 노출되는 현상이다.
IE에서 주로 발생한다.(IE11에서도 여전히 발생한다고 한다.)

@Import를 사용한 css

IE를 제외한 브라우저는 @import된 스타일이 적용될 때까지 화면에 표시하지 않는다.
하지만 IE는 화면에 노출된 상태로 스타일을 적용하여 FOUC를 유발한다.

다음과 같은 해결방법이 있다.

Preload 사용하기

preload 속성을 사용하여 중요한 css를 렌더링 이전에 사용할 수 있도록 한다.

css 링크 옮기기

head 요소안에 css를 링크하는 방식으로도 해결할 수 있다.

렌더링 지연시키기

render block 요소인 <link rel="stylesheet">을 사용하여 렌더링을 고의로 지연시켜 해결할 수 있다.

Proper caching 적용하기

  • 브라우저 캐시 혹은 cdn을 사용하여 정적 리소스를 받아오는 시간을 줄인다.

웹 폰트의 사용

@import를 사용하여 스타일링을 할 때와 같은 원리로 FOUC가 발생한다. IE는 웹폰트를 사용할 경우 기본 폰트를 불러들여 화면에 노출시키고 이후 사용된 웹 폰트로 다시 변경하기 때문에 발생한다.

다음과 같은 해결방법이 있다.

물론 위에서 언급한 preload와 같은 해결방법도 유효하다.

Font Loading API 사용하기

Font Face Observer 라이브러리는 웹 폰트의 로딩 상태를 추적할 수 있는 폰트 로더로, 파일 크기가 작고 실행속도가 빠르다는 장점이 있다.

다음과 같이 사용할 수 있다.

웹 폰트가 적용되지 않은 상태와 적용한 상태의 css를 적어둔다. 그 후 적용되지 않은 상태의 css가 먼저 적용되도록 한다.

1
2
3
4
5
6
7
body {
font-family: "Apple SD Gothic Neo", sans-serif;
}

body.fonts-loaded {
font-family: "Roboto", "Apple SD Gothic Neo" sans-serif;
}

그 후 사용할 웹 폰트로 FontFaceObserver의 인스턴스를 만들고 load 이벤트를 등록한다.

1
2
3
4
5
let font = newFontFaceObserver("Roboto");

font.load().then(function () {
document.body.classList.add("fonts-loaded");
});

font-display 속성

font-display 속성을 사용하여 웹 폰트의 로딩 상태에 따른 동작을 설정할 수 있다.
swap 속성을 통해 fallback font를 사용할 수 있다.

fallback font로 글자를 렌더링하고 로딩이 완료되면 웹 폰트를 적용한다.

1
font-display: swap;

SSR

SSR의 경우 SSR 단계에서 스타일을 해주어 해결할 수 있다.

공식문서나 바벨 참조하기,,^^

요약

웹폰트 - preload하여 사전에 받아와라, 폴백 폰트를 준비해라
css - 폰트보단 우선순위가 떨어지지만 preload해라. 안 될경우 head에서 받아와라.
최후의 방법으로는 렌더링을 지연시켜라..

Ref

FOUC(Flash of Unstyled Content)
웹 폰트 사용과 최적화의 최근 동향

댓글