Safari 26.3 — Zstandard 압축과 Navigation API가 온다
Safari 업데이트가 나올 때마다 프론트엔드 개발자가 제일 먼저 확인하는 건 "이번에는 뭘 고쳤나"다. Chrome과 Firefox에서 잘 되던 기능이 Safari에서만 안 되는 경험이 쌓여 있기 때문이다. Safari 26.3은 새 기능 2개와 CSS 버그 수정 다발을 가져왔다. 새 기능 중 Zstandard 압축은 성능 측면에서, Navigation API AbortSignal은 SPA 개발 편의성 측면에서 주목할 만하다.
Zstandard 콘텐츠 인코딩
Safari 26.3부터 서버가 Content-Encoding: zstd 헤더로 응답을 보내면 브라우저가 자동으로 압축 해제한다. HTML, CSS, JavaScript, JSON, SVG 등 텍스트 기반 에셋에 모두 적용할 수 있다.
| 압축 방식 | 압축률 | 압축 해제 속도 | Safari 지원 |
|---|---|---|---|
| gzip | 보통 | 보통 | 오래 전부터 |
| Brotli | 높음 | 보통 | Safari 11+ |
| Zstandard | 높음 | 매우 빠름 | Safari 26.3+ |
Zstandard(줄여서 zstd)의 핵심 장점은 압축 해제 속도다. Brotli와 비슷한 수준으로 압축하면서도 해제 속도가 훨씬 빠르다. 비유하면 Brotli가 "빽빽하게 짐을 잘 싸지만 풀 때 시간이 걸리는 짐꾼"이라면, Zstandard는 "같은 수준으로 싸면서도 순식간에 풀어내는 짐꾼"이다.
또 하나의 장점은 실시간 압축(on-the-fly compression) 지원이다. Brotli의 최고 압축 레벨은 사전 압축(static compression)에 적합하지만 실시간 응답에는 느리다. Zstandard는 낮은 레벨에서도 gzip보다 나은 압축률을 보여서 동적 API 응답에도 실용적이다.
[💡 잠깐! 이 용어는?]
Zstandard(zstd): Facebook(현 Meta)이 개발한 실시간 압축 알고리즘이다. RFC 8878로 표준화되어 있으며, zstd CLI 도구로 파일을 압축할 수 있다. Linux 커널, 데이터베이스 등에서 이미 널리 사용되고 있다.
서버 설정
Nginx에서 Zstandard를 활성화하는 설정은 아래와 같다.
http {
zstd on;
zstd_min_length 256;
zstd_comp_level 3;
zstd_types text/html text/css application/javascript application/json image/svg+xml;
}주의할 점은 Nginx 기본 빌드에는 zstd 모듈이 포함되어 있지 않다는 것이다. ngx_http_zstd_module을 별도로 빌드해야 한다. CDN을 사용한다면 Cloudflare는 이미 zstd를 지원하고 있고, 다른 CDN들도 순차적으로 지원을 추가하고 있다.
Navigation API — AbortSignal 지원
SPA(Single Page Application)에서 페이지 전환 시 진행 중인 네트워크 요청을 취소하는 건 오래된 문제다. 사용자가 A 페이지 데이터를 로딩하는 중에 B 페이지로 이동하면, A 페이지의 요청은 쓸모가 없어진다. 하지만 취소하지 않으면 응답이 돌아와서 잘못된 데이터를 렌더링하거나 메모리가 누수된다.
Safari 26.3은 Navigation API의 NavigateEvent에 AbortSignal을 노출한다.
navigation.addEventListener('navigate', (event) => {
event.intercept({
async handler() {
const response = await fetch('/api/page-data', {
signal: event.signal,
});
const data = await response.json();
renderContent(data);
},
});
});event.signal이 핵심이다. 사용자가 중간에 다른 페이지로 이동하면 이 시그널이 자동으로 abort 상태가 되고, fetch가 즉시 취소된다. 비유하면 택배 기사가 배달 중에 "주문 취소"가 들어오면 바로 유턴하는 것과 같다. 기존에는 AbortController를 직접 만들고 네비게이션 이벤트마다 수동으로 abort()를 호출해야 했다.
[💡 잠깐! 이 용어는?]
Navigation API: SPA의 클라이언트 사이드 라우팅을 브라우저 수준에서 관리하는 Web API다. window.navigation 객체를 통해 네비게이션 이벤트를 가로채고(intercept), 브라우저 히스토리를 제어할 수 있다.
CSS 버그 수정
Safari 26.3의 진짜 볼거리는 새 기능보다 버그 수정 목록일 수 있다. 특히 CSS Anchor Positioning 관련 수정이 여러 건 포함됐다.
| 수정 내용 | 영향 범위 |
|---|---|
position-try + display: none 조상 → 스타일 해석 무한 루프 | Anchor Positioning |
| 앵커 위치 요소의 애니메이션 중 위치 점프 | Anchor Positioning |
position-area + 스크롤 가능한 컨테이닝 블록에서 fixed 위치 계산 오류 | Anchor Positioning |
text-decoration: underline + text-box-trim 높이 렌더링 | 텍스트 장식 |
widows + text-indent가 적용된 다단 레이아웃 | Multi-column |
move, all-scroll, ew-resize, ns-resize 커서 미표시 | 커서 |
Anchor Positioning 버그가 3건이나 수정된 것은 이 기능이 아직 안정화 단계라는 의미다. Interop 2026 집중 영역에 Anchor Positioning이 포함된 이유이기도 하다.
프론트엔드 개발자에게 의미하는 것
Safari 26.3의 변경 사항을 현실적으로 정리하면 이렇다.
| 변경 사항 | 당장 활용 가능? | 조건 |
|---|---|---|
| Zstandard 압축 | 서버/CDN 설정 필요 | 서버에 zstd 모듈 설치, 또는 CDN 지원 확인 |
| Navigation API AbortSignal | SPA 프레임워크 업데이트 필요 | React Router, Vue Router 등의 지원 대기 |
| CSS 버그 수정 | 즉시 혜택 | Safari 업데이트만으로 기존 문제 해소 |
CSS 버그 수정은 별도 작업 없이 Safari 업데이트만으로 자동 적용된다. "사파리에서 이거 깨지는데요" 이슈 리스트에서 몇 개가 사라질 수 있다. Zstandard는 서버 측 설정이 필요하지만, 이미 Chrome과 Firefox가 zstd를 지원하고 있었으므로 Safari 26.3 추가로 3대 브라우저 모두 지원 상태가 됐다. 서버에 zstd를 설정할 이유가 충분해진 셈이다.
정리
- Safari 26.3은 Zstandard 콘텐츠 인코딩을 지원해 3대 브라우저 모두에서 zstd 사용이 가능해졌다
- Navigation API AbortSignal로 SPA에서 네비게이션 중 요청 자동 취소가 가능해졌다
- CSS Anchor Positioning 관련 버그 3건 포함, 다수의 렌더링 버그가 수정됐다
- Zstandard는 Brotli 수준의 압축률에 더 빠른 해제 속도를 제공해 동적 응답에도 실용적이다
참고:
- WebKit Blog: https://webkit.org/blog/17798/webkit-features-for-safari-26-3/
- Zstandard RFC 8878: https://datatracker.ietf.org/doc/html/rfc8878
- Navigation API MDN: https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API
관심 있을 만한 포스트
AI 코딩의 맹점 — Artifacts 없이 에이전트는 기억을 잃는다
PRD, ADR, TDD가 AI 코딩 워크플로우에서 왜 선택이 아닌 필수인지, 실전 구조와 함께 살펴본다.
Next-Translate 3.0 — Turbopack과 App Router를 위한 i18n 재건
1년간 공백 후 돌아온 Next-Translate 3.0이 Turbopack 지원, 비동기 params, App Router 안정화를 한 번에 처리하는 방법.
V8 WasmGC 투기적 최적화 — 가상 메서드를 인라인으로 만드는 법
V8이 WasmGC의 가상 메서드 디스패치에 투기적 인라이닝을 도입해 Dart와 Java 앱에서 최대 8% 성능을 끌어낸 방법.
Vinext — Vite 위에서 Next.js를 1주일 만에 다시 만든 이야기
Cloudflare가 AI와 함께 단 일주일, $1,100의 API 비용으로 Next.js 호환 프레임워크를 Vite 위에 구축한 과정.
Tsonic — TypeScript를 네이티브 바이너리로 컴파일하는 실험
TypeScript → C# → NativeAOT 파이프라인으로 네이티브 실행 파일을 만드는 Tsonic. 어떻게 동작하고, 어떤 한계가 있는지 살펴봤다.
VS Code 팀의 AI 에이전트 병렬화 — 월간 릴리스를 주간으로 만든 워크플로우
VS Code 팀이 월간 릴리스에서 주간 릴리스로 전환한 비결. 에이전트 세션 병렬화, 자동화 파이프라인, 품질 게이트 설계 전반을 공개했다.
React Compiler의 한계 — 뭘 최적화하고 뭘 못 하는가
React Compiler가 자동 메모이제이션으로 해결하는 것과 해결하지 못하는 것. 컴파일러 기반 UI 프레임워크의 능력 경계를 정리했다.
Native JSON Modules — 번들러 없이 JSON을 import하는 시대
Import Attributes와 함께 표준이 된 native JSON module. 어떻게 동작하고, 기존 번들러 방식과 뭐가 다른지 정리했다.