이번 Google I/O 2024 발표에도 소개되었던 Speculation Rules API에 대한 내용을 가져왔어요.
Speculation Rules API는 이동할 페이지의 HTML을 미리 가져올 수 있는 기능으로, 기존 사용되던 <link rel="prefetch">의 개선된 버전이에요.
Multiple Page Application 사이트를 방문하다 보면 페이지 이동 시마다 로딩 스피너가 도는 답답함 경험해 보셨죠?
Speculation Rules API을 사용하면 Multiple Page Application에서도 Single Page Application처럼 빠른 페이지 로딩을 보장할 수 있다고 합니다.
동작 원리
과연 이 API는 어떻게 동작하는 것인지 간단히 알아볼까요?
페이지가 로드되면, 브라우저에서는 각 페이지마다 백그라운드 프로세스를 생성하여 페이지 리소스를 미리 요청한 후에 메모리에 저장해 둡니다.
즉, 브라우저에 보이지 않는 탭이 생긴다고 이해하시면 됩니다.
이후 사용자가 해당 페이지로 이동하게 되면 백그라운드에 있던 해당 페이지로 교체되면서 빠른 페이지 전환이 되는 원리입니다.
Speculation Rules API는 prerender와 prefetch 두 가지 방식을 제공합니다.
prerender는 페이지 렌더링에 필요한 모든 리소스를 미리 가져오지만, prefetch는 페이지 내 하위 리소스는 미리 가져오지 않습니다.
그리고 사용자 기기가 배터리/데이터 절약 모드인 경우, 메모리가 부족한 경우에도 동작하지 않기 때문에 너무 많은 페이지를 가져오지 않아야 합니다.
이커머스 플랫폼을 예로 들면, 사용자가 자주 찾는 메뉴나 상위에 위치한 상품에만 적용하는 것이 좋겠죠?
사용 방법
사용 방법은 간단한데요, 아래처럼 script 태그에 미리 요청할 url 목록을 추가하면 됩니다.
// 1. 정적 선언
<script type="speculationrules">
{
"prerender": [
{
"urls": ["/login.do", "/board.do"]
}
]
}
</script>
// 2. 브라우저가 speculationrules를 지원하는 경우에만 동적으로 추가
if (HTMLScriptElement.supports?.("speculationrules")) {
const specScript = document.createElement("script");
specScript.type = "speculationrules";
const specRules = {
"prerender": [
{
"urls": ["/login.do", "/board.do"],
},
],
};
specScript.textContent = JSON.stringify(specRules);
document.body.append(specScript);
} else {
const linkElem = document.createElement("link");
linkElem.rel = "prefetch";
linkElem.href = "/next.html";
document.head.append(linkElem);
}
물론 저렇게 특정 목록을 지정하는 방법 외에도 아래처럼 조건에 맞는 모든 url을 지정하는 방법도 있습니다.
// 3. 조건과 일치하는 url을 prerender
<script type="speculationrules">
{
"prerender": [
{
"where": {
"and": [
{ "href_matches": "/*" },
{ "not": { "href_matches": "/logout" } },
{ "not": { "href_matches": "/*\\?*(^|&)add-to-cart=*" } },
{ "not": { "selector_matches": ".no-prerender" } },
{ "not": { "selector_matches": "[rel~=nofollow]" } }
]
}
}
],
"prefetch": [
{
"urls": ["/next.do", "/board.do"],
"requires": ["anonymous-client-ip-when-cross-origin"],
"referrer_policy": "no-referrer"
}
]
}
</script>
전/후 속도 비교
그럼 Speculation Rules API 적용 전과 후를 한 번 비교해 볼까요?
적용 전 | 적용 후 |
적용 전에는 페이지 이동시 확실히 로딩 구간이 느껴지지만 적용 후에는 거의 즉각적으로 페이지가 뜨는 것을 볼 수 있습니다.
LCP도 확연히 차이나는데요, 적용 전의 LCP는 592ms 이고, 적용 후의 LCP는 놀랍게도 0ms인 것을 확인할 수 있어요.
직접 테스트하고 싶으신 분들은 요 링크에서 가능하니 한 번 들어가 보셔도 좋을 것 같아요!
<link rel="prefetch">와의 차이점
그럼 처음 소개할 때 말씀드렸던 <link rel="prefetch">과의 차이점도 무엇인지 알아볼까요?
<link rel="prefetch"> 태그는 css, js 등의 하위 리소스를 미리 가져오기 위한 태그로 주로 사용됩니다.
<link rel="prefetch" href="/app/style.css" />
// 혹은
<link rel="prefetch" href="/landing-page" />
이 방식은 네비게이션 리소스인 HTML 문서 자체를 가져오는 데에는 적합하지 않은데, 응답 헤더에 Cache-Control 속성 값이 no-cache, no-store일 경우에는 동작하지 않기 때문입니다.
(참고로 Speculation Rules API는 Cache-Control의 영향을 받지 않습니다.)
크롬에서도 <link rel="prerender">라는 태그를 만들어서 완벽한 프리 렌더링을 시도했었지만, 이 역시 효율성을 입증하지 못해 현재는 deprecated 되었습니다.
prefetch, prerender 외에도 비슷한 속성들이 더 있는데요, 헷갈려서 표로 정리했으니 궁금하신 분들은 한 번 읽어보셔도 좋을 것 같아요!
<link rel="prefetch"> | <link rel="prerender"> | <link rel="preload"> | <link rel="modulepreload"> | <link rel="preconnect"> |
추론적 힌트 (권장) |
추론적 힌트 (권장) |
선언적 힌트 (필수) |
선언적 힌트 (필수) |
추론적 힌트 (권장) |
사용자가 탐색을 위해 해당 리소스가 필요할 가능성이 높음을 알려주는 힌트 | prefetch와 동일 비표준 deprecated됨 |
우선순위가 높은 리소스를 미리 요청 | 모듈 스크립트(mjs)를 미리 요청 | 사용자가 탐색을 위해 해당 origin이 필요할 가능성이 높음을 알려주는 힌트 |
브라우저 지원 현황
Speculation Rules API를 실제 사이트에도 적용해보면 좋을 것 같은데요, 아직은 실험적인 기능이기도 하고 크롬, 엣지를 포함한 일부 브라우저에서만 지원되고 있습니다.
크롬 개발팀이 열일해서 좀 더 완성된 모습으로 정식 출시되면 좋겠네요!
참고 링크
'Language > Javascript' 카테고리의 다른 글
Shadow DOM이란? + Shadow DOM 활용 예시 (0) | 2024.08.06 |
---|---|
Javascript - groupBy를 사용하여 조건별 그룹 나누기 (0) | 2024.07.29 |
Javascript - ECMAScript 2023(ES14)에 추가된 기능 (0) | 2023.06.05 |
Typescript - 유틸리티 타입(Utility Type) (0) | 2022.09.25 |
Javascript - a 태그 알아보기 (0) | 2022.07.10 |