Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.
RetroTech 팟캐스트 44BITS 팟캐스트

Data-URI로 웹 폰트 사용하기

l웹 대부분은 문서이므로 웹에서 폰트는 상당히 중요하지만 디자인 의도대로 폰트를 사용하기가 쉽지 않은 것이 현실이다. 사용자 환경마다 폰트의 설치 현황이 다르므로 디자인 의도에 맞는 타이포그래피를 사용해야 한다면 웹 폰트를 사용해야 한다.(웹 폰트로 인한 트레이드오프에 대해서도 고민이 많지만 이런 얘기는 다음에 기회가 되면...)

@font-face로 웹폰트 사용하기

웹 폰트는 꽤 많이 쓰이긴 하지만 먼저 웹 폰트에 대해서 얘기해 보자.

@font-face {
  font-family: 'action_manregular';
  src: url('fonts/Action_Man-webfont.eot?#iefix') format('embedded-opentype'),
       url('fonts/Action_Man-webfont.woff') format('woff'),
       url('fonts/Action_Man-webfont.ttf') format('truetype'),
       url('fonts/Action_Man-webfont.svg#action_manregular') format('svg');
  font-weight: normal;
  font-style: normal;
}

위처럼 @font-face로 폰트의 이름을 지정하고 해당 폰트 파일을 지정하면 웹 폰트를 사용할 수 있다. 웹 폰트 파일을 다양하게 지정한 것은 (항상 그렇듯이) 브라우저 호환성 때문인데 각 파일과 설정에 대해서는 웹 폰트 파헤치기에 자세하게 나와 있다. 위 폰트를 사용할 곳에서 font-family: action_manregular로 지정하면 웹 폰트를 사용할 수 있다.(여기서는 무료 폰트인 Action Man을 사용했다.)

웹폰트를 적용한 화면과 네트워크 상태

CSS 파일을 로드하면 브라우저가 자신에게 맞는 웹 폰트를 내려받고 이 폰트가 지정된 스타일에 적용하게 된다. 폰트파일이 여러 개라고 다 내려받는 것은 아니고 브라우저가 해석할 수 있는 한 가지만 내려받는다.

TTF, WOFF, EOF, SVG 파일의 크기

웹에서는 리소스 다운로드가 속도에 영향을 미치다 보니 이런 각 파일의 용량은 신경 쓰이기 마련이다. 여기서 사용한 폰트파일은 용량이 그리 크지 않지만 실제로 사용하다 보면 폰트의 두께별로 여러 개의 파일이 필요하기도 하고(얇은 폰트, 보통, 두꺼운 폰트 등) 용량이 꽤 되는 폰트파일도 있고 특히 한글이 들어가는 경우는 1, 2MB가 넘어가는 경우도 많다.

caniuse로 검색한 woff 지원 브라우저 상황

대부분의 모던 브라우저는 woff를 지원하고 있는데 지원 현황을 보면 IE 9 이상과 그 외 거의 모든 브라우저에서 woff를 지원하고 있다. 이 말은 대부분의 경우에는 woff를 사용할 것이고 그 외 일부 상황에서만 다른 폰트 파일을 사용하게 된다는 것이다.(woff 2도 있지만 아직은 지원하는 브라우저가 많지 않다.)

Data-URI

Data URI는 RFC 2397에서 정의되었으며 이미지 등의 외부 바이너리 파일을 웹페이지에 인라인으로 넣기 위해서 사용하고 형식은 data:[<MIME-type>][;charset=<encoding>][;base64],<data>이다.

