폰트 최적화
초기 페이지 로딩 시 폰트 다운로드 하는 시간 때문에
폰트가 깜빡이는 현상이 나타난다. (폰트 다운로드 후 폰트가 글자에 입혀짐)
웹 폰트의 문제점
- FOUT(Flash of Unstyled Text) - 폰트 다운로드 전 기본 폰트로 텍스트가 보여짐, 다운로드 후 폰트 적용된 텍스트 보여줌 / IE, Edge
- FOIT(Flash of Invisible Text) - 폰트 다운로드 전 텍스트 노출하지 않음, 다운로드 후 폰트 적용된 텍스트 보여줌 / Chrome, Safari
웹 폰트의 최적화 방법
1) 폰트 적용 시점 컨트롤 - FOUT or FOIT or 혼합, 새 방식 등
css의 속성 font-display
사용
- auto - 브라우저 기본 동작
- block - FOIT(timeout = 3s) / 폰트 다운로드 완료시 폰트 입힌 텍스트 보여줌
timeout: 다운로드까지 기다리는 시간, 지나면 기본 폰트 입힌 텍스트 보여줌
- swap - FOUT
- fallback - FOIT(timeout = 0.1s) 3초 후에도 불러오지 못했을 시, 기본 폰트로 유지, 이후 캐시(다운로드 되도 기본 폰트 사용)
- optional - FOIT(timeout = 0.1s) 이후 네트워크 상태에 따라, 기본 폰트로 유지할지 웹폰트를 적용할지 결정, 이후 캐시
FOIT 시 자연스러운 애니메이션 주기
FOIT 사용시 폰트가 입혀진 텍스트가 갑자기 화면에 띄워진다. fade-in
애니메이션을 줘서 자연스럽게 띄워줄 수 있다.
fontfaceobserver
모듈을 활용해서 폰트 다운로드가 완료된 시점을 감지한다.
import FontFaceObserver from 'fontfaceobserver'
function BannerVideo() {
const [isFontLoaded, setIsFontLoaded] = useState(false)
const font = new FontFaceObserver('BMYEONSUNG')
useEffect(() => {
font.load().then(function() {
setIsFontLoaded(true)
})
}, [])
//...생략
return (
<div style={{opacity: isFontLoaded ? 1 : 0, transition: 'opacity 0.3s ease'}}>폰트있는글씨</div>
)
}
2) 폰트 용량 줄이기 - 용량 줄여서 빠르게 다운로드
- 웹폰트 포맷 사용
- 압축이 거의 안 된 TTF/OTF 대신 압축된 WOFF, WOFF2를 사용 | 용량: TTF/OTF > WOFF > WOFF2
- 폰트 변환기 ex) https://transfonter.org 사용해서 폰트 포맷 변경 가능
- woff2가 브라우저와 호환이 안되는 경우가 있을 수 있다. src에 각 포맷 폰트의 주소를 줘서 해결할 수 있다.
@font-face { font-family: hi; src; url('url') format('woff2'), url('url') format('woff'), url('url') format('truetype'); }
- local 폰트 사용
- 사용자 시스템에 설치되어 있는 폰트가 있을 경우 src에 추가해서 빠르게 사용할 수 있게 한다.
@font-face { font-family: hi; src; local('BMYEONSUNG'), url('url') format('woff2'), url('url') format('woff'), url('url') format('truetype'); }
- Subset 사용
- 폰트 파일은 각 글자마다 폰트 입혀진 글자가 각각 파일로 구성되어 있다.
- 사용하는 글자 수가 적을 경우 굳이 전체 폰트를 다운로드할 필요는 없다. 필요한 글자만 다운로드해주면 된다.
- 폰트 변환기 ex) https://transfonter.org 사용해서 Subset에 사용하는 글자 입력 후 변환해준다. 얘를 사용한다.
- Unicode Range 적용
- 폰트 사용하지 않는 페이지에서 불필요하게 폰트를 로드하는 것을 막기 위해 사용
- 지정된 unicode 범위에 대해서만 폰트를 적용, 글자 없으면 폰트 로딩하지 않음
@font-face { font-family: hi; unicode-range: U+0041; /* A */ }
- 유니코드 구하는 법
Array.prototype.map.call('ABCDEFGIKLMNOPR', c => 'u+' + ('0000' + c.charCodeAt(0).toString(16)).slice(-4)).join(', ')
- data-uri로 변환
- 폰트 사이즈가 작을 경우 페이지 자체에 폰트를 넣어서 한꺼번에 다운로드하도록 한다. (네트워크 리소스 절약) - 이미지에 사용한 것과 같음
- 폰트 변환기 ex) https://transfonter.org 사용해서 Base64 encode 켜주고 변환 -> css 파일
@font-face
src
부분을 확인해보면 이상한 글자들이 엄청 많이 있다. css파일에 폰트에 대한 데이터가 직접적으로 들어가게 된다. - 이 방법은 굳이 안 쓸 것 같다. css 파일이 알아보기가 너무 힘들어 진다. 그리고 커진다.
3) 폰트 Preload
폰트는 css읽는 순간 로드한다. 그 시점보다 먼저 폰트를 로드하도록 하는 방법
html 파일에 link 태그로 명시해준다.
빌드된 폰트 파일 주소를 href에 넣어야 한다.
<link rel="preload" href="./static/media/font.[hash].woff2" as="font" type="font/woff2" crossorigin>
이 방식은 매 빌드시마다 hash 값 달라지기 때문에 번거롭다.
웹팩 플러그인 추가해서 편하게 폰트 preload를 할 수 있다. preload-webpack-plugin
new PreloadWebpackPlugin({
rel: 'preload',
as: 'font',
include: 'allAssets',
fileWhitelist: [/(.woff2?)/i]
})
빌드 결과물 html을 확인해보면 모든 조건에 맞는 폰트들이 link태그에 들어가 있다.
'프론트엔드 > 성능 최적화' 카테고리의 다른 글
로딩 성능 최적화 - 텍스트 압축, 불필요한 CSS 제거 (0) | 2023.04.28 |
---|---|
로딩 성능 최적화 - 캐시 (0) | 2023.04.28 |
로딩 성능 최적화 - 프리 로딩 (0) | 2023.04.28 |
로딩 성능 최적화 - 코드 스플릿, 레이지 로딩 (0) | 2023.04.28 |
로딩 성능 최적화 - 이미지, 동영상 (0) | 2023.04.25 |