> [!quote] > [이제 모던 CSS가 SPA를 끝낼 때입니다](https://devowen.com/524/)를 읽고 배운 것과 생각을 정리했습니다. (원문: [It’s time for modern CSS to kill the SPA](https://www.jonoalderson.com/conjecture/its-time-for-modern-css-to-kill-the-spa/)) 프론트엔드 개발에서 중요한 것은 사용자에게 매끄러운 UX를 제공하는 것이다. 지금까지는 그것을 실현하기 위한 방법이 SPA만 존재한다는 분위기였던 것 같다. 실제로도 MPA는 매번 화면 전환마다 화이트스크린이 뜨고, 화면이 번쩍이고... 그러니까 당연히 SPA를 써야 한다고 생각했던 것이다. 하지만 생각해보면 SPA도 그렇게 매끄럽지는 않다. 컴포넌트 리하이드레이트를 기다리면서 화면이 멈추거나 지연되고, 레이아웃 시프트도 발생하고, 페이지 성능이 오롯이 클라이언트 성능에 기대기 때문에 성능 저하도 있다. 이런 SPA의 문제를 해결하기 위해 JS 모듈들로 최적화를 많이 하는데, 사실 그마저도 성능에 악영향을 끼친다. 그런데, 우리가 JS만으로 모든 문제를 해결하려는 동안 모던 브라우저는 네이티브 기능으로 이런 문제를 해결할 수 있도록 무럭무럭 발전하고 있었다. 이 아티클에서 소개하는 **View Transitions API**와 **Speculation Rules**가 바로 그것이다. ## View Transitions API 페이지 간 전환에서 발생하는 버벅임을 부드럽게 만들어주는 API다. 크게 두 가지 방식으로 쓸 수 있다. **Same-document** (SPA용): 한 페이지 안에서 DOM 상태가 바뀔 때 전환 애니메이션을 적용한다. ```js document.startViewTransition(() => { // DOM 업데이트 document.body.classList.toggle('dark-mode'); }); ``` **Cross-document** (MPA용): 페이지 간 이동 시 전환 애니메이션을 적용한다. JS 없이 CSS만으로 가능하다. ```css @view-transition { navigation: auto; } ::view-transition-old(root), ::view-transition-new(root) { animation: fade 0.3s ease both; } @keyframes fade { from { opacity: 0; } to { opacity: 1; } } ``` `view-transition-name`을 이용하면 특정 요소끼리 연결해서 애니메이션할 수도 있다. 예를 들어 목록 페이지의 썸네일이 상세 페이지의 이미지로 자연스럽게 이어지는 효과를 낼 수 있다. ### 브라우저 지원 현황 | | Same-document | Cross-document | |---|---|---| | Chrome | ✅ 111+ | ✅ 126+ | | Edge | ✅ 111+ | ✅ 126+ | | Safari | ✅ 18+ | ✅ 18.2+ | | Firefox | ✅ 144+ | ❌ 미지원 | Same-document는 2025년 기준 Baseline Newly Available. Cross-document는 Firefox가 아직 미지원이다. ## Speculation Rules 링크를 클릭하기 전에 브라우저가 페이지를 미리 로드하거나 렌더링해두는 기능이다. JS 이벤트 리스너 없이 선언적으로 작성할 수 있다. ```html <script type="speculationrules"> { "prerender": [ { "where": { "selector_matches": "a" } } ] } </script> ``` 다만 현재 Chrome, Edge, Opera 등 크로미움 기반 브라우저에서만 지원되고, Firefox와 Safari는 미지원이다. MDN에서는 아직 Experimental로 분류하고 있다. 빠른 사이트에서는 즉각적인 내비게이션을 만들어주지만, 느린 사이트에서는 오히려 불필요한 리소스를 낭비하는 함정이 될 수 있다. --- SPA 존재 이유가 단순히 매끄러운 화면 전환 뿐만은 아니다. 전역 상태관리라던가, 부분 업데이트, 캐싱 같은 것들은 이 아티클에서 소개한 모던 CSS만으로는 해결되지 않을 문제라고 생각한다. 그래서 이 아티클에 완전히 동의하긴 어렵지만, 복잡한 상태 관리 없이 콘텐츠 전달이 주 목적인 랜딩 페이지나, 블로그, 문서 포털 같은 경우에는 MPA + 모던 CSS가 충분히 유효한 선택지가 될 수도 있을 것 같다. 그런데 Next.js 같은 프레임워크에서 이미 이 모던 브라우저의 기능들을 코어에 통합시키려는 작업들을 하고 있는 것으로 보여서 아마 프레임워크 레벨에서 자연스럽게 흡수될수도 있을 것 같기도 하다... (비슷한 의견이 번역본 블로그 댓글에도 많기도 했음)