본문으로 바로가기

화면 깜빡임(FOUC) 문제해결

category 웹개발론/크로스브라우징 2015. 6. 18. 11:00

어쩌면 낯선 단어일 수도 있습니다. 자꾸 어떤 단어와 헷갈리기도 하고... 웹문서를 작성하다가 요소들의 변화가 눈에 띄어 화면의 깜빡거림이 눈에 거슬리는 경우가 있습니다. 이와 관련된 내용을 다루어 봅니다.

FOUC 란 무엇인가?

FOUC(Flash of Unstyled Content)는 브라우저로 웹문서에 접근했을때, 미처 CSS의 스타일이 모두 적용되지 못한 상태에서 화면이 표시되어 발생하는 화면 깜박임, 스타일의 적용 전과 적용 후가 그대로 화면에 노출된 상태로 변경되는 현상등을 일컫는다. 이 현상은 특히 IE(Internet Explorer) 브라우저에서 확인되는데 최신의 IE11에서도 여전히 발생되는 문제이다. 이는 해당 웹문서의 사용자 경험을 떨어뜨리는 요인으로 작용한다.

FOUC 역사

FOUC는 2001년도에 Flash of Unstyled Content(링크 사라짐)란 이름으로 처음으로 글이 기재되었으며, 오직 IE에서만 발생하는 문제였다. 다음으로 2006년에 사파리 브라우저에서 결함이 발견되어 The FOUC Problem란 이름으로 글이 기재되었다. 최근에는 JS나 jQuery를 이용해 스타일링을 하기도 하므로 다방면에서 FOUC가 발견되고 있다.

개인적인 경험으로는 브라우저를 망라하고 이 현상이 목격되었다. 이는 과거와 달리 오늘날에는 많은 자원을 끌어다 쓰기에 예상치 못한 화면 깜박임을 마주하게 된다.

FOUC 원인

FOUC가 발생하는 주된 원인은 브라우저의 동작 방식과 연관이 있다.

  1. 브라우저는 마크업에 참조된 모든 부수적인 파일들을 모아 즉시 DOM(Document Object Model)을 생성
  2. 가장 빠르게 분석할 수 있는 글의 내용부분을 화면에 표시
  3. 화면에 표시된 내용을 선언된 마크업의 순서에 따라 스타일을 적용하고 스크립트를 실행

최근의 웹문서들은 여러 개의 CSS 파일을 참조하고 DOM 구조를 변경하므로 이는 더욱 빈번하게 발생하고 있다.

  • 웹문서들은 종종 프린터와 무선 장치를 위한 CSS 규칙으로 브라우저 화면 이외의 다른 미디어에 대한 스타일 참조를 포함한다.
  • 웹문서는 @import로 스타일 파일을 가져오고, 다른 CSS를 참조할 수 있다.
  • 온라인 광고와 동영상과 검색 엔진같은 다른 곳에서 삽입된 콘텐츠는 종종 코드 블록 내에서 자신의 스타일 규칙을 구술한다.
  • 웹 문서가 모두 불러와진 후 자바스크립트를 이용해 DOM 구조를 변경한다.

무엇보다도 최근에 많이 사용되고 있는 웹폰트의 경우에도 IE 브라우저에서는 FOUC를 유발해 매우 산만하고 아름답지 못한 경험을 선사한다.

브라우저별 테스트

윈도우용 브라우저를 사용한 테스트 결과이다.

참조된(@import) CSS

크롬(Chrome), 파폭(Firefox), 오페라(Opera)의 경우, 참조되는 스타일이 적용될때까지 화면에 표시하지 않지만, IE의 경우 화면에 노출된 상태로 스타일이 적용되어 FOUC를 유발한다. 사파리의 경우 윈도우용 브라우저를 더 이상 지원하지 않으므로 생략.

자바스크립트로 DOM 구조 변경

자바스크립트를 이용해 DOM 구조를 변경하면 대부분의 브라우저가 콘텐츠를 화면에 노출한 상태로 변경되어 FOUC를 유발한다.

FOUC 해결책

  • FOUC를 최소화하기 위해서는 기본적으로 <head> 요소안에 CSS를 링크하고, @import의 사용을 자제해야 한다.
  • 자바스크립트의 선언순서, 위치를 변경함으로써 극복 가능하거나, 매우 짧아질 수 있다.(성능을 위해 </body> 요소 앞에 자바스크립트를 위치시키곤 하는데 이를 <head> 안으로 위치를 변경해 본다.)
  • FOUC를 유발하는 구역을 숨겼다가 문서의 스타일이나 스크립트가 모두 적용되면 보여준다.

FOUC를 유발하는 구역을 숨겼다가 다시 보여주는 방법을 아래에서 설명한다.

<html class="no-js">
  <head>
    <style>
      .js #fouc {display: none}
    </style>
    <script>
    (function(H){H.className=H.className.replace(/\bno-js\b/,'js')})(document.documentElement)
    </script>
  </head>

  <body>
    <div id="fouc">
     ...
    </div> <!-- /#fouc -->

    <script>
    document.getElementById("fouc").style.display="block";
    </script>
  </body>
</html>

html 태그에 .no-js를 추가하고 head 태그에 스타일과 자바스크립트를 추가한다. 해당 자바스크립트는 브라우저의 자바스크립트가 활성화되어 있을 경우, html 태그의 클래스를 .js로 변경한다. 숨겨질 구역에 ID 값으로 fouc를 추가했다.

위와 같이 페이지 전체를 감싸는 영역을 지정하면 빈 페이지를 보여주다가 모든 리소스가 로드되면 페이지를 보여주게 된다.

필자는 IE에서 유독 웹폰트들에 대한 FOUC가 거슬려 브라우저스니핑으로 IE들을 골라내고 이에 대한 FOUC 처리를 하곤 한다. 또한 숨겨질때 빈페이지를 보여주는 대신 로딩중이라는 표기나 이미지를 넣는 것도 방법이 될 수 있다.