Skip to content

Commit

Permalink
웹 폰트 최적화 마무리
Browse files Browse the repository at this point in the history
  • Loading branch information
jihunhong committed Aug 22, 2022
1 parent c18e34a commit 8cd81ed
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 42 deletions.
136 changes: 96 additions & 40 deletions 웹 퍼포먼스 최적화/웹 폰트 최적화.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,54 +3,110 @@
- 강의에서는 750kb를 로드하는 동안 처음 페이지 랜더링시 로드 되는 1.5초동안 폰트가 적용되지 않은 상태로 보이는 문제가있다.

- 웹폰트의 경우 문제점이 두가지 있는데
- FOUT (Flash of Unstyled Text) : 폰트를 다운로드 하기전에는 기본폰트로 텍스트가 보여진 후 로드가 완료되면 적용된 모습으로 보이는 것
- `FOUT (Flash of Unstyled Text)` : 폰트를 다운로드 하기전에는 기본폰트로 텍스트가 보여진 후 로드가 완료되면 적용된 모습으로 보이는 것

- FOIT (Flash of Inivisible Text) : 폰트가 다운로드 되기전에는 보여지지 않다가 로드가 완료되면 보이는 것
- `FOIT (Flash of Inivisible Text)` : 폰트가 다운로드 되기전에는 보여지지 않다가 로드가 완료되면 보이는 것

- 두가지 폰트가 적용되는 방식은 브라우저마다 다른데 FOUT는 ie, edge이고 FOIT는 chrome, safari등에서 보여진다.

- 어느것이 나은지는 상황에 따라 다르기 때문에 궁극적으로는 최대한 폰트를 최적화할 필요가있다.

#### 어떻게 최적화 할 수 있을까

- 폰트 적용 시점 컨트롤 하기
- FOIT를 이용할 것인지, FOUT를 이용할지
- `font-display` **css**를 이용해 컨트롤한다.
- auto : 브라우저 기본 동작
- block : FOIT (timeout = 3s)
- timeout 초과시 기본 텍스트로 보여지며 다운로드 이후부터 텍스트가 깜빡이며 다운된 폰트로 보여진다
- swap : FOUT
- 로드를 기다리고 다운된 순간 깜빡이며 다운된 폰트로 보여진다
- fallback : FOIT (timeout = 0.1s)
- 3초 후에도 불러오지 못했을때, 기본폰트로 계속 보여진다 이후 캐싱 (다음번 로드는 좀더 빠르게 적용 될 수 있도록)
- 사용자에게 깜빡이는 텍스트를 보여주지 않기 위해 이용된다
- optional : FOIT (timeout = 0.1s)
- 네트워크 상태에 따라 기본폰트로 유지할시 웹폰트를 적용할지 결정한다. 이후 캐싱

- FOIT을 이용할때는 보이지 않는 텍스트가 보여지게 되는 순간 없던 요소가 바로 다음 프레임에 보여지기 때문에 어색할때가 있다. 이는 폰트의 다운로드 상태에 따라 `opacity` css를 바꿔주는 css를 사용하면 자연스럽게 보이게 할 수 있는데 `FontFaceObserver`를 npm 패키지를 이용한다.

```
const Sample = () => {
const [isFontLoaded, setIsFontLoaded] = useState(false);

const font = new FontFaceObserver('font-name');

useEffect(() => {
font.load().then(function() {
setIsFontLoaded(true);
})
}, []);

return (
<div style={{ opacity : isFontLoaded ? 1 : 0, transition: 'opacity 0.3s ease' }}>...</div>
)
};

```
##### # 폰트 적용 시점 컨트롤 하기

- FOIT를 이용할 것인지, FOUT를 이용할지
- `font-display` **css**를 이용해 컨트롤한다.
- auto : 브라우저 기본 동작
- block : FOIT (timeout = 3s)
- timeout 초과시 기본 텍스트로 보여지며 다운로드 이후부터 텍스트가 깜빡이며 다운된 폰트로 보여진다
- swap : FOUT
- 로드를 기다리고 다운된 순간 깜빡이며 다운된 폰트로 보여진다
- fallback : FOIT (timeout = 0.1s)
- 3초 후에도 불러오지 못했을때, 기본폰트로 계속 보여진다 이후 캐싱 (다음번 로드는 좀더 빠르게 적용 될 수 있도록)
- 사용자에게 깜빡이는 텍스트를 보여주지 않기 위해 이용된다
- optional : FOIT (timeout = 0.1s)
- 네트워크 상태에 따라 기본폰트로 유지할시 웹폰트를 적용할지 결정한다. 이후 캐싱

