메인 배너에 특정 폰트를 지정할 수 있게 해달라는 요청이 들어왔다.
폰트 변경... 어떻게 하더라? font-family만 건들면 됐던가?
다른 작업과 다르게 손이 바로 움직이지 않았다. 웹개발을 시작한 지 그리 적지 않은 시간이 흘렀지만 지금까지 폰트 작업은 할 기회가 별로 없었던 것 같다.
다행이라고 해야하나? 최근에 다른 팀원 폰트 변경 이슈를 진행하여 작업 이력이 남아있었고, 해당 작업 이력을 참고해 요구사항을 구현했다. 내가 하고 있는 작업에 대해 이해를 못 한 상태로 진행한 건 아니지만 뭔가 놓치고 있는 기분이 들었다. 그래서 글 하나 쓸 겸 웹사이트에서 폰트가 렌더 되기까지의 과정을 알아보았다~~
https://web.dev/learn/performance/optimize-web-fonts 이 글을 읽고 내가 이해한 대로 다시 써보았다.
📝 사용할 폰트 정의
To. 브라우저... 나 여기에 있는 요 폰트 파일 쓰고 싶으니까 가져와라?
웹사이트에 폰트를 적용해 보여주려면 우선 브라우저에게 우리가 어떤 폰트를 사용할지, 또 폰트파일은 어디서 가져올 수 있는지 알려주어야한다. 이는 스타일시트에 @font-face 를 이용해 작성해주면 된다.
@font-face {
font-family: "Open Sans";
src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2");
}
"Open Sans" 라는 이름으로 font-family를 정의하고, 해당 폰트 파일을 어디서 가져올 수 있는지 작성한다.
해당 font-family를 사용하는 element가 페이지에서 사용되기 전까지는 폰트를 불러오지 않는다. 아래 코드처럼 font-family가 지정된 h1 element 있다고 하자.
h1 {
font-family: "Open Sans";
}
h1을 페이지에서 사용하는 게 확인이 되면 그때 브라우저는 OpenSans 폰트 파일을 불러오기 시작한다.
미리 불러올 수 없을까??
preload
이렇게 정의된 style sheet를 가져오고, 해당 font-family를 사용하는 element 가 있어야만 파일을 불러오고 있으니 폰트를 늦게 불러오게 된다. 여기서 preload 를 이용하면 style sheet 로딩 과정 없이, 폰트가 필요한지 확인하는 과정 없이 폰트를 페이지와 함께 미리 불러올 수 있게된다.
<!-- The `crossorigin` attribute is required for fonts—even
self-hosted ones, as fonts are considered CORS resources. -->
<link rel="preload" as="font" href="/fonts/OpenSans-Regular-webfont.woff2" crossorigin>
하지만 네트워크 대역폭(bandwidth)을 부분 사용하기 때문에 다른 중요한 리소스의 다운이 늦어질 수도 있다. 과도하게 사용하지 않도록 주의해야한다. 또, 폰트는 CORS 리소스이므로 자체 호스팅한 폰트라도 crossorigin 속성을 지정해주어야한다.
Inline @font-face declarations
이번엔 style sheet 로딩 과정 없이, 그러나 사용할 폰트만 불러올 수 있는 방법이다. 위의 방법은 사용하지 않을 폰트까지 모두 불러왔다면 이번엔 페이지에서 사용되는 폰트만 체크하여 불러올 수 있다는 이점이 있다.
바로 HTML 의 <head> 내에 <style> element를 사용해 @font-face를 선언하는 방법이다.
하지만 브라우저는 렌더링 차단 리소스가 모두 로드된 후에 글꼴 파일 다운로드를 시작하므로 나머지 css가 외부 style sheet에 있는 경우 브라우저는 외부 style sheet가 다운될 때까지 기다리게 된다.
📥 폰트 파일 다운로드
자체 호스팅하거나 다른 서버에서 가져오거나
브라우저가 사용할 폰트를 파악했다면 이제 폰트 파일을 다운로드 해 올 것이다. 이 파일은 어디서 가져올까?
Google Fonts 같은 서비스에서 제공하는 걸 가져오거나, 자체 호스팅 할 수 있다. 타사 서비스를 이용하는 경우 공급하는 도메인에 연결하는 과정이 있으므로 다운로드 하기까지 시간이 더 걸릴 수 있어 유의해야한다. 이 오버헤드를 줄일 방법이 있긴 한데, preconnect 를 사용하면 다른 출처(origin)에 대한 연결을 더 빨리 하도록 지시할 수 있다.
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
woff2 포맷의 폰트를(만) 사용하자!
웹에 사용하기 가장 좋은 폰트 파일 형식은?
WOFF2 는 다양한 브라우저를 지원하며 파일을 압축시켜 크기를 줄인 만큼 다운로드 시간도 빨라진다. 레거시 브라우저를 지원해야 하는 경우에는 WOFF, EOT, TTF 등 다른 형식을 사용해야 할 수 있다. 하지만 레거시 브라우저를 지원할 필요가 없는 경우에는 WOFF2 이외의 웹 글꼴 형식을 사용할 이유가 없다고 원문에서는 강조되어있다...ㅋㅋ 그정도로 최신 브라우저에서의 WOFF2 형식의 폰트 사용을 권장하고 있다
작성예정..
+ 폰트 포맷 변경 방법+ 레거시 브라우저도 지원하도록 다양한 포맷으로 font-face정의해두기
Subset 이용하기
웹 폰트 파일에 있는 모든 글자들을 쓰지 않을 건데... 일부만 떼서 사이즈를 줄여 받아올 수는 없을까?🤔
웹 폰트는 일반적으로 여러 언어에서 사용되는 다양한 문자를 표현하는 데 필요한 다양한 glyph(문자 기호)들을 포함한다. 만약 페이지에서 한 가지 언어로만 콘텐츠를 제공하거나 단일 알파벳을 사용하는 경우 subset을 이용해 불러올 폰트의 사이즈를 줄일 수 있다! 이 subset이란, 원본 폰트 파일에 포함되어있는 glyph 들의 축소된 집합이다. 그러니까, 폰트 파일에 있는 모든 걸 불러올 필요가 없다면 subset 하위집합을 만들어 사용할 폰트의 사이즈를 줄일 수 있다는 것이다.
Google Fonts와 같은 폰트 제공 서비스는 쿼리 문자열 매개변수를 사용해 subset을 자동으로 제공하고 있다. 예를들어 사이트에 'Welcome'이라는 문구에만 필요한 폰트가 있는 경우 다음 URL(https://fonts.googleapis.com/css?family=Monoton&text=Welcome) 통해 Google Fonts에 해당 subset을 요청할 수 있다.
만약 자체 호스팅 방법을 이용하고 있다면, glyphanger, subfont와 같은 툴을 이용해볼 수 있다.
🎨 폰트 렌더링 (with font-display)
브라우저가 정의된 폰트를 다운로드 받아왔다면 이제 폰트를 렌더링 할 수 있다.
기본적으로 브라우저는 폰트가 다운로드될 때까지 해당 폰트를 사용하는 모든 텍스트의 렌더링을 차단하고 있지만 어떻게 렌더링 할지 우리가 선택할 수도 있다. font-display CSS 속성을 사용하여 브라우저의 텍스트 렌더링 동작을 조정하고, 웹 폰트가 완전히 로드될 때까지 어떤 텍스트를 표시하거나 숨길지 설정할 수 있다. 이 속성들을 알아두고 상황에 맞게 사용하면 되겠다.
- block
폰트 파일이 로드되거나 타임아웃 될 때까지 텍스트 렌더링이 차단된다. - swap
폰트 파일이 로드될 때까지 대체 폰트를 사용한다. 사용하려는 폰트 파일이 로드되면 즉시 변경된다. - fallback
block과 swap 의 절충안이다. 백업 폰트를 사용하는 짧은 렌더링 차단 기간 후, 웹 폰트가 로드될 때까지 기다리는 시간이 추가된다. - optional
사용자 에이전트가 네트워크 상태와 사용자 경험을 고려하여 웹 폰트를 사용할지 결정한다.
위 속성에 대한 자세한 내용과 demo 를 원문 사이트에서 확인할 수 있다
https://web.dev/learn/performance/optimize-web-fonts#font_demos