data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAA8AAD/4QMxaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzAxNCA3OS4xNTY3OTcsIDIwMTQvMDgvMjAtMDk6NTM6MDIgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE0IChNYWNpbnRvc2gpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkY0RjI5NDAzRDlBRjExRTQ5RkFBREEzMTc1NDY5QTIxIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkY0RjI5NDA0RDlBRjExRTQ5RkFBREEzMTc1NDY5QTIxIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6RjRGMjk0MDFEOUFGMTFFNDlGQUFEQTMxNzU0NjlBMjEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6RjRGMjk0MDJEOUFGMTFFNDlGQUFEQTMxNzU0NjlBMjEiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7/7gAOQWRvYmUAZMAAAAAB/9sAhAAGBAQEBQQGBQUGCQYFBgkLCAYGCAsMCgoLCgoMEAwMDAwMDBAMDg8QDw4MExMUFBMTHBsbGxwfHx8fHx8fHx8fAQcHBw0MDRgQEBgaFREVGh8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx//wAARCAAQABQDAREAAhEBAxEB/8QAeAAAAwEAAAAAAAAAAAAAAAAABAYHBQEBAQEBAAAAAAAAAAAAAAAABAMFBhAAAQIEBAUBCQAAAAAAAAAAAQIDERIEBQAhExUxcYEUBkGxIjJCYiMWBxcRAAEDAgYDAQAAAAAAAAAAAAEAEQISAzFBUSITBMEUBXH/2gAMAwEAAhEDEQA/ALF+fVtmvdfRVYNfRpqHC2rNDjYKiZRMMwnhA9DDGv6QuQEhtLLG9+VuconcHSz5V5G7ebuuqbW4mlRKKVpeRQABEwBIiVZxwzrWBbgxxzQu12Dcm4wyTPoXb+f7tuD/AH0/cTzGeSbSlnjNCX3uOB1Q56GFOHlNpn69dRqx8IL9kN2l24dyw84K4QbepiwpKTD5tQhMcueKfPMxFiNv6p/REDJwd2jLI8d8Ou15qUfaWxRRBdqlpIEvrJH4jy64vf7cLY1OiP1+pO4cGjqrBttHtu26Y7TS0NP6JZfZjA5DVVm7rouONNOTMv/Z"

다음과 같은 base64로 인코딩된 data-uri을 <img>태그의 src로 지정하면 외부 파일 없이 HTML에 내장해서 파일을 표현할 수 있다.

이 트위터 이미지는 이미지 아이콘을 다음 코드로 출력한 것이다.(개발자 도구로 확인해 볼 수 있다.)

<img src="data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkq..중략...ouONNOTMv/Z" />


font 파일을 Data-URI로 생성하기

이미지처럼 웹 폰트도 같게 사용할 수 있는데 Font Squirrel에서 제공하는 Webfont Generator를 사용하면 쉽게 data-uri로 만들어 낼 수 있다.

font squirrel의 웹폰트 생성기 설정 화면

사용할 TTF 폰트파일을 업로드하고(무료 폰트만 업로드 해야 한다.) Expert 옵션을 선택하면 세부사항을 선택할 수 있다. 다른 폰트파일은 있으므로 여기서는 WOFF만 지정했지만 TTF 폰트만 있다면 여기서 다른 타입의 폰트파일을 만들 수 있다. 하단의 CSS 부분에서 Base64 Encode를 지정해야 한다. 다운로드 버튼을 누르면 잠시 처리하는 시간이 걸린 뒤에 압축파일을 다운로드 받을 수 있다.

다운로드 받은 파일에서 stylesheet.css파일을 열면 woff 파일 부분이 파일 링크 대신 base64로 인코딩된 data-uri를 볼 수 있고 이를 사용해서 @font-face를 다음과 같이 바꿀 수 있다.(data-uri 부분이 엄청나게 길어서 여기서는 생략을 했다. )

@font-face {
  font-family: 'action_manregular';
  src: url('fonts/Action_Man-webfont.eot?#iefix') format('embedded-opentype'),
       url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAA...중략...7vRb/kAAAABVSpW6QAA) format('woff');
       url('fonts/Action_Man-webfont.ttf') format('truetype'),
       url('fonts/Action_Man-webfont.svg#action_manregular') format('svg');
  font-weight: normal;
  font-style: normal;
}

Data-URI로 웹폰트를 적용한 화면과 네트워크 상태