- FOIT을 이용할때는 보이지 않는 텍스트가 보여지게 되는 순간 없던 요소가 바로 다음 프레임에 보여지기 때문에 어색할때가 있다. 이는 폰트의 다운로드 상태에 따라 `opacity` css를 바꿔주는 css를 사용하면 자연스럽게 보이게 할 수 있는데 `FontFaceObserver`를 npm 패키지를 이용한다.

```
const Sample = () => {
const [isFontLoaded, setIsFontLoaded] = useState(false);
const font = new FontFaceObserver('font-name');
useEffect(() => {
font.load().then(function() {
setIsFontLoaded(true);
})
}, []);
return (
<div style={{ opacity : isFontLoaded ? 1 : 0, transition: 'opacity 0.3s ease' }}>...</div>
)
};
```

##### # 폰트 사이즈 줄이기

- 웹폰트 포맷 사용, local 폰트 사용
- TTF/OTF : pc에서 주로 이용하기 위해 압축없이 이용하는 포맷
- WOFF : TTF/OTF를 웹에서 사용하기 좋게끔 압축한 포맷
- WOFF2 : WOFF를 좀더 개선한 포맷
- EOT : 구 IE에서 지원했던 포맷, 현재는 모던 브라우저 모두 지원하지 않는다
**EOT, TTF/OTF는 대체적으로 2MB정도, WOFF는 1.3MB, WOFF2는 1MB나 KB단위로도 줄어든다**

[transfonter.org](https://transfonter.org)

```
@font-face {
font-family: fontname;
src: local('fontname') // 이미 이용자가 로컬에 다운받아져있다면 그것을 그대로 이용
url('./fontname.woff2') format('woff2),
url('./fontname.woff') format('woff),
url('./fontname.truetype') format('truetype')
// .ttf => truetype
font-display: block; // FOT
}
```

- Subset 사용
- 폰트 파일내에서는 수많은 글자 데이터를 갖고있는데 폰트를 적용하는 부분이 한정적이라면 사용하지 않는 데이터들이 낭비되기 때문에 transfer 과정에서 이용하는 문자만 분리하는 작업을 거친다면 다운로드 사이즈가 상당히 줄어들 수 있다.

- Unicode Range 적용
- Subset 에서 분리해낸 폰트 데이터들을 어느 문자들에만 적용할지를 결정할 수 있다.
- Subset에서 분리된 문자 이외의 부분에서 font를 로드한다면 불필요한 네트워크 로드가 발생 할수 있기 때문에 이용한다.
- 상위에서 지정된 font style의 네트워크 로드를 못하게 하기위해 이용한다고 할 수 있다.
- data-uri로 변환
- base64 encode를 통해 폰트에 대한 데이터를 css value안에 이용하는 방법
- 불러오는 데이터의 크기는 비슷하지만, css를 탐색한 뒤에 폰트를 로드하는것이 아니라, css를 탐색할때 폰트데이터도 포함된 방식을 이용한다면 시간, 네트워크를 조금이라도 절약 할 수 있다.

##### # 폰트 preload
- css가 로드되고 읽는 순간 이후에 폰트 로드가 발생하는데, 이 시점보다 전에 폰트를 로드하는 방식이다.

```
<link rel="preload" href="fontname.woff2" as="font" type="font/woff2" crossorigin>
```

[react-app-rewired](https://www.npmjs.com/package/react-app-rewired)

- webpack 설정을 통해 href에 위치하는 path를 빌드시에 hash값이 추가되는 값을 지정 할 수 있다.

[preload-webpack-plugin](https://www.npmjs.com/package/preload-webpack-plugin)

```
const PreloadWebpackPlugin = require('preload-webpack-plugin);
- 혼합해서 이용할지
module.exports = function override(config, env){
config.plugins.push(new PreloadWebpackPlugin({
rel: 'preload',
as: 'font',
include: 'allAssets',
fileWhitelist: [/(.woff2?)/i]
}));
- 폰트 사이즈 줄이기
- 다운로드 용량 줄이기
return config;
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
jpg는 png에 비해 품질이 좀 떨어지지만 용량이 적어서 투명을 이용하지 않는 이미지는 jpg를 이용하는 경우가 많다.
webp는 구글에서 개발한 이미지 포멧으로 jpg보다 나은 화질과 용량을 차지한다.

![squoosh](https://squoosh.app/)
[squoosh](https://squoosh.app/)

강의에서 보여진 예시로는

Expand All @@ -14,7 +14,7 @@ webp는 구글에서 개발한 이미지 포멧으로 jpg보다 나은 화질과

webp는 지원하지 않는 브라우저도 있기 때문에 jpg와 webp중 어느것을 이용할지 처리가 필요하다.

![<picture>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture) 태그를 이용하는데
[picture](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture) 태그를 이용하는데

```html
<picture>
Expand Down

0 comments on commit 8cd81ed

Please sign in to comment.