2023. 10. 4. 18:54ㆍ개인노트-인강
The RED 견고한 UI 설계를 위한 마크업
Part 3. Performance
02. 덩어리 콘텐츠 빨리 그리기
# 덩어리 콘텐츠 빨리 그리기
- LCP(Largest Contentful Paint)는 구글의 성능지표에 포함되는 한 가지 항목이다.
- LCP를 좋아지게 하기 위해서는 우리들이 알고있는 성능에 관한 모든 지식을 총 동원해서 이 부분에 집약해서 적용해야만, LCP의 문제를 해결할 수 있습니다.
- 구글은 핵심 성능 지표에 해당하는 LCP를 구글 검색 결과 순위에 반영하겠다고 발표했다.
- 우리의 목표는 LCP 점수를 2.5초 이내로 단축시키는 것이다. 가장 큰 덩어리 콘텐츠를 2.5초 이내로 로딩시켜야만 사용자에게 좋은 사용자 경험을 줄 수 있다.
## Core Web Vitals
- 핵심 성능 지표를 측정하는 많은 다양한 도구들이 있다. 그 중에서 lighthouse를 추천한다.
## LCP (가장 큰 덩어리 콘텐츠)
- 대부분의 웹사이트에서 뷰포트 초기화면에 보이는 덩어리 콘텐츠는 이미지일 확률이 높다. 이 요소가 늦게 로딩되는 이유는 이미지가 무겁기 때문만은 아니다. 여러가지 원인 중 한가지일 뿐이다. 이 이미지를 그리기 전에 나타나는 모든 과정들의 성능을 개선해야만 LCP 성능을 개선할 수 있다.
- 이미지를 표시하기 전 발생하는 모든 성능 이슈가 LCP문제를 해결하는 열쇠이다.
## LCP 개선 사례 (LCP 3.6초 단축한 이야기)
### 라이브러리 의존 줄이기 (jquery, lodash, normalize...)
- jquery가 FCP를 상당히 지연시키고 있다. jquery를 제거할 수 있다면 제거하는 것을 추천한다.
- 사이트 추천 : https://youmightnotneed.com/ jquery나 lodash 대신 사용할 수 있는 바닐라 스크립트를 찾아볼 수 있다. 이 것을 사용해서 javascript 라이브러리를 제거하는데 도움을 받을 수 있다.
### Remove unused CSS
<head>
<!-- <link rel="stylesheet" href="normalize.css"> -->
</head>
- normalize나 reset과 같이 잘 사용하지 않거나 필요하지 않은 stylesheet 들을 과감하게 버리자.
### Preconnect / Preload 기법
- 아래는 일반적으로 css코드를 참조하는 방법.
<head>
<link rel="stylesheet" href="*.css"> <!-- css를 로딩하고 해석하는 동안 웹 페이지가 차단된다. -->
</head>
- 아래처럼 수정하자.
<head>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link rel="preload" as="style" href="*.css" onload="this.onload=null;this.rel='stylesheet'">
</head>
- preconnect 란 값은 href에 적힌 url을 미리 연결하는 기능이다.
- 미리 연결하여 준비하고 있다가 필요한 내용을 다운로드 받을 수 있게 도와준다.
- preload를 사용하면 css파일을 다운로드하면서 웹페이지 렌더링을 방해하지 않고, 웹 페이지를 렌더링하는 동시에 css 파일을 다운로드하게 되어 있다.
- 그리고 onload script를 이용하여 css 다운로드가 끝나면 preload 값을 stylesheet로 바꿔서 stylesheet를 웹페이지에 적용하게 된다. 즉, 지양적용이다.
<정리>
<link rel="preconnect">
- 도메인을 알지만 자원의 최종 경로를 모르는 경우 서버와의 연결을 미리 설정.
- DNS(Domain Name Server), TCP(Transmission Control Protocol), TLS(Transfer Layer Security) 왕복에 필요한 시간을 단축.
- 서드 파티 자원 연결에 적합. preconnect를 구글 웹폰트를 참조하고 load 하는데 사용하고 있다.
<link rel="preload">
- 필요한 자원을 병렬 다운로드.
- 자원을 로딩하는 동안 렌더링을 차단하지 않음.
- as 속성을 함께 명시해 주어야 정상적으로 동작한다. 예) as="style", as="script", as="image".
- css 뿐만 아니라 이미지, 스크립트 등 다양한 파일들을 병행로딩할 수 있다.
### 히어로 이미지 preload
- 히어로 이미지를 미리 로딩하는 기법
- 원래 이미지는 html body 요소 안쪽에 마크업이 되어있지만, 첫번째 히어로 이미지를 빨리 로딩하기 위해서 html head에서 미리 로딩을 한다.
<head>
<link
rel="preload" as="image"
media="(max-width:640px)" href="small.avif">
<link
rel="preload" as="image"
media="(min-width:641px)" href="large.avif">
</head>
- 해상도가 640px 보다 같거나 작은 환경에서 "small.avif" 이미지를 미리 로딩한다.
- 해상도가 641px 과 같거나 크면 태블릿이나 데스크탑 해상도에서는 "large.avif" 이미지를 미리 다운로드 받는다.
### Feature detection
- Image type 이나 Viewport width 를 감지해서 성능을 개선하는 방법이다.
- 우리가 일반적으로 사용하는 방법은 아래와 같다.
<!-- UNOPTIMIZED HERO IMAGE (이미지최적화가 되어있지 않음)-->
<img src="large.jpg" alt>
- 이미지 회적화를 한다면 아래처럼 할 수 있다.
<!-- OPTIMIZED HERO IMAGE -->
<picture>
<!-- AVIF && SMALL SCREEN -->
<source srcset="small.avif" type="image/avif" media="(max-width:640px)">
<!-- AVIF && LARGE SCREEN -->
<source srcset="large.avif" type="image/avif">
<!-- WEBP && SMALL SCREEN -->
<source srcset="small.webp" type="image/webp" media="(max-width:640px)">
<!-- WEBP && LARGE SCREEN -->
<source srcset="large.webp" type="image/webp">
<!-- FALLBACK -->
<img src="small.jpg" alt>
</picture>
- type 과 media라는 조건 구문을 붙여야 한다.
- 조건 : avif 타입을 지원하면서 동시에 640px 이하이면 small.avif 이미지를 출력한다. -> 이 조건이 충족된다면 <img src="small.jpg" alt> 에 small.avif를 표시하게 된다. 실행하게 되면, 나머지 요소들은 다운로드하거나 화면에 표시하지 않게 된다.
### Image Loading / Decoding
- 앞으로는 loading과 decoding 속성을 명시하는 것을 추천한다.
<!-- 최적화되지 않은 이미지 사용법 (unoptimized image) -->
<img src="example.jpg" alt>
<!-- 최적화된 이미지 (optimized image) -->
<img
src="example.jpg"
loading="lazy"
decoding="async"
alt>
- loading="lazy"을 사용하면 뷰포트안에 들어와있지 않으면 이미지를 loading 하지 않는다. 페이지가 로딩되고, 화면 아래쪽에 있는 이미지들은 로딩되지 않은 상태로 존재하다가 사용자가 scroll 하면서 페이지 문서가 뷰포트 안쪽으로 들어올때, 모니터 뷰 포트 높이의 1배에서 2배 크기 아래쪽 부터 이미지가 로딩되기 시작해서 그 때 화면에 표시할 준비를 한다. 이것을 lazy load 기법이라고 한다. javascript를 사용하지 않고도 이미지 지연 로딩을 할 수 있다.
- decoding="async" decoding은 암호화했던 이미지를 복호화하는 방법이다. 복호화 방법으로 async 라는 값을 사용하면 화면에 다른 요소를 렌더링 하는 것을 중단하지 않고 다른 요소를 먼저 표시하고 이미지를 뒤늦게(지연해서) 화면에 표시하게 해준다.
- 이 두가지 옵션을 사용하면 가능한 다른 요소들이 빠르게 화면에 표시되기 때문에 이미지 최적화에 매우 큰 도움이 된다.
- loading 과 decoding 이라는 속성은 img속성에만 사용한다. picture나 source 요소에는 loading 과 decoding 속성을 사용하지 않아도 된다.
## 정리
1. LCP는 뷰포트에 표시하는 가장 큰 콘텐츠 렌더링 성능.
2. 가장 큰 덩어리 콘텐츠를 2.5초 이내로 표시해야 한다.
3. JS/CSS 라이브러리 의존도를 낮추어야 한다.
4. preconnect/preload 속성으로 외부 자원 최적화.
5. photo 요소의 type, media 속성으로 이미지 전송량 최적화.
6. loading/decoding 속성으로 이미지 렌더링 최적화.
'개인노트-인강' 카테고리의 다른 글
개인 노트 정리) 마크업19 - 웹 접근성 오류 유형 12개 리뷰 (1) | 2023.10.15 |
---|---|
개인 노트 정리) 마크업18 - 덜컥덜컥 누적 배치 변경 문제 (0) | 2023.10.10 |
개인 노트 정리) 마크업16 - CSS 코드 최적화 (0) | 2023.09.22 |
개인 노트 정리) 마크업15 - 포토샵 닫고 CSS 열기 (0) | 2023.09.19 |
개인 노트 정리) 마크업14 - 코드는 짧고 사연은 길다 (0) | 2023.09.18 |