내 블로그가 더 빨라졌습니다: Cloudflare Workers와 AVIF 지원

이 웹사이트가 빠르다고 말했던가요? 아, 맞다. 말했었죠. 여러 번이나요.
그럴 만한 이유는 다음과 같습니다. (평범한 이유부터 살짝 제정신이 아닌 수준의 이유까지요.)
- 📄 정적 사이트
- ☁️ Cloudflare CDN에 캐시됨
- 🔗 ️HTTP/2 및 HTTP/3 지원
- 🚫 웹 폰트 없음 (슬프게도)
- ✅ 엣지 워커로 구동되는 분석 기능 (Google Analytics 없음)
- 🌸 가능한 한 JavaScript를 사용하지 않음. 제가 필요한 기능의 90%는 CSS로 해결됩니다.
- 🖼️ 페이지 리플로를 방지하기 위해 HTML에 이미지 너비와 높이를 지정함
- 👍🏻 인라인 처리한 최적화 SVG 그래픽과 직접 작성한 CSS
- 🚅 정적 WASM 검색 (지연 로드)
- 🏎️ 그래픽을 포함한 홈페이지 전체 용량이 10KB 미만입니다( Brotli 압축 기준). 따라서 첫 번째 HTTP 왕복 안에 전부 들어갈 수 있습니다.
- 💟 심지어 파비콘도 용량을 줄이도록 최적화했습니다. 업데이트: 이제는 이 글 덕분에 SVG 아이콘을 사용합니다.
하지만 2020년이잖아요. 모두가 파비콘을 최적화하고 있죠? …그렇죠!?
그런데 알고 보니 다른 사이트 대부분은 저만큼 사용자의 데이터 요금제를 신경 쓰지 않더군요. 아니, 이건 너무 완곡한 표현입니다. 전혀 신경 쓰지 않습니다. 하지만 저에게는 가벼운 것이 아름답습니다!
잠깐, 이미지는요?
다이어그램과 일러스트에는 SVG를 선호합니다. 사진일 때만 JPEG나 WebP를 사용합니다.
솔직히 말하면 WebP는 예전부터 그다지 좋아하지 않았습니다. 요지는 MozJPEG로 압축한 JPEG보다 작지 않을 수도 있다는 겁니다. 더 알고 싶다면 Mozilla 버그 트래커의 긴 논쟁을 읽어보세요. 지금까지도 Safari는 WebP를 지원하지 않습니다.
AVIF를 만나보세요 👋
새로운 차세대 이미지 압축 형식인 AVIF를 소개합니다. 이걸 보세요.
이미 Chrome 85와 Firefox 80에서 지원됩니다.
그때 저는 마치 허리케인에 얻어맞은 듯 깨달았습니다 🌪️:
😲 세상에, 이제 AVIF를 주요 브라우저에서 지원한다고!?
내 블로그에도 이걸 쓰고 싶어!
맞기도 하고 아니기도 합니다.
저는 블로그에 Zola를 사용하고 있는데, 아직 Zola의 AVIF 지원은 없습니다. 하지만 지금 당장 필요합니다! 그래서 예전 JPEG와 PNG 이미지로 AVIF 이미지를 만들어주는 볼품없는 Rust 스크립트를 뚝딱 만들었습니다. 혹시 모르니 원본 파일은 그대로 보관하고 있습니다.
내부적으로는 Kornel Lesiński가 만든 cavif를 호출합니다.
데이터 절약
블로그에 AVIF를 적용한 결과는 정말 인상적이었습니다.
브라우저를 확인해 보세요
그런데 잠깐만요… 여러분의 브라우저는 정말 AVIF를 표시할 수 있나요?

“응”이라고 표시된다면 준비가 끝난 겁니다.
“아니”라고 표시된다면 몇 가지 방법이 있습니다.
- Firefox에서는: 주소 표시줄에
about:config를 입력하고avif를 검색하세요. - Chrome에서는: 최신 버전으로 업데이트했는지 확인하세요.
- Safari에서는: 지금 무슨 인생을 살고 계신 건지 모르겠네요. 대신 진짜 브라우저를 써보세요. 😏
우회 방법 I: 오래된 브라우저를 위한 대체 이미지
HTML이 훌륭한 이유는 브라우저가 새로 추가된 문법을 모르면 그냥 무시한다는 점입니다. 따라서 <picture> 요소를 사용해 각 브라우저에 맞는 형식을 제공할 수 있습니다. (보세요, JavaScript가 하나도 없습니다!)
<picture>
<source srcset="fancy_browser.avif" />
<source srcset="decent_browser.webp" />
<img src="meh_browser.jpg" />
</picture>실제 코드는 조금 더 복잡하지만, 어떤 방식인지 감은 오실 겁니다.
우회 방법 II: Github Pages의 잘못된 Content-Type
그런데 Github와 AVIF를 함께 사용할 때 한 가지 골치 아픈 문제가 있었습니다. 서버가 Content-Type: application/octet-stream 헤더를 반환한 것입니다.
그 때문에 Firefox에서는 이미지가 로드되지 않았습니다.
Github가 제 페이지를 호스팅하고 있으니 제 쪽에서 고칠 방법은 없었습니다. 지금까지는요! 예전부터 Cloudflare의 Workers Sites를 써보고 싶었는데, 이 버그 덕분에 마침내 옮기게 됐습니다. 기본적으로 전체 웹사이트를 CDN 위의 엣지 워커에서 바로 실행하는 방식입니다. 자체 웹 서버가 필요하지 않습니다. 가장 좋은 점은 이제 사이트가 어디서나 빠르다는 것입니다. 외딴 지역에서도요. 더 이상 서버까지 왕복할 필요가 없습니다.
엣지 워커를 실행하면서 요청 및 응답 객체를 완전히 제어할 수 있게 되었습니다. 워커의 응답을 가로채기 위해 이 보석 같은 코드를 추가했습니다.
if (/\.avif$/.test(url)) {
response.headers.set("Content-Type", "image/avif");
response.headers.set("Content-Disposition", "inline");
}자, 끝입니다. Firefox도 만족합니다. 응답 객체 수정에 관한 내용은 여기에서 더 읽을 수 있습니다.
Workers Sites를 사용하면서 생긴 또 다른 부수 효과는 이제 프로덕션 배포에 1분밖에 걸리지 않는다는 것입니다.
Cloudflare로 옮긴 뒤의 성능 결과

출처: KeyCDN

출처: KeyCDN

출처: Pingdom.com

출처: Pingdom.com
유명한 사이트들과 비교해도 전혀 꿀릴 게 없습니다.

출처: Speedcurve
더 읽어볼 만한 자료
- AVIF 사용법: 새로운 차세대 이미지 압축 형식 — AVIF를 통합할 때 흔히 겪는 문제를 짚어주는 좋은 입문 글입니다. 이 글을 읽고 AVIF 지원을 추가하게 됐습니다.
- AVIF가 도착했다, Jake Archibald — SVG, JPEG, PNG, WebP, AVIF 등 여러 형식의 이미지 크기와 품질을 비교합니다.
- avif.io — 데스크톱과 모바일에서 작동하는 빠르고 설정 가능한 클라이언트 측 이미지 압축 도구입니다.
- Squoosh — AVIF를 지원하는 WebAssembly 기반의 또 다른 이미지 압축 서비스입니다.
- Cloudflare workers 설정 방법을 보여주는 훌륭한 예제 모음
- Cloudflare Workers Sites
글을 무작위로 읽기