이제 CSS 파일에 Data-URI를 넣었으므로 용량이 커진 대신 별도로 폰트 파일을 가져오지는 않는다. 너무 간단한 예제이므로 여기서 나오는 속도를 가지고 비교를 할 수는 없지만 크게 차이가 나지는 않는다.

Data-URI를 사용했을 때의 특징

  • Data-URI로 접근한 이유 중 하나는 HTTP 리퀘스트 수를 줄이기 위함이다. 웹페이지에서는 리소스를 가져오는 요청이 많이 발생하므로 CSS Sprites처럼 HTTP 요청개수를 줄여서 속도를 높이려는 것이다. 물론 CSS Sprites처럼 다수의 요청을 하나로 만들 수 있는 것은 아니고 CSS를 받은 다음에 font를 가져오는 요청 대신 CSS를 받을 때 한꺼번에 받도록 한 것이다.
  • 웹 폰트의 용량이 큰 경우에는 가져오는 데 시간이 걸리므로 소위 FOUC(Flash of Unstyled Content)라는 현상이 발생할 수 있다. 기본 폰트의 텍스트가 화면에 출력된 뒤에 웹 폰트 다운로드가 완료되면 폰트 스타일이 적용되는 현상이다. 이는 사이트의 요구사항에 따라 다를 텐데 웹 폰트가 적용 안 되더라도 내용을 보여주는 것이 더 우선이라면 괜찮지만 FOUC 현상 없이 웹 폰트가 적용된 텍스트가 필요하다면 Data-URI는 한꺼번에 같이 받으므로 이러한 현상을 줄일 수 있다.
  • 보통 font 파일은 브라우저가 캐싱하지만, Data-URI는 별도로 캐싱하지 않는다. 그래서 Data-URI를 사용한 파일(여기서는 CSS)에 캐싱 정책을 주어야 한다.
  • Data-URI를 가진 파일을 캐싱하더라도 사용하려면 브라우저가 Data-URI를 처리해야 하는데 이는 페이지를 열 때마다 매번 처리한다. 현재 이를 줄이는 방법은 없으므로 Data-URI를 너무 많이 쓰는 것은 좋지 않고 사용하더라도 바이너리를 받아서 사용하는 것과 비교해서 사용해야 한다.(사이트의 성능은 보통 복합적이므로 HTTP 요청을 줄이는 게 좋을지 Data-URI를 처리 시간을 없애는 게 좋을지에 대한 정답은 없다고 본다.) 모바일에서는 이 처리가 binary 파일보다 6배나 느리다는 글도 있다.(왜 느린가를 추가로 분석한 내용도 있다.)
  • Base64 인코딩은 보통 원래의 데이터보다 1.37배 정도 용량이 늘어나고 여기에 814바이트의 헤더 데이터가 추가된다. 물론 gzip 압축을 할 수 있으므로 최종 용량의 차이는 크게 나지 않는다.
  • 웹 폰트를 쓰면 파이어폭스가 크로스 도메인을 허용하지 않아서 폰트가 제대로 다운로드 되지 않는 문제가 발생할 수 있다. CDN이나 폰트 파일을 내려주는 곳에서 CORS를 설정해야 폰트 파일이 제대로 로드되는데 Data-URI를 사용하면 이런 설정 없이도 파이어폭스에서 웹 폰트를 사용할 수 있다.

위에도 간단히 언급했지만, HTTP 요청과 Data-URI 간의 트레이드 오프는 쉽게 한쪽이 더 좋다고 말하기 어렵고 한쪽이 더 좋다고 하더라도 체감할 정도로 큰 차이가 나는 것도 아니다. 물론 이 글에서처럼 woff를 Data-URI를 사용한다면 woff 브라우저에서는 상관없지만 woff가 되지 않는 파일에서도 woff를 받은 것과 같은 영향(woff의 Data-URI가 css에 포함되어 있으므로)이 생기는 문제고 있다.(그러니까 모던 브라우저 쓰세요.) 이 글은 Data-URI가 좋으니까 쓰세요 라기보다는 Data-URI로 사용하는 방법을 설명한 것에 가깝다.

2015/04/13 23:58 2015/04/13 23:58