웹 사용자가 링크를 클릭하기 직전, 브라우저는 이미 다음 페이지의 렌더링을 끝마쳐 둘 수 있습니다. 자원 낭비 없이 0ms 네비게이션을 달성하는 차세대 웹 표준 Speculation Rules API의 원리와 실무 적용 전략을 심층 분석합니다.
HTMLScriptElement vs speculationRules)document.prerendering)웹 성능 최적화는 지난 10여 년간 번들 크기 축소, 코드 스플리팅, 이미지 지연 로딩(Lazy Loading), HTTP/3 도입 등 다양한 진화를 거듭해 왔습니다. 하지만 아무리 프론트엔드 자산을 경량화하고 엣지(Edge) 네트워크에서 렌더링하더라도, 물리적인 네트워크 왕복 시간(RTT)과 브라우저의 DOM/CSSOM 트리 파싱 및 JavaScript 파싱/실행 시간으로 인해 링크를 누른 뒤 최소 100~300ms의 공백이 필연적으로 발생합니다.
사용자 관점에서 진정한 ‘앱과 같은 반응성’은 대기 시간이 0에 수렴하는 **즉각 전환(Instant Loading)**입니다. 모바일 네이티브 앱은 화면 전환 시 백그라운드 메모리에 적재된 뷰를 즉각 스왑(Swap)하여 지연을 숨깁니다. 브라우저에서도 이와 동일한 메커니즘을 표준 웹 플랫폼 API로 구현하기 위해 도입된 규격이 바로 Speculation Rules API입니다.
이 API는 링크 목록이나 특정 URL 패턴을 브라우저에 JSON 형태로 알려줌으로써, 브라우저가 사용자 상호작용 의도를 감지했을 때 리소스를 미리 당겨오거나(Prefetch), 심지어 보이지 않는 백그라운드 페이지 샌드박스에서 렌더링까지 끝마치도록(Prerender) 지시합니다.
브라우저에는 과거부터 사전 로딩을 위한 선언적 힌트들이 존재했습니다.
<link rel="prefetch" href="/page.html">: 다음 탐색에 필요할 수 있는 단일 HTML 리소스를 브라우저 HTTP 캐시에 다운로드합니다.<link rel="prerender" href="/page.html">: 페이지 전체를 사전에 렌더링하도록 요청했습니다(과거 Chrome에서 실험적으로 지원되다 폐기).그러나 과거의 <link rel="prerender">는 심각한 문제점들을 안고 있었습니다:
이로 인해 브라우저 벤더들은 구형 link rel="prerender"를 폐기하고, 구조화된 JSON 규칙, 세밀한 실행 격리, 휴리스틱 기반의 적응형 실행을 지원하는 Speculation Rules API를 W3C WICG 표준으로 설계하여 Chrome 108부터 본격적으로 배포하기 시작했습니다.
Speculation Rules API는 크게 두 가지 동작 모드를 제공합니다.
| 비교 항목 | prefetch (사전 수집) |
prerender (사전 렌더링) |
|---|---|---|
| 가져오는 리소스 | 대상 URL의 기본 HTML 문서 (경우에 따라 하위 리소스) | HTML, CSS, JavaScript, 이미지, 서드파티 스크립트 전체 |
| 실행 단계 | 단순 HTTP 다운로드 후 메모리/디스크 캐시 저장 | 백그라운드 탭에서 DOM/CSSOM 구축 및 JS 초기 실행 완료 |
| 전환 속도 | HTML 다운로드 시간 절약 (약 150~400ms 단축) | 클릭 즉시 뷰포트 스왑 (0~50ms, 완전한 체감 0초) |
| 메모리 및 CPU 소모 | 매우 낮음 | 비교적 높음 (새로운 렌더러 프로세스/컨텍스트 소비) |
| 적용 권장 대상 | 외부 사이트 이동, 모바일 저사양 기기, 무거운 상세 페이지 | 전환 확률이 높은 핵심 유저 플로우, 장바구니→결제, 블로그 다음 글 |
기존의 <link rel="prefetch">와 달리 Speculation Rules API의 prefetch 모드는 HTTP 캐시 파티셔닝(Cache Partitioning) 문제를 우회하지 않고도 브라우저 내부의 자격 증명(Credential)과 쿠키를 표준에 맞게 안전하게 처리하며, Service Worker와의 연동도 매끄럽습니다.
Speculation Rules API는 HTML 문서 내에 <script type="speculationrules"> 블록을 선언하여 사용합니다. 이 스크립트는 실행형 자바스크립트가 아니며 순수 JSON 데이터 블록으로 파싱됩니다.
<script type="speculationrules">
{
"prerender": [
{
"source": "list",
"urls": ["/checkout/step1", "/products/popular"]
}
],
"prefetch": [
{
"source": "list",
"urls": ["/about", "/contact"]
}
]
}
</script>"prerender" 또는 "prefetch" 배열을 선언합니다.source: 대상 대상을 어떻게 지정할 것인지 정의합니다.
"list": 명시적인 URL 문자열 목록을 직접 열거합니다."document": 현재 DOM 트리에 렌더링된 <a> 태그들을 검사하여 조건에 맞는 링크를 자동으로 매칭합니다.urls: source: "list"일 때 사용되며, 절대 경로 또는 상대 경로 문자열 배열을 받습니다.대규모 전자상거래 플랫폼이나 블로그에서 모든 링크를 일일이 urls: [...]로 열거하는 것은 비현실적입니다. 이를 해결하기 위해 표준에 추가된 것이 **Document Rules (source: "document")**입니다.
<script type="speculationrules">
{
"prerender": [
{
"source": "document",
"where": {
"and": [
{ "href_matches": "/articles/*" },
{ "not": { "href_matches": "/articles/archive/*" } },
{ "not": { "selector_matches": ".no-prerender" } }
]
},
"eagerness": "moderate"
}
]
}
</script>where 절의 주요 연산자href_matches: URL 패턴 표준(URL Pattern API) 문법을 따릅니다. 와일드카드(*), 매개변수 바인딩(:id)을 사용할 수 있습니다.selector_matches: CSS 선택자를 기반으로 특정 클래스나 속성이 있는 <a> 태그만을 선택하거나 제외합니다."and", "or", "not"을 조합하여 정교한 화이트리스트/블랙리스트 필터링이 가능합니다.이 방식을 적용하면 마크업 개발자는 단순히 중요한 링크에 <a href="/articles/123" class="instant-link">와 같은 속성을 부여하는 것만으로 브라우저가 알아서 사전 렌더링 후보로 등록하게 만들 수 있습니다.
언제 사전 로딩을 시작할 것인가는 기기 배터리와 네트워크 대역폭 보호를 위한 핵심 제어 요소입니다. Speculation Rules는 eagerness 속성으로 4단계의 실행 민감도를 제공합니다.
| eagerness 단계 | 동작 트리거 조건 | 권장 사용 케이스 |
|---|---|---|
immediate |
규칙이 파싱되자마자 즉시 사전 렌더링/프리패치 시작 | 다음 이동 경로가 95% 이상 확실한 경우 (예: 로그인 폼 입력 중 메인 대시보드) |
eager |
사용자가 상호작용하기 전이라도 가능한 한 빠르게 시작 | 현재 뷰포트에 보이는 중요 링크, 추천 상품 1순위 |
moderate |
마우스 커서를 링크에 올리거나(200ms hover) 터치를 시작할 때 | 블로그 글 목록, 탐색 바 메뉴, 대부분의 일반 웹사이트 (가장 추천) |
conservative |
마우스 클릭 누름(mousedown) 또는 터치 시작(touchstart) 시점 |
결제 직전 단계 등 잘못 렌더링했을 때 위험이 큰 페이지 |
실무에서는 **moderate**가 가장 압도적인 성능 대 비용 효율을 자랑합니다. 인간의 반응 시간상 마우스를 올린 후 실제로 클릭을 완료하기까지 평균 200~350ms의 지연이 발생합니다. moderate는 이 200ms의 공백을 감지하여 즉시 사전 렌더링을 시작하므로, 대역폭을 낭비하지 않으면서도 클릭 순간에는 렌더링이 완료된 상태를 만들어 냅니다.
HTMLScriptElement vs speculationRules)단일 페이지 애플리케이션(SPA)이나 무한 스크롤, 비동기 데이터 로딩 환경에서는 DOM이 동적으로 생성되므로 자바스크립트를 통해 규칙을 주입하고 제거할 수 있어야 합니다.
<script> 요소를 동적으로 추가하는 방식 (크로스 브라우저 호환)// Speculation Rules를 지원하는지 체크
if (HTMLScriptElement.supports && HTMLScriptElement.supports('speculationrules')) {
const specScript = document.createElement('script');
specScript.type = 'speculationrules';
const rules = {
prerender: [
{
source: 'list',
urls: ['/cart/checkout'],
eagerness: 'immediate'
}
]
};
specScript.textContent = JSON.stringify(rules);
document.head.appendChild(specScript);
// 더 이상 필요 없으면 DOM에서 제거하여 취소 유도
// document.head.removeChild(specScript);
}document.speculationRules최신 명세에서는 스크립트 태그를 DOM에 삽입하지 않고도 자바스크립트 객체 형태로 규칙을 등록할 수 있는 document.speculationRules 인터페이스가 제안되고 있습니다.
// Speculation Rules 프로그래밍 객체 조작 패턴
if ('speculationRules' in document) {
// 규칙 동적 등록
const ruleSet = document.speculationRules.add({
prerender: [{
source: 'list',
urls: ['/dashboard/reports']
}]
});
// 특정 시점에 규칙 해제
// ruleSet.delete();
}이러한 동적 삽입 기법을 사용하면 마우스 커서가 특정 컴포넌트 근처로 다가오는 제스처(Pointer Velocity 예측)를 프론트엔드 라우터가 계산하여 필요한 타깃 페이지만 정밀하게 프리렌더할 수 있습니다.
document.prerendering)사전 렌더링(Prerender)은 완전히 독립된 백그라운드 브라우징 컨텍스트에서 실행됩니다. 이때 사용자가 보지도 않은 페이지에서 오디오가 재생되거나 웹캠 권한 요청 팝업이 뜨면 안 되므로 브라우저는 강력한 제약과 수명 주기 이벤트를 부여합니다.
alert(), confirm(), prompt(): 호출 즉시 무시되거나 에러 발생navigator.mediaDevices.getUserMedia(): 활성화 전까지 호출 보류Notification.requestPermission(): 사용자 상호작용 전까지 차단스크립트는 자신이 현재 보이지 않는 사전 렌더링 상태인지, 아니면 실제 화면에 노출되었는지를 document.prerendering 불리언 속성과 prerenderingchange 이벤트를 통해 파악해야 합니다.
// analytics.js - 사전 렌더링 상태를 고려한 로깅 스크립트
function sendPageView() {
fetch('/api/analytics/pageview', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ path: window.location.pathname, timestamp: Date.now() }),
keepalive: true
});
}
if (document.prerendering) {
console.log('[Speculation] 현재 페이지는 백그라운드에서 사전 렌더링 중입니다.');
// 사용자가 실제로 페이지로 진입하여 활성화될 때까지 실행을 연기
document.addEventListener('prerenderingchange', () => {
console.log('[Speculation] 페이지가 화면에 활성화(Activated)되었습니다.');
sendPageView();
}, { once: true });
} else {
// 일반적인 즉시 로드
sendPageView();
}prerenderingchange 리스너를 적절히 활용하지 않으면 사용자가 방문하지도 않고 링크 위를 스쳐 지나간 수천 명의 가짜 페이지뷰가 분석 서버에 전송되는 대참사가 일어납니다.
Speculation Rules를 적용했을 때 실측 사용자 경험 지표(RUM: Real User Monitoring)는 극적인 개선을 보여줍니다.
일반적인 페이지 이동 시 LCP는 보통 1.2초2.5초 내외로 형성됩니다. 그러나 50ms 수준으로 수렴**합니다. Chrome User Experience Report(CrUX) 지표에서 녹색 구간(Good, 2.5s 이하) 비율이 99%에 달하게 됩니다.prerender가 완료된 페이지로 전환되면, 화면 전환 시점에는 이미 브라우저 내부 렌더 트리가 완성되어 있으므로 **LCP 수치가 0ms에 가까운 10
클릭 시점에 메인 스레드가 다음 페이지 번들을 파싱하느라 멈추는 현상이 사라집니다. 이전 페이지에서 링크를 클릭하는 동작 자체의 시각적 반응 속도가 최적화되어 상호작용 지연이 대폭 감소합니다.
백그라운드에서 이미 TCP/TLS 핸드셰이크와 HTTP 응답 수신을 완료해 두었기 때문에, 네비게이션 시점의 실질적 TTFB는 0ms가 됩니다.
실무 도입 시 반드시 고려해야 할 부작용과 해결 방안입니다.
기본 Google 태그(gtag.js) 최신 버전은 브라우저의 document.prerendering을 감지하여 활성화될 때까지 page_view 이벤트를 자동으로 대기시킵니다. 그러나 사내 자체 로깅 솔루션, 페이스북 픽셀, 핫자(Hotjar) 등 커스텀 추적 스크립트는 이 처리가 되어 있지 않은 경우가 많습니다.
if (document.prerendering) 검사를 수행하는 공통 래퍼(Wrapper) 함수를 통해 실행되도록 강제해야 합니다.사전 렌더링 중에 세션을 갱신하거나 1회용 CSRF 토큰을 새로 발급받는 로직이 백그라운드에서 실행되면, 정작 사용자가 머물고 있는 현재 탭의 토큰이 만료되어 폼 제출 시 에러가 날 수 있습니다.
Sec-Purpose: prefetch;prerender HTTP 요청 헤더를 전송합니다. 백엔드 서버는 이 헤더를 감지하여 상태를 변경하지 않는 읽기 전용 로직만 처리해야 합니다.GET /checkout HTTP/1.1
Host: example.com
Sec-Purpose: prefetch;prerenderSpeculation-Rules 응답 헤더HTML 문서 본문에 인라인 스크립트를 넣는 대신, 웹 서버 응답 헤더를 통해 규칙 파일의 URL을 브라우저에 내려줄 수도 있습니다.
Speculation-Rules: "/rules/site-speculation.json"이를 통해 정적 캐싱된 HTML을 수정하지 않고도 CDN 단에서 유연하게 프리렌더 정책을 배포할 수 있습니다.
강력한 기술인 만큼 잘못 적용하면 시스템 비용이 폭증하고 유저 데이터가 파괴될 수 있습니다.
/api/logout, /cart/delete?item=1 같은 안티패턴 URL. 백그라운드 렌더링 순간 강제 로그아웃되거나 상품이 삭제됩니다.immediate 프리렌더를 걸면 안 됩니다.navigator.connection.saveData 및 기기 메모리(navigator.deviceMemory)를 체크하는 방어 코드를 두는 것이 좋습니다.// 클라이언트 측 방어적 사전 렌더링 검사기
function canPrerenderSafely() {
const connection = navigator.connection || {};
if (connection.saveData) return false; // 데이터 절약 모드
if (connection.effectiveType && connection.effectiveType.includes('2g')) return false;
if (navigator.deviceMemory && navigator.deviceMemory < 4) return false; // 저사양 기기
return true;
}Speculation Rules API는 브라우저가 지원하지 않더라도 오류를 내지 않고 조용히 무시되는(Graceful Degradation) 완벽한 하위 호환 구조를 갖추고 있습니다.
moderate eagerness 권장: 200ms 마우스 호버 시간을 활용하여 비용 없는 즉각 렌더링 달성document.prerendering 방어 코드 필수: 분석 데이터 왜곡 및 세션 오염을 방지하기 위해 라이프사이클 이벤트 분기 구현Sec-Purpose 헤더를 분기하여 불필요한 백엔드 쓰기 방지✨ 한 줄 요약 Speculation Rules API는 브라우저의 비가시 백그라운드 렌더링을 선언적으로 지휘하여 클릭 즉시 다음 화면을 띄워내는 차세대 웹의 치트키다.
