안녕하세요 메이토입니다 🍅 요즘 기술 블로그 글을 쓸 주제가 굉장히 많아서 기분이 좋네요 ! 제가 그만큼 모르는 것들이 많이 발견되고 있어서가 아닐까 싶기도 한데, 배운걸 기록하면서 정말 많이 배우는 것 같습니다.
혹시 여러분, 우아한 낮춤에 대해서 들어보신적 있으신가요 ?
우아한 낮춤(Graceful Degradation), 우아한 성능저하는 최신 브라우저에서 동작하는 웹사이트 구축에 주력하되 오래된 브라우저에서 좋지 않은 경험이라도 필수 컨텐츠 등을 제공하는 설계 철학입니다.
우아한 성능 저하 _ mdn ▼
우아한 낮춤을 공부하던 중, 최적화를 위해 했던 프로젝트(성능 개선 프로젝트)에 마침 우아한 낮춤의 좋은 예👍 와 좋지 않은 예 👎가 둘 다 있어 한번 살펴보고자 합니다.
좋은 예 👍
최적화를 위해 gif를 mp4로 변경하게 되었는데 이유는 gif 보다 mp4형태로 했을 때 압축률이 높고 품질 손실이 적기 때문이었습니다. 하지만, 일부 환경에서는 재생이 실패되기도 하는데, 실패될 경우를 대비하여 img 태그 등의 방식으로 fallback을 제공할 것을 권장하고 있습니다.
const GifItem = React.memo(({ imageUrl = '', title = '' }: GifItemProps) => {
const isVideo = imageUrl.includes('.mp4');
const thumbnail = imageUrl.replace('.mp4', '.jpg');
return (
<div className={styles.gifItem}>
{isVideo ? (
<video className={styles.gifImage} preload="metadata" autoPlay loop muted playsInline>
<source src={imageUrl} type="video/mp4" />
<img src={thumbnail} alt={title} />
</video>
) : (
<img className={styles.gifImage} src={imageUrl} />
)}
<div className={styles.gifTitleContainer}>
<div className={styles.gifTitleBg}></div>
<h4 className={styles.gifTitle}>{title}</h4>
</div>
</div>
);
});
위 코드를 보시면 최신 브라우저 (mp4를 지원하는 브라우저) 를 위해서 video 태그를 위해 .mp4 형태의 요소를 재생할 수 있도록 처리해두었습니다. 단, video 를 지원하지 않는 경우에는 img 태그로 대체 이미지를 표시하였습니다. 이를 통해 video가 재생되지 않더라도 이미지를 볼 수 있도록 구현했다는 점에서 우아한 낮춤이라고 볼 수 있습니다 !
Content may be provided inside the video element. User agents should not show this content to the user; it is intended for older web browsers which do not support video, so that text can be shown to the users of these older browsers informing them of how to access the video contents.
출처: https://html.spec.whatwg.org/multipage/media.html#the-video-element
Web 표준 명세에 따르면 "video 태그 내부에 있는 요소는 video 태그를 지원하지 않는 구형 브라우저에게 보여주기 위한 부분이므로 뭔가 내용이 제공되어야 한다." 라고 이야기 하고 있습니다. 이때 단순히 썸네일을 보여주거나, 혹은 a 태그를 통해 아예 영상을 다운로드할 수 있도록 제공하는 방법도 있을 것 같습니다.
좋지 않은 예 👎
반면에,, 최적화만 신경쓰느라 이러한 fallback을 제공하지 못한 예시도 있었습니다. 이미지를 최적화하려면 webp 혹은 avif로 확장자를 변경하면 된다. 라는 사실은 다들 알고 계셨을 텐데, 과연 그 두 포맷이 구형 브라우저도 지원할까요?
webp
- jpeg 를 대체하기 위한 이미지 포맷
- 손실 압축 방식으로 jpeg 보다 용량이 작고 품질 손실이 적음
🖼 WebP 지원 시작 버전
- Chrome (데스크탑) 17버전부터 기본적인 WebP 지원 시작.
- Firefox 65버전부터 지원.
- Edge 18버전부터 지원.
- Safari (macOS/iOS)에서는 Safari 14버전 (iOS 14 포함)부터 WebP 지원됨.
avif
- webp 보다 더 최신 이미지 포맷
- HEIF(고효율 이미지 형식) 기반이라 압축 효율이 훨씬 높음
- 동일 화질 기준으로 WebP보다도 더 작은 파일 크기
🌈 AVIF 지원 시작 버전
- Chrome 데스크탑에서는 버전 85부터 본격적인 AVIF 지원.
- Firefox 데스크탑에서는 버전 93부터 기본 지원.
- Safari에서는 macOS/iOS에서 버전 16쯤부터 AVIF 지원됨.
- Edge에서는 비교적 최근에 (버전 121 등) 지원이 본격화됨.
import heroImage from '../../assets/images/hero.webp';
// 중략
<img className={styles.heroImage} src={heroImage} alt="hero image" loading="eager" />
위 코드를 보면, hero.webp는 일부 구형 브라우저에서는 해석이 불가능한 경우가 될텐데,, 이때 아무 fallback 이 없다 보니 빈 화면 혹은 깨진 이미지 아이콘이 뜨게 됩니다. 이럴 때 해결하기 좋은 방법이 바로 picture 태그입니다.
<picture>
<source srcSet="/images/hero.avif" type="image/avif" />
<source srcSet="/images/hero.webp" type="image/webp" />
<img src="/images/hero.jpg" alt="hero image" loading="eager" />
</picture>
1️⃣ 브라우저가 avif를 지원하면 → AVIF 로드
2️⃣ 지원 안 하지만 webp는 지원하면 → WebP 로드
3️⃣ 둘 다 안 되면 → 마지막 img(JPEG 등)로 fallback
이번에 우아한 낮춤을 공부하면서,
단순히 최신 기술을 적용하는 것만이 좋은 프론트엔드 개발이 아니라는 걸 새삼 느꼈습니다.
결국 “모든 사용자가 최소한의 경험이라도 잃지 않도록 만드는 것” — 그게 진짜 사용자 중심의 개발이 아닐까 싶습니다.
우리는 종종 “최적화”라는 단어에 매몰되어 최신 포맷, 최신 API, 최신 기술만을 쫓지만,
진정한 완성도는 깨져도 괜찮은 웹을 만드는 데서 시작한다고 생각합니다 🌿
'궁금증 해결소' 카테고리의 다른 글
| [라이브러리 개발 일기] Stylelint 가 어떻게 하드코딩을 막을까? (0) | 2026.03.21 |
|---|---|
| [라이브러리 개발 일기] 디자인 시스템 컨벤션 좀 지켜 !! - 1 (1) | 2026.01.06 |
| 프론트 개발자가 바라보는 멱등성🔥 (0) | 2025.10.17 |
| TroubleShoot Ep.1 험난했던 빌드 오류 해결의 과정.. (2) | 2025.01.22 |
| [자바스크립트] 정적 메서드, 인스턴스 메서드 뭐가 달라? (3) | 2024.11.30 |