폰트는 용량이 커서 1,2개 정도만 사용하기
용량을 줄이기 위해선 같은 폰트를 링크로 다운받을 때 세트로 가져오기
web safe font : 일반적으로 시스템에 설치된 폰트 (윈도우 : 맑은 고딕 , 맥 : apple 산돌 고딕)
web font : 기본으로 설치되어 있지 않고, 별도로 다운로드가 필요한 코드
❓ 별도로 다운로드가 필요한 웹 폰트를 왜 사용할까?
1. 디자인적으로 기본 폰트로 표현할 수 없는 경우
2. 가독성이 떨어짐
3. 한국어와 같은 외국어는 영어 위주로 지원되는 web safe font로는 한계가 있음
하지만 이렇게 웹 폰트를 사용하게 되면
1. 웹 폰트 다운로스 시간만큼 rendering이 느려진다.
2. 한글 폰트는 용량이 크다. → 렌더링 시간도 많이 들고, 프로그램 용량 자체에도 문제
웹 폰트 확장자 종류와 브라우저 별 지원 현황 (2021-11)
1. EOT
: IE 8 이하
2. TTF
: 구형 안드로이드 버전(4.4)에서 필요
3. WOFF(Web Open Font Foramt)
: 압축된 폰트 형식, 대부분의 모던 브라우저에서 지원
4. WOFF2
: WOFF보다 30%~50% 더 압축
인터넷 익스플로어의 폰트 형식은 '설치 가능' 으로 설정된 경우에만 작동한다.
2018년 글 기준으로 IE는 WOFF까지 지원 가능, WOFF2는 지원 불가
이렇게 브라우저간 호환되지 않는 폰트가 있을 경우를 대비해 @font-face 형식을 다음과 같이 맞춰준다.
웹 폰트 확장자 순서
브라우저는 지원 가능한 파일 형식이 나올 때까지 순서대로 다운 받음
1. 압축률이 가장 높은 WOFF2를 가장 먼저 작성한다
2. format()을 반드시 작성해야한다.
3. IE8 이하를 지원해야하는 경우, IE는 format 형식을 읽지 못하기 때문에 가장 앞에 eot 형식 선언 (format을 적지 않아도 된다.)
src: url(/static_fonts/NanumGothic-Regular.eot),
url(/static_fonts/NanumGothic-Regular.woff2) format("woff2"),
url(/static_fonts/NanumGothic-Regular.woff) format("woff"),
url(/static_fonts/NanumGothic-Regular.ttf) format("truetype");
src: local('Nanum-Gothic'),
서브셋 폰트 ? 폰트 파일에서 불필요한 글자를 제거하고 사용할 글자만 남겨둔 폰트
특히 한글 폰트의 경우, 가능한 조합이 무수히 많기 때문에 영어 폰트에 비해 가지고 있는 폰트 글자 타입이 많다. 삭제 할 글자 조합은 '국가 표준의 정보 교환용 부호계' 를 기준으로 삼으면 된다.
다만 기존에 있는 서브셋 폰트를 사용하는 것이 아니라 기존 폰트에서 새로운 서브셋 폰트로 만들기 위해서 별도의 수정 작업이 필요해, 사용 과정이 복잡하다.
만드는 방법
- python을 활용한 subset 생성기 https://github.com/fonttools/fonttools
- Google의 subset 활용
브라우저는 웹 페이지를 렌더링 하는 과정에서 웹 폰트가 다운되어있지 않으면, 해당 텍스트의 렌더링을 차단한다.
: 기본 스타일 폰트가 일단 적용 후, 웹 폰트로 변환
1. 인터넷 익스플로어 계정의 브라우저에서 사용
2. 웹 폰트의 로딩 여부와 관련 없이 텍스트가 항상 보이는 장점 有
3. 글꼴의 자간, 높이 등 서식이 달라 웹 폰트 적용 전후의 레이아웃 차이가 존재할 수 있음.
❓ 레이아웃의 차이가 존재하는 이유
브라우저의 렌더링 과정에서 브라우저는 HTML 파일을 이용해 DOM 트리를 생성하고, CSS나 JS 파일을 요청해 렌더트리와 접목시킨다. 이 때 폰트 속성을 필요로 하는 특정 텍스트를 렌더트리가 가르키게 되면, 해당 폰트를 요청한다.
이 후, 브라우저가 스크린의 레이아웃을 설계하고 그리는 데 만약 폰트가 아직 도착하지 않았다면, 브라우저는 해당 텍스트를 그리지 않는다. 폰트가 도착한 뒤, 브라우저가 텍스트를 그려낸다.
렌더트리가 그려진 뒤, 페이지 컨텐츠의 첫 paint와 폰트 리소스 요청간 간격은 브라우저가 페이지 레이아웃을 렌더할 때 텍스트들을 누락시키는'빈 텍스트 문제 (blank text problem)'
를 만들어낸다.
: 텍스트가 보이지 않는 상태에서, 웹 폰트 적용 후 폰트 나타남
1. firefox, chrome 등의 브라우저에서 사용
2. 웹 폰트가 로딩되지 않은 채로 3초가 지나면, 폴백폰트(기본폰트)로 우선 렌더링
3. 그러나 UX관점에서 FOIT 방식은 좋지 않아 FOUT 방식으로 작동하도록 바꿔야함.
로딩 성공시, promise 객체를 리턴해주는 라이브러리
CSS를 웹폰트를 적용하지 않은 상태 (body) 와 적용된 상태 (.font-loaded) 클래스를 생성해두고, JS에서 웹 로딩이 완료되면 .font-loaded 클래스를 추가하는 형식으로 FOUT 처럼 작동되도록 한다.
font-display의 속성을 이용해 FOUT 처럼 보이게 한다.
font-display는 auto, block, swap, fallback, optional 의 5가지 옵션을 갖고 있다.
block
- FOIT와 동일하게 동작하는 방식
swap
- FOUT와 동일하게 동작하는 방식
fallback
- 100ms동안 텍스트가 보이지 않고 이후 폴백폰트로 렌더링, 약 2초간의 swap전환 시간이 존재해 이 때 변환되지 않으면 시스템을 재로딩 하지 않는 이상, 웹 폰트로 변환되지 않은다.
캐시에는 웹 폰트가 저장되어 사이트에 재접속시 웹폰트가 적용된 페이지를 확인할 수 있다.
optional
- fallback이랑 비슷하게 작동하지만, 네트워크 상태를 파악한다는 차이점이 있다. 네트워크 상태가 좋지 않으면 웹 폰트 다운이 끝나더라도 캐시에만 저장하고 페이지에 적용은 하지 않는다.
FOIT가 사용되는 대표 브라우저들에서는 작동한다.
하지만 다음 방식은 단점이 존재한다.
- CSS로는 설정에 한계가 존재 - swap time과 block time 조절이 불가능
- 100ms는 한글 폰트를 다운 받기엔 너무 짧은 시간
FOUT 방법을 사용하는 경우, 폰트가 로딩되지 않았을 때, 기본 폰트로 인해 레이아웃이 생각했던 것과 다르게 보여질 수 있다. 이를 해결하기 위해 font style matcher를 이용해 두 폰트 사이의 간격을 조정하고, font face observer 라이브러리의 폰트 로더 방법으로 디테일하게 기본 폰트의 속성을 이용하고자 하는 폰트의 속성과 맞춰준다.
<link>
태그의 rel속성에 preload 옵션을 사용하면 해당 리소스를 다른 리소스보다 빨리 로딩한다. 폰트, 이미지, 스크립트 파일 등 브라우저 생성시 빨리 그려져야하는 리소스들에 적용한다.
preload 옵션으로 다운로드 하는 리소스가 너무 많으면, 렌더링 시간도 그만큼 늦어지는 단점이 있다. 꼭 필요한 리소스들만 preload 옵션을 사용하는 것이 좋다.
<link rel="preload" href="fonts/zantroke-webfont.woff2" as="font" type="font/woff2" crossorigin>
리소스의 유형을 제대로 명시하지 않으면, 브라우저는 해당 리소스를 사용하지 않음
리소스를 중복 참조하면 중복된 개수만큼 리소스를 가져옴. 따라서 crossorigin을 꼭 기입하기
현재 페이지에서 3초이상 사용되지 않는 리소스는 콘솔창에 경로가 출력되며 경고메세지가 뜬다.
참고
https://web.dev/optimize-webfont-loading/
https://velog.io/@vnthf/%EC%9B%B9%ED%8F%B0%ED%8A%B8-%EC%B5%9C%EC%A0%81%ED%99%94-%ED%95%98%EA%B8%B0
https://d2.naver.com/helloworld/4969726