Chrome 151의 Soft Navigations API 덕분에 드디어 싱글 페이지 애플리케이션(SPA)이 앱 내 모든 네비게이션에 대해 Core Web Vitals를 보고할 수 있게 되었습니다. 하지만 Google의 CrUX 데이터셋은 여전히 첫 번째 하드 로드(hard load)만 기록하므로, 개발자들은 서로 다른 두 가지 성능 지표를 마주하게 됩니다.

SPA 지표가 뒤처졌던 이유

Core Web Vitals—Largest Contentful Paint (LCP), Interaction-to-Next-Paint (INP), Cumulative Layout Shift (CLS)—는 **하드 네비게이션(hard navigations)**을 기준으로 정의되었습니다. 하드 네비게이션은 완전히 새로운 문서를 가져오고 이전 페이지의 상태를 폐기합니다.

React, Vue, Next.js 또는 이와 유사한 프레임워크로 구축된 SPA는 하드 네비게이션을 거의 발생시키지 않습니다. 링크를 클릭하면 History API를 통해 URL이 업데이트되고, 백그라운드에서 데이터를 가져오며, 전체 페이지를 다시 로드하지 않고 콘텐츠를 교체합니다. 기존 Performance API는 초기 페이지 로드만 캡처하므로, 사용자가 한 라우트에서 다른 라우트로 이동할 때 느끼는 지연 시간(latency)을 LCP와 INP가 감지하지 못합니다.

이러한 사각지대는 Performance Timeline이나 Google의 Chrome User Experience Report(CrUX)에서 데이터를 가져오는 대시보드를 왜곡합니다. 이들은 종종 "셸(shell)" 페이지에 대해서는 훌륭한 LCP를 보여주지만, 앱 깊숙한 곳에서의 느린 로딩은 무시하여 성능이 건강하다는 잘못된 인상을 줍니다.

Chrome의 Soft Navigations API

Chrome 151은 특정 SPA 상호작용을 실제 네비게이션으로 취급하는 휴리스틱(heuristics) 세트인 Soft Navigations API를 도입했습니다. 이 API는 세 가지 신호를 감시합니다:

  • 사용자 주도 상호작용 (클릭, 탭, 키보드 이벤트)
  • History API를 통한 URL 변경
  • 새로운 콘텐츠를 렌더링하는 후속 페인트(paint) 이벤트

이 세 가지가 모두 일치하면 Chrome은 Performance Timeline에 **소프트 네비게이션(soft navigation)**을 기록하며, 하드 네비게이션과 마찬가지로 해당 전환에 대한 Core Web Vitals가 계산됩니다. 오픈 소스 web-vitals 라이브러리가 7월 21일에 지원을 추가했으므로, 개발자는 이미 사용 중인 동일한 API로 이 수치들을 가져오기 시작할 수 있습니다.

실제로 이제 각 라우트 변경에 대한 LCP 값, 마지막 사용자 입력의 실제 지연 시간을 반영하는 INP, 그리고 소프트 네비게이션 후의 레이아웃 이동을 포착하는 CLS를 확인할 수 있습니다.

데이터의 분리: Chrome vs. CrUX

Google의 CrUX(Chrome User Experience Report)는 PageSpeed Insights, Search Console 및 간접적으로 순위 신호(ranking signals)의 기반이 됩니다. CrUX는 여전히 하드 네비게이션 데이터만 집계합니다.

결과적으로, 일관되지만 서로 다른 두 가지 데이터 스트림을 갖게 됩니다:

  • Performance Timeline을 읽는 내부 도구는 이제 라우트 수준의 LCP, INP, CLS를 보여주며, SPA에서 사용자가 실제로 경험하는 모습을 현실적으로 보여줍니다.
  • Google의 공개 데이터셋은 계속해서 첫 번째 페이지 로드에 대한 지표만 보여주며, 이는 Search Console이 보고하고 Google의 순위 알고리즘이 참조하는 데이터입니다.

둘 다 맞습니다. 단지 서로 다른 시점을 측정할 뿐입니다. Search Console에만 의존하면 초기 로드 이후에 발생하는 성능 저하를 놓칠 수 있는 반면, 내부 대시보드만으로는 Google이 SEO에 사용하는 기준점을 반영하지 못합니다.

개발자가 주의해야 할 사항

  • 브라우저 지원 – Soft Navigations API는 현재 Chromium 기반 브라우저에서만 작동합니다. Safari와 Firefox에는 이에 상응하는 기능이 없으므로, 사용자 일부를 위해 폴백(fallback) 로직을 유지해야 합니다.
  • 휴리스틱의 한계 – 이 API는 일련의 단서를 바탕으로 소프트 네비게이션 여부를 결정합니다. URL을 변경하지 않고 콘텐츠를 업데이트하는 경우(예: 모달 오버레이 또는 무한 스크롤), API가 이러한 전환을 놓쳐 데이터에 공백이 생길 수 있습니다.
  • 신뢰하기 전 테스트 – 감지 방식이 휴리스틱이기 때문에, 앱에서 실제 환경과 유사한 상호작용 세트를 실행하고 보고된 지표를 수동 타이밍(예: performance.mark 사용)과 비교해 보십시오. 정확성을 확인한 후에만 새로운 수치를 바탕으로 최적화 결정을 내려야 합니다.

결론

Chrome 151은 SPA 개발자들에게 앱 내 모든 라우트 변경에 대해 LCP, INP, CLS를 측정할 수 있는 오랫동안 기다려온 기능을 제공하지만, Google의 순위 데이터는 여전히 첫 번째 하드 로드만을 반영합니다. CrUX가 따라잡을 때까지 팀은 두 개의 병렬 데이터 세트를 관리해야 합니다. 하나는 실제 사용자 경험을 알려주는 데이터이고, 다른 하나는 검색 순위를 결정하는 데이터입니다. 경쟁이 치열한 웹 생태계에서 성능 우선의 SPA를 유지하려면 이 두 가지 사이의 균형을 맞추고 더 넓은 브라우저 지원에 대비하는 것이 핵심이 될 것입니다.