1. 추론 규칙
HTML § 7.6.1 Speculation rules를 다음과 같이 수정하여 프리렌더링을 지원합니다.
1.1. 파싱
추론 규칙 집합 구조체에 두 개의 항목을 추가로 확장합니다:
-
prerender rules : list of speculation rules, 초깃값은 빈 리스트
-
prerender_until_script rules : list of speculation rules, 초깃값은 빈 리스트
speculation rule 구조체에 한 개의 항목을 추가로 확장합니다:
-
target navigable name hint : string 또는 null
-
typesToTreatAsPrefetch 구문을 제거하고, parsed["
prerender"]를 prerender rules 리스트로, parsed["prerender_until_script"]를 prerender_until_script rules 리스트로 파싱합니다. 이 때 parsed["prefetch"]와 prefetch rules에 대해 하는 것과 동일하게 처리합니다. -
parsed["
prefetch"]에서 파싱된 rule 중 target navigable name hint가 null이 아닌 것은 폐기합니다. -
parsed["
prerender"] 및 parsed["prerender_until_script"]에서 파싱된 rule 중 requirements에 "anonymous-client-ip-when-cross-origin"가 포함되면 해당 rule은 폐기합니다.
구현체는 § 1.2 Processing model에서 수정된 대로 prerender 후보를 prefetch로 취급하는 것도 여전히 허용됩니다.
-
targetHint를 null로 둡니다.
-
input["
target_hint"]가 존재한다면:-
input["
target_hint"]가 유효한 navigable target name 또는 키워드가 아니라면:-
사용자 에이전트는 제공된 target hint가 유효하지 않음을 콘솔에 경고로 보고할 수 있습니다.
-
null을 반환합니다.
-
-
targetHint를 input["
target_hint"]로 설정.
-
그리고 마지막 단계에서 speculation rule을 반환할 때 target navigable name hint를 targetHint로 설정합니다.
1.2. 프로세싱 모델
prerender 후보는 다음과 같은 추가 항목을 가진 speculative load candidate입니다:
-
target navigable name hint : 유효한 navigable target name 또는 키워드 또는 null
-
should block scripts : boolean 값, 초깃값은 false
-
prerenderCandidates를 빈 list로 둡니다.
-
각 ruleSet을 document의 speculation rule sets에서 반복:
-
각 (rules, shouldBlockScripts)를 « (ruleSet의 prerender rules, false), (ruleSet의 prerender_until_script rules, true) »로 간주:
-
각 rule을 rules에서 반복:
-
-
referrerPolicy = speculative load referrer policy 계산(rule, null)
-
추가: 새로운 prerender candidate, 값
- URL
-
url
- No-Vary-Search hint
-
rule의 No-Vary-Search hint
- eagerness
-
rule의 eagerness
- referrer policy
-
referrerPolicy
- tags
-
rule의 tags
- target navigable name hint
- should block scripts
-
shouldBlockScripts
-
-
rule의 predicate가 null이 아니면:
-
각 link를 links에서 반복:
-
target = rule의 target navigable name hint
-
target이 null이면 element의 target 얻기(link) 결과로 설정.
-
referrerPolicy = speculative load referrer policy(rule, link)
-
- URL
-
link의 url
- No-Vary-Search hint
-
rule의 No-Vary-Search hint
- eagerness
-
rule의 eagerness
- referrer policy
-
referrerPolicy
- tags
-
rule의 tags
- target navigable name hint
-
target
- should block scripts
-
shouldBlockScripts
-
-
-
-
-
speculativeLoadCandidates = prefetchCandidates 와 prerenderCandidates의 합집합으로 둔다.
not-still-being-speculated prefetch records를 취소하는 후속 단계를 prefetchCandidates 대신 speculativeLoadCandidates 기준으로 적용하라.
prerenderCandidateGroups 리스트도 prefetchCandidateGroups와 유사하게 만드는데 값으로 prerenderCandidates 사용.
실제 prefetch를 수행하는 단계를 prefetchCandidateGroups 대신 다음과 같이 변경합니다:
-
speculativeLoadCandidateGroups = prefetchCandidateGroups와 prerenderCandidateGroups의 합집합으로 한다.
-
각 group을 speculativeLoadCandidateGroups에서 반복:
-
사용자 에이전트는 아래 단계를 실행할 수 있다:
-
candidate를 group[0]으로 둔다.
-
tagsToSend = collecting tags from speculative load candidates(group)의 결과로 둔다.
-
prefetchRecord를 새로운 prefetch record로 다음 값 설정하고 생성
- source
-
"
speculation rules" - URL
-
candidate의 URL
- No-Vary-Search hint
-
candidate의 No-Vary-Search hint
- referrer policy
-
candidate의 referrer policy
- tags
-
tagsToSend
-
candidate가 prefetch candidate라면 prefetchRecord의 anonymization policy를 candidate의 anonymization policy로 설정.
-
candidate가 prerender candidate라면 아래 단계를 실행할 수 있음:
-
prefetchRecord의 prerendering traversable를 "
to be created"로 설정 -
prefetchRecord의 prerendering target navigable name hint를 candidate의 target navigable name hint로 설정.
-
리퍼러 기반 내비게이션 프리렌더 시작(document, prefetchRecord, candidate의 should block scripts)
-
-
이전 단계가 실행되지 않았다면, 리퍼러 기반 내비게이션 프리페치 시작(document, prefetchRecord)
(아래 "may" 단계의 실행 시점은 계속 논의에 포함됨.)
-
-
1.3. 트리거링
attribute change steps를
a
및
area
요소에 대해
target
속성까지 모니터링하도록, 그리고 변경 시 speculative loads 고려가 이루어지도록 수정합니다.
2. 프리렌더링 인프라
2.1. Document
인터페이스 확장
[HTML]의 Document
중앙 정의를 다음과 같이 수정합니다:
partial interface Document {readonly attribute boolean prerendering ; // Under "special event handler IDL attributes that only apply to Document objects"attribute EventHandler onprerenderingchange ; };
onprerenderingchange 속성은 이벤트 핸들러 IDL 속성이며, prerenderingchange 이벤트 핸들러 이벤트 타입과 대응됩니다. (해당 표는 현재 onreadystatechange만
포함하고 있습니다. 이에 대한 표도 [HTML]에서
갱신됩니다.)
[HTML]의 관례에 따라, prerendering
정의는 명세 내 다른 섹션에 위치합니다. 아래에 소개되는 새 섹션에 배치됩니다:
2.2. 프리렌더링 내비게이블
다음 절은 [HTML]의 Navigables 절에 새 하위 절로 추가됩니다.
모든 navigable에는 loading mode가 있으며, 아래 중 하나입니다:
- "
default" -
이 navigable에 로드된 콘텐츠에는 특별한 고려 사항이 적용되지 않습니다.
- "
prerender" -
이 navigable은 프리렌더링된 콘텐츠를 표시 중입니다.
기본적으로 navigable의 loading mode는 "default"입니다. loading
mode가 "prerender"인 navigable은 prerendering navigable이라고 부릅니다. prerendering navigable이면서 최상위 traversable인 것은 prerendering traversable이라고 부릅니다.
프리렌더링 navigable의 active browsing context는 보조 브라우징 컨텍스트가 될 수 없습니다.
현재 loading mode 값은 두 가지지만, fenced frames, portal, uncredentialed(교차사이트) prerendering 등 향후 로딩 모드 추가를 고려해 유연한 구조로 되어 있습니다. 실제로 필요없다는 것이 드러나면 boolean으로 바꿀 수도 있습니다.
모든 navigable은 scripting mode가 있으며, 아래 중 하나입니다:
- "
enabled" -
스크립트가 정상적으로 실행됩니다.
- "
blocked-until-activation" -
navigable이 활성화될 때까지 스크립트 실행이 차단됩니다.
기본적으로 navigable의 scripting mode는 "enabled"입니다.
scripting mode는 document가 아니라 navigable의 속성입니다. 이는 동일 navigable 내에서 navigation 이
일어나도 유지되어야 하며, about:blank 첫 문서나 활성화 전 client-side redirect 케이스 등에 필요합니다.
모든 prerendering traversable은 prerender 초기 응답 search variance가 있으며, URL search variance 또는 null이며, 초기값은 null입니다.
document.prerendering-
페이지가 비대화형 프리렌더링 컨텍스트에서 표시 중인 경우 true를 반환합니다.
true→false로 값이 변할 수 있으며, 이 때
Document에서prerenderingchange이벤트가 발생합니다. (이후 다시 true로 바뀌지는 않습니다.)
prerendering getter 단계는 this에 비null인 node navigable이 존재하고, 해당 navigable이 prerendering navigable이면 true,
아니면 false 반환.
모든 Document
는 post-prerendering activation steps list를
가지며, list 자료구조로 각
항목은 일련의
알고리즘 단계 집합입니다. 편의를 위해 임의의 플랫폼 객체 platformObject에 대해 post-prerendering activation steps
list를 다음과 같이 정의합니다:
- 만약 platformObject가 노드라면
-
-
platformObject의 node document의 post-prerendering activation steps list를 반환.
-
- 그 외의 경우
-
-
단언: platformObject의 relevant global object는
Window객체임.
-
platformObject의 relevant global object의 연관 Document의 post-prerendering activation steps list 반환.
-
모든 Document
는 activation start time을 가지며, 초기값은 타임값이 0인 DOMHighResTimeStamp
입니다.
모든 Document
는 프리렌더링 중 교차 오리진 iframe 내비
허용을 가지며, boolean이고, 초깃값은 false입니다.
2.3. 프리렌더 알고리즘
사용자 에이전트 기반 프리렌더링 시작을 URL startingURL에 대해 다음과 같이 수행합니다:
-
단언: startingURL의 scheme는 HTTP(S) scheme 중 하나임.
-
prerenderingTraversable을 새 최상위 traversable 생성(null, 빈 문자열) 결과로 둡니다.
-
prerenderingTraversable의 loading mode를 "
prerender"로 설정. -
prefetchRecord를 새 prefetch record로 두며, URL은 startingURL, anonymization policy는 null, referrer policy는 빈 문자열, No-Vary-Search hint는 기본 URL 검색 variance, source는 "
browser UI", prerendering traversable는 prerenderingTraversable. -
리퍼러 기반 네비게이션 프리페치 시작(prerenderingTraversable의 active document, prefetchRecord) 실행.
-
Navigate prerenderingTraversable to startingURL with prerenderingTraversable의 active document.
이 초기 navigation은 prerenderingTraversable이 자신을 navigation하는 것으로 취급하여 관련 모든 보안 검사 통과를 보장합니다.
-
사용자가 activationURL로 navigation 확인 의사를 표시하였고, activationURL에 대해 prefetchRecord가 URL 매칭이면:
-
사용자가 navigation 도중 새 사용자 가시적 최상위 traversable 생성을 원하면 (예: 주소창에서 Shift+Enter):
-
활성화용 successor 갱신(prerenderingTraversable, startingURL, activationURL).
-
프리렌더 탭/창 등 사용자 UI 갱신.
-
-
또는, 사용자가 기존 최상위 traversable predecessorTraversable에 navigation 활성화 표시 시:
-
활성화(prerenderingTraversable, predecessorTraversable, "
push", startingURL, activationURL).
-
-
사용자가 그런 활성화를 전혀 표시하지 않을 수도 있고, 프리렌더 자원이 필요한 즉시 다른 작업을 위해 사용자 에이전트가 자원을 회수해야 할 수도 있습니다. 이런 경우 사용자 에이전트는 destroy prerenderingTraversable할 수 있습니다.
Document
referrerDoc, prefetch record prefetchRecord, boolean
blockScripts가 주어졌을 때 다음을 수행합니다:
-
단언: prefetchRecord의 URL의 scheme은 HTTP(S) scheme 중 하나임.
-
referrerDoc의 node navigable이 최상위 traversable이 아니면 return.
현재로서 child navigable에서 프리렌더링은 명세/구현되지 않음. navigable 트리 내 노출 등 복잡한 고려 사항 있음.
-
referrerDoc의 browsing context가 보조 브라우징 컨텍스트면 return.
prerendering traversable과 referrerDoc의 browsing context opener 관계를 피하기 위함.
-
referrerDoc의 origin이 prefetchRecord의 URL의 origin과 same site가 아니면 return.
현재로서는 교차 사이트 프리렌더링 명세/구현 안 됨. (추후 개선 아이디어는 있음)
-
referrerDoc이 매칭 프리페치 기록 있음이면 return.
-
단언: prefetchRecord의 prerendering traversable이 "
to be created"임. -
prerenderingTraversable을 새 최상위 traversable 생성 결과로.
사용자 에이전트는 prefetchRecord의 prerendering target navigable name hint를 새 최상위 traversable 생성 구현 힌트로 활용할 수 있음.
이 값은 힌트에 불과. 실제 활성화된 traversable이 다를 수도 있음.
-
prerenderingTraversable의 loading mode를 "
prerender"로 설정. -
blockScripts가 true라면 prerenderingTraversable의 scripting mode를 "
blocked-until-activation"로. -
prefetchRecord의 prerendering traversable을 prerenderingTraversable로 한다.
-
prerenderingTraversable의 remove from referrer에 prefetchRecord의 prerendering traversable을 null로 설정하는 알고리즘을 부여.
모든 최상위 traversable과 마찬가지로, prerendering traversable도 비응답, 제한 행위, 과도 리소스 등 이유로 언제든 제거 가능. 이 경우에도 prefetch record는 남아 향후 navigation 활용 가능.
-
리퍼러 기반 네비게이션 프리페치 시작(referrerDoc, prefetchRecord).
-
Navigate prerenderingTraversable to prefetchRecord의 URL with referrerDoc, referrerPolicy= prefetchRecord의 referrer policy.
활성화용 successor 갱신은 prerendering traversable successorTraversable, URL startingURL, URL activationURL이 주어졌을 때:
-
successorDocument를 successorTraversable의 active document로 둔다.
-
startingURL이 successorDocument의 URL과 같고, startingURL이 activationURL과 다르면:
-
단언: successorDocument가 activationURL로 URL을 변경할 수 있음.
-
navigation를 successorDocument의 relevant global object의 navigation API로 둔다.
-
continue = push/replace/reload
navigate이벤트 발화(navigation, "replace", activationURL, true) 결과 -
continue가 true면 URL & 히스토리 갱신 단계(successorDocument, activationURL) 실행
No-Vary-Search 기반인 부정확 매칭에서 실제 URL과 프리렌더 URL을 일치시킬 수 있음.
-
활성화는 prerendering traversable successorTraversable, 최상위 traversable predecessorTraversable, history handling behavior historyHandling, URL startingURL, URL activationURL, 선택적 navigation ID navigationId가 주어졌을 때:
-
단언: successorTraversable의 active document의 is initial about:blank가 false임.
-
navigationId가 없다면, navigationId를 임의 UUID 생성 결과로 설정.
-
referrerOrigin을 predecessorTraversable의 active document의 origin으로 둔다.
-
predecessorTraversable의 ongoing navigation에 navigationId를 설정.
이렇게 하면 predecessorTraversable의 기존 navigation은 모두 abort됨.
-
병렬로 다음 단계 실행:
-
unloadPromptCanceled = 언로드 유저취소 여부 확인(predecessorTraversable의 active document의 모든 자식 navigable)
-
unloadPromptCanceled가 true이거나 predecessorTraversable의 ongoing navigation이 더 이상 navigationId가 아니라면 중단.
-
글로벌 태스크 큐잉(navigation and traversal task source, predecessorTraversable의 active window) → abort(predecessorTraversable의 active document)
-
활성화용 successor 갱신(successorTraversable, startingURL, activationURL).
-
세션 히스토리 traversal 단계 추가(predecessorTraversable, 아래 단계):
-
단언: successorTraversable의 현재 세션 히스토리 step은 0.
-
단언: successorTraversable의 세션 히스토리 엔트리 크기는 1.
-
successorEntry = successorTraversable의 세션 히스토리 엔트리[0]
-
제거(successorEntry, successorTraversable의 세션 히스토리 엔트리)
이 시점에서 successorTraversable는 비어 있고 (성공적으로) 파괴될 수 있음. (단, successorEntry 등 관련 대상은 다음 단계까지 유지)
-
교차 문서 navigation 완료(predecessorTraversable, historyHandling, successorEntry)
세션 히스토리 엔트리 전체를 이동시키기 때문에, 이 엔트리 내 document의 browsing context까지 그룹이 변경됨. COOP(Co-Opener-Policy)와 유사하게 opener 관계가 해제됨.
-
유저 에이전트 UI(탭/창 등) 업데이트.
-
최종 활성화(successorTraversable, referrerOrigin)
-
여기에서 WebDriver BiDi와의 연계 고려 필요(w3c/webdriver-bidi#321 참조). 현재는 탐색 시작만 나오고 종료 제어 없음.
-
-
-
각 navigable을 traversable의 active document의 모든 자식 navigable에서 반복, 글로벌 태스크 큐에 추가(navigation and traversal task source, navigable의 active window)하여 아래 단계 수행:
-
각 origin → hintSet을 navigable의 prerender-scoped Accept-CH cache 맵에서 반복:
-
Set Accept-CH cache[origin] = hintSet
-
-
navigable의 scripting mode가 "
blocked-until-activation"이면:-
navigable의 scripting mode를 "
enabled"로. -
navigable의 active document에서 스크립트 실행 차단 해제.
스크립트 실행 재개 및 큐된 태스크 처리 상세는 향후 추가 필요.
-
-
doc = navigable의 active document로 둠.
-
여기서 실제로 로딩 모드 변경 신호가 전달되어야 하며, 구현체는 이 태스크에서
document.prerendering변화 반영 필요. -
doc의 origin이 origin과 같으면 doc의 activation start time을 해당 현재 고해상도 시각으로.
-
각 steps를 doc의 post-prerendering activation steps list에서 반복:
-
steps 실행.
반환값은 무시 가능.
-
단언: steps 실행 중 예외 없음.
여러 document가 같은 이벤트 루프 쓸 때만 순서 보장.
-
-
prerendering traversable 파괴 시 참조 해제를 보장하기 위해, destroy a top-level traversable에 아래 스텝을 추가합니다:
-
traversable이 prerendering traversable이고 traversable의 remove from referrer가 null 아니면 호출.
2.4. 내비게이블 생성 변경 사항
-
navigable의 loading mode를 element의 node navigable의 loading mode로 설정합니다.
3. 네비게이션 및 세션 히스토리
3.1. 네비게이션 대신 활성화 허용
Document
predecessorDocument와 URL url이 주어졌을 때:
-
recordToUse를 null로 둔다.
-
각 record를 predecessorDocument의 prefetch records에서 반복:
-
record의 prerendering traversable이 prerendering traversable이 아니면 continue
-
record의 prerendering traversable의 active document의 is initial about:blank가 true이면 continue
-
record의 URL이 url과 같으면:
-
recordToUse를 record로 설정.
-
-
recordToUse가 null이고 record가 URL 매칭(url)이면:
-
recordToUse를 record로 설정.
-
-
-
recordToUse가 null이 아니면:
-
제거(recordToUse, predecessorDocument의 prefetch records)
-
-
recordToUse를 반환.
-
다음 조건 중 하나라도 만족하면:
-
navigable이 최상위 traversable이 아님;
-
navigable이 prerendering traversable임;
-
navigable이 fenced frame임;
-
cspNavigationType이 "
other"가 아님; -
documentResource가 null이 아님
이 경우 null을 반환.
-
-
predecessorDocument를 navigable의 active document로 둔다.
-
cutoffTime을 null로 둔다.
-
while true:
-
completeRecord = 매칭되는 프리렌더 프리페치 기록 찾기(predecessorDocument, url) 결과.
-
completeRecord가 null이 아니라면 return completeRecord
-
potentialRecords를 빈 list로 둔다.
-
각 record를 predecessorDocument의 prefetch records에서 반복:
-
아래 조건을 모두 만족하면 append record to potentialRecords:
-
record의 prerendering traversable 이 prerendering traversable 임;
-
record의 prerendering traversable의 active document의 is initial about:blank가 true임;
-
record가 URL 매칭 예상(url);
-
cutoffTime이 null이거나 record의 start time이 cutoffTime 미만
-
-
-
potentialRecords가 empty이면 null을 반환
-
predecessorDocument의 prefetch records의 어떤 record의 prerendering traversable의 ongoing navigation이 변할 때까지 기다림
-
cutoffTime이 null이고 potentialRecords 중 일부의 prerendering traversable의 active document의 is initial about:blank가 false이면 cutoffTime을 현재 고해상도 시각(predecessorDocument의 relevant global object)로 설정
-
navigate 알고리즘에 패치를 적용하여, 일반적인 네비게이션 대신 prerendering traversable의 활성화를 허용합니다.
-
record = 매칭되는 프리렌더 프리페치 레코드 대기(navigable, url, cspNavigationType, documentResource) 결과.
-
record가 null이 아니면:
-
matchingPrerenderedNavigable = record의 prerendering traversable.
-
startingURL = record의 URL.
-
활성화(matchingPrerenderedNavigable, navigable, historyHandling, startingURL, url, navigationId).
-
이 단계들 종료.
-
3.2. 네비게이션 fetch 변경
-
initiatorOrigin을 entry의 document state의 initiator origin으로 둔다.
아래 부분, "while true:" 첫 서브스텝 이후에 아래 단계들을 추가합니다:
-
navigable이 prerendering navigable이고, currentURL의 origin이 initiatorOrigin과 same site가 아니면:
-
navigable이 최상위 traversable이면 null 반환.
-
그 외, navigable의 top-level traversable의 active document의 프리렌더링 중 교차 오리진 iframe 내비 허용이 false라면, 사용자 에이전트는 navigable의 loading mode가 "
normal"이 될 때까지 이 알고리즘을 대기해야 한다. 대기 중(즉시 포함) 언제든지 destroy navigable의 top-level traversable 및 이 알고리즘에서 null 반환 선택가능.
-
알고리즘 마지막 부분, locationURL 체크 이후 아래 단계를 추가합니다:
-
navigable이 prerendering navigable이고, responseOrigin이 initiatorOrigin과 same origin이 아니면:
-
loadingModes를 응답의 지원 loading mode 얻기 결과로 둔다.
-
loadingModes에 `
credentialed-prerender`가 없으면 null 반환.향후
uncredentialed-prerender토큰도 허용할 수 있으나, 이는 교차사이트용이라 아직 실명세/구현 없음. 현스펙 기준 해당 토큰만 있으면 prerender 실패.
-
Refresh header, then:" 뒤에 아래 단계를 추가하세요:
-
navigationParams의 navigable이 prerendering navigable이면:
-
loadingModes를 응답의 지원 로딩 모드 얻기 결과로 둔다.
-
loadingModes에 `
prerender-cross-origin-frames`가 있으면 document의 프리렌더링 중 교차 오리진 iframe 내비 허용을 true로 설정.
-
-
navigable이 prerendering navigable이고 아래 중 하나라도 해당하면:
-
failure가 true임;
-
navigationParams의 request가 null임;
-
navigationParams의 request의 current URL의 scheme이 HTTP(S) scheme이 아님;
-
navigationParams의 request의 current URL이 잠재적으로 신뢰할 수 있는 URL이 아님;
-
navigationParams의 response가 프리페치 지원이 아님;
prefetch 부적격(예: 오류 status 등) 응답은 prerender에도 부적격. 향후 명확히 구분할 수도 있음. -
navigationParams의 response에 `
Content-Disposition` 헤더가 존재해attachment인 경우;
이라면:
-
destroy navigable의 top-level traversable.
-
return.
-
-
navigable이 prerendering traversable이고, navigable의 prerender 초기 응답 search variance가 null이면:
-
navigable의 prerender 초기 응답 search variance를 URL search variance 취득(navigationParams의 response) 결과로 설정.
-
-
navigable이 prerendering navigable이면 외부 소프트웨어 패키지를 호출하지 않고 return.
리다이렉트 대신 활성화를 허용할 수도 있지만, 이는 복잡성 증가 및 미구현으로 이번엔 포함하지 않음.
3.3. 단순 세션 히스토리 유지
-
navigable이 prerendering navigable이면 historyHandling을 "
replace"로 설정.
-
navigable이 prerendering navigable이면 historyHandling을 "
replace"로 설정.
3.4. 워커 수명과의 상호작용
워커는 active needed worker라 불리려면 오너 중 하나가 Document
객체이고, 해당 fully active이며 그 node navigable이 prerendering navigable이 아닌
경우, 또는 active needed workers 중 하나일 때이다.
즉, 워커 스크립트는 로드되지만, 문서가 활성화될 때까지 실행은 일시중지된다.
3.5. Document
폐기 시 정리
Document의
destroy 알고리즘에 아래 단계를 추가하세요:
-
비움: document의 post-prerendering activation steps list.
4. 다른 명세 및 개념과의 상호작용
4.1. Page Visibility와의 상호작용
prerendering
navigables의 문서는 항상 visibility state가 "hidden"이다.
아마 document.prerendering와
마찬가지로 이 값도 명시적으로 업데이트해야 할 것 같다.
4.2. 시스템 포커스와의 상호작용
Prerendering traversables는 system focus를 가지지 않는다.
4.3. PerformanceNavigationTiming
인터페이스 확장
PerformanceNavigationTiming
인터페이스를 아래와 같이 확장합니다:
partial interface PerformanceNavigationTiming {readonly attribute DOMHighResTimeStamp activationStart ; };
activationStart
getter 단계는 다음과 같습니다:
4.4. 클라이언트 힌트 캐시와의 상호작용
Accept-CH cache는 사용자 에이전트가 전역 스토리지로 소유하는데, 프리렌더링 중엔 변경되지 않고, 활성화 후에는 올바르게 업데이트되어야 함을 보장해야 함. 아래 수정으로 이를 달성.
각 prerendering navigable는 prerender-scoped Accept-CH cache를 가지며, ordered map 형식으로 origin에서 client hints sets으로 매핑된다.
이 구조는 각 origin별로 받은 client hints를 저장하고, 활성화 시 글로벌 Accept-CH cache로 복사한다.
-
navigable을 settingsObject의 global object의 navigable로 둔다.
-
originMatchingEntries를 Accept-CH cache에서 origin이 settingsObject의 origin과 same origin인 엔트리로 둔다.
-
navigable이 prerendering navigable이라면:
-
prerenderAcceptClientHintsCache를 navigable의 prerender-scoped Accept-CH cache로 둔다.
-
origin을 settingsObject의 origin으로 둔다.
-
prerenderAcceptClientHintsCache[origin]이 존재하면 originMatchingEntries를 prerenderAcceptClientHintsCache 안에서 origin이 origin과 same origin인 엔트리로 둔다.
-
-
navigable을 settingsObject의 global object의 navigable로 둔다.
-
navigable이 prerendering navigable이면 set navigable의 prerender-scoped Accept-CH cache[origin]에 hintSet을 설정.
-
그 외에는 set Accept-CH cache[origin]에 hintSet을 설정.
4.5. Clear Site Data와의 상호작용
Clear Site Data § 3.1 The Clear-Site-Data HTTP Response Header Field에 아래 헤더 값 설명을 추가하세요:
- "
prerenderCache" -
"
prerenderCache" 타입은 서버가 특정 origin이 시작한 모든 prerender를 response의 URL 기준으로 삭제하고자 함을 나타낸다.이 타입은 "
cache" 타입의 하위셋입니다.구현 상세는 아래를 참고.
parse response’s Clear-Site-Data header의 파싱 단계에서 아래와 같이 수정하세요:
-
`"cache"`또는`"*"`가 등장하면 "prerenderCache" 를 types에 append(기존 append 이외에도); -
`"prerenderCache"`발견 시 "prerenderCache" 를 types에 append.
clear site data for response의 switch 문에,
"prerenderCache"
케이스를 추가하고 clear
prerender cache(origin)을 호출합니다.
-
각 top-level traversable traversable을 사용자 에이전트의 top-level traversable 집합에서 반복:
-
navigables를 traversable의 active document의 모든 자식 navigable로 둔다.
-
각 navigable을 navigables에서 반복:
-
activeDocument를 navigable의 active document로 둠.
-
activeDocument의 origin이 origin 과 same origin이 아니면 continue
-
각 prefetchRecord를 activeDocument의 prefetch records에서 반복:
-
prefetchRecord의 prerendering traversable 이 null이면 continue
-
Cancel and discard prefetchRecord(activeDocument).
-
-
-
4.6. Fetch와의 상호작용
Sec-Purpose`를
설정하는 단계 다음에
다음 단계를 추가합니다:
-
그렇지 않으면, httpRequest의 client가 environment settings object이고 그 global object가
Window이며, 그Window의 navigable가 prerendering navigable인 경우:-
"
prerender"라는 키와 값이 true인 파라미터를 purpose의prefetch토큰에 추가합니다. -
구조화 필드 값 설정을 호출하여 (`
Sec-Purpose`, purpose)를 httpRequest의 header list에 설정합니다.
이것은 프리렌더링 navigable 내의 서브리소스뿐만 아니라, 프리렌더링 navigable 자체가 내비게이션 중인 경우도 포함합니다.
5. `Supports-Loading-Mode` HTTP 응답
헤더
다음 절은 [HTML]의 Loading web pages 절의 하위절로 추가됩니다.
일부 경우, 교차 출처 웹 페이지는 새로운 컨텍스트에서 로드되도록 준비되어 있지 않을 수 있습니다. 그런 경우에
해당 페이지가 그러한 로딩 방식에 옵트인할 수 있도록,
`Supports-Loading-Mode`
HTTP 응답 헤더를 사용할 수 있습니다. 이 헤더는 structured
header이며;
존재할 경우 그 값은 아래 열거된 하나 이상의 tokens이어야
합니다.
파싱은 실제로 list of tokens로 수행되며, 알 수 없는 토큰은 무시됩니다.
The
`credentialed-prerender`
토큰은, 응답이 교차-출처 동일 사이트 리퍼러에 의해 시작된 경우에도 해당 응답을 사용하여 prerendering navigable을 만들 수 있음을
나타냅니다. 이 옵트인이 없으면, 그러한 프리렌더는 § 3.2 Navigation fetch changes에서 설명한 대로
실패합니다.
The
`prerender-cross-origin-frames`
토큰은 응답이 모든 교차-출처 iframe을 프리렌더링하는 데 사용될 수 있음을 나타냅니다. 이 옵트인이 없으면,
그러한 프리렌더는 § 3.2 Navigation fetch changes에서 설명한 대로
연기됩니다.
응답에 대한 지원되는 로딩 모드 얻기는 response response에 대해 다음과 같이 동작합니다:
-
response가 network error이면, 빈 리스트를 반환합니다.
-
slmHeader를 getting a structured field value 호출로부터 얻습니다; 인자로는 `
Supports-Loading-Mode`와 "list" 그리고 response의 header list입니다.
6. 침해성 동작 방지
여러 동작들이 prerendering navigables에서 금지됩니다. 이는 프리렌더된 콘텐츠가 사용자가 적극적으로 상호작용하는 상태가 아니므로 사용자에게 침해적일 수 있기 때문입니다.
6.1. 스크립트 실행 일시정지
만약 navigable의 scripting mode가 "blocked-until-activation"이면,
사용자 에이전트는 그 navigable의 active document에서 스크립트를 실행해서는 안 됩니다. 이에는
<script> 요소 실행이 포함되지만 이에 국한되지 않습니다.
스크립트 실행이 어떻게 정확히 차단되고, 다양한 스크립트 관련 작업이 처리되지 않고 큐에 쌓이는지에 대한 메커니즘은 더 자세히 명시할 필요가 있습니다.
이 규정은 페이지가 활성화될 때까지 모든 JavaScript 실행을 실질적으로 일시정지합니다. 인라인 이벤트 핸들러에 대한 예상 동작은 논의 중입니다.
6.2. 리소스 다운로드
download the hyperlink 알고리즘을 수정하여, prerendering navigable 안에서의 다운로드가 활성화가 될 때까지 지연되도록, in parallel로 가는 단계 앞에 다음을 삽입합니다:
-
subject의 node navigable가 prerendering navigable이면, 다음 단계를 subject의 post-prerendering activation steps list에 추가하고 반환합니다.
6.3. 사용자 프롬프트
Window
window가 주어졌을 때 다음 단계를 맨 앞에 추가합니다:
-
window의 navigable가 prerendering navigable이면 true를 반환합니다.
print()
메서드 단계들을 수정하여, 다음 단계를 앞에 추가합니다:
-
this의 navigable가 prerendering navigable이면 반환합니다.
6.4. 비동기 API 결과 지연
많은 명세들은, 주어진 알고리즘이 prerendering navigable 내에서 호출될 경우 그 작업의 대부분을 그 navigable의 top-level traversable가 활성화될 때까지 연기하도록 패치되어야 합니다. 많은 명세들이 이벤트 루프 사용에 대해 일관성이 없기 때문에 이를 일관되게 적용하는 것은 까다롭습니다. 그럼에도 불구하고 아래 절들은 우리가 시도한 최선의 방법을 제시합니다.
만약 scripting mode가 "blocked-until-activation"이면,
이러한 알고리즘을 호출하는 스크립트들은 애초에 활성화될 때까지 실행되지 않습니다.
6.4.1. [DelayWhilePrerendering] 확장 속성
비동기 메서드의 동작을 활성화 시까지 지연시키는 보일러플레이트를 추상화하기 위해, [DelayWhilePrerendering]라는 Web IDL
확장 속성을 도입합니다. 이 속성은 주어진 메서드가 활성화 전에 호출되면 즉시 보류 중인 프라미스를
반환하고 아무 것도 하지 않음을 의미합니다. 활성화 시에만 원래 메서드 단계가 실행되어 그 결과로 이전에
반환된 프라미스를 해결하거나 거부합니다.
[DelayWhilePrerendering]
확장 속성은 인자를 받지 않아야 하며, 반환 타입이 프라미스 타입 또는 undefined인
정규 또는 정적 연산에만
나타날 수 있어야 하고, 그 노출 세트는 오직 Window만
포함해야 합니다.
[DelayWhilePrerendering]
확장 속성이 붙은 연산의 메서드 단계는 다음으로 대체됩니다:
-
realm을 현재 realm으로 둡니다.
-
만약 해당 연산이 regular operation이면, realm을 this의 relevant realm으로 설정합니다.
-
realm의 global object의 navigable가 prerendering navigable이면:
-
promise를 realm에서 생성된 새로운 프라미스로 합니다.
-
다음 단계들을 this의 post-prerendering activation steps list에 추가합니다:
-
만약 이 연산의 return type이 프라미스 타입이면, promise를 반환합니다.
-
-
그렇지 않으면, 동일한 this와 인자들로 원래 명시된 단계들을 실행한 결과를 반환합니다.
6.4.2. Service Workers
[DelayWhilePrerendering]
을 update(),
unregister(),
register(scriptURL, options),
postMessage(message, transfer),
및 postMessage(message, options)
에 추가합니다.
이는 프리렌더된 페이지가 기존 서비스 워커를 활용할 수 있게 하지만, 서비스 워커 등록 상태에는 어떠한 영향도 주지 않도록 합니다.
6.4.3. BroadcastChannel
[DelayWhilePrerendering]
을 postMessage()
에 추가합니다.
6.4.4. 지오로케이션 API
getCurrentPosition()
메서드 단계를 수정하여, 다음 단계를 가장 앞에 추가합니다:
-
this의 relevant global object의 navigable이 prerendering navigable이면, 다음 단계를 this의 post-prerendering activation steps list에 추가하고 return.
watchPosition()
메서드 단계를 수정하여, 다음 단계를 가장 앞에 추가합니다:
-
this의 relevant global object의 navigable이 prerendering navigable이면:
-
watchId를 구현자 정의
unsigned long으로 두고, 이를 post-prerendering activation 지오로케이션 watch 프로세스 ID로 기록합니다. -
다음 단계를 this의 post-prerendering activation steps list에 추가하되, 생성된 watchId를 그 ID로 사용하게 하고 watchId를 반환합니다.
-
clearWatch(watchId)
메서드 단계를 수정하여, 다음 단계를 가장 앞에 추가합니다:
-
this의 relevant global object의 navigable이 prerendering navigable이면:
-
watchId가 post-prerendering activation 지오로케이션 watch 프로세스 ID이면, 해당 단계들을 this의 post-prerendering activation steps list에서 제거합니다.
-
return.
-
6.4.5. 웹 시리얼 API
[DelayWhilePrerendering]
을 requestPort()
에 추가하세요.
TODO: 아래는 일반화된 [DelayWhilePrerendering]
를 dedicated worker에서 owner document를 이용해 지원하면 쉽게 처리될 듯하다.
getPorts()
메서드 단계를 수정하여, promise가 생성된 직후 바로 다음에 아래 단계를 삽입하세요:
-
document를 this의 relevant global object의 associated Document로 두거나, this의 relevant global object가
DedicatedWorkerGlobalScope면 owner document로 둡니다. -
document가 null이면, a promise rejected with "
SecurityError"DOMException을 반환. -
document의 node navigable이 prerendering navigable이면, 아래 단계들을 document의 post-prerendering activation steps list에 추가하고 promise를 반환.
6.4.6. 알림 API
[DelayWhilePrerendering]
을 requestPermission()
에 추가하세요.
Notification()
생성자 단계를 수정하여, in parallel로 가는 단계를 아래로 교체합니다:
-
this의 relevant global object의 navigable이 prerendering navigable이면, 아래 단계들을 this의 post-prerendering activation steps list에 추가합니다. 그렇지 않으면 아래 단계를 in parallel로 실행합니다.
permission
static getter 단계를 바꾸어 아래 단계로 대체합니다:
-
current global object의 navigable이 prerendering navigable이면 "
default"를 반환한다.이렇게 하면 구현체가 실제 permission 값을 동기적으로 조회하지 않아도 되고, 특히 prerendering navigable 경우 권한 상태를 바로 확인 못해도 됨. 웹 개발자는
Notification.requestPermission()을 사용할 수 있고, 위 변경에 따라 실질 처리는 활성화 후에만 됨. 그때 permission이 진짜 "granted" 또는 "denied"임이 드러날 수 있고, 일반 "default"와 달리 진짜로 유저에게 묻지 않을 수도 있지만, 웹 개발자 코드에선 볼 수 없으니 문제 없음. -
그 외에는 알림 permission 상태 가져오기를 반환한다.
6.4.7. 웹 MIDI API
[DelayWhilePrerendering]
을 requestMIDIAccess()
에 추가하세요.
6.4.8. Idle Detection API
[DelayWhilePrerendering]
을 start()
에 추가하세요.
다른 주요 메서드인 IdleDetector.requestPermission()은
transient activation에 의존하지만, 명시 origin에 permission이 이미 부여됐더라도
프리렌더링 중엔 idle detector 시작을 지연시킴.
6.4.9. Generic Sensor API
start()
메서드 단계를 "state를 activating로 변경" 바로 뒤에 아래 단계를 삽입하세요:
-
this의 relevant global object의 navigable이 prerendering navigable이면, 다음 단계들을 this의 post-prerendering activation steps list에 추가하고 return.
-
this.
[[state]]가 "idle"이면 return.프리렌더 지연 중 stop() 호출 시, 활성화 때는 아무 일도 안 함.
6.4.10. Web NFC
[DelayWhilePrerendering]
을 write()
와 scan()
에 추가하세요.
6.4.11. 배터리 상태 API
getBattery()
메서드 단계를 수정하여, 다음 단계를 가장 앞에 추가합니다:
-
this의 relevant global object의 navigable이 prerendering navigable이면, 아래 단계를 this의 post-prerendering activation steps list에 추가하고 this.[[BatteryPromise]] 를 반환.
6.4.12. 스크린 오리엔테이션 API
-
promise를 새 promise로 둔다.
-
this의 relevant global object의 navigable이 prerendering navigable이면, 아래 단계를 this의 post-prerendering activation steps list에 추가하고 promise 반환.
-
user agent가 스크린 오리엔테이션 lock 지원이 안 되면, reject(promise, "
NotSupportedError"DOMException) 하고 promise 반환. -
해당 document의 active sandboxing flag set에 sandboxed orientation lock browsing context flag가 있거나, user agent가 pre-lock 조건을 만족하지 않으면, reject(promise, "
SecurityError"DOMException) 하고 promise 반환. -
document의 [[orientationPendingPromise]]를 promise로 설정.
[DelayWhilePrerendering]
을 unlock()
에 추가하세요.
이 마지막 수정은 screen.orientation.lock()
다음에 screen.orientation.unlock()
호출 시 예상되는 결과가 나오도록 보장한다.
6.4.13. 게임패드
getGamepads()
메서드 단계를 수정하여 아래 단계를 가장 앞에 추가합니다:
-
this의 relevant global object의 navigable이 prerendering navigable이면, 빈 시퀀스를 반환합니다.
gamepadconnected
와 gamepaddisconnected
이벤트에 대한 설명을 수정하여, Window
객체의 navigable이 prerendering navigable인 경우에는 이러한 이벤트를 dispatch하지 않아야 함을 명시합니다.
gamepadconnected
섹션을 다음과 같이 갱신하여, 모든 Document
document의 post-prerendering activation steps
list에 아래 단계를 추가합니다:
-
document가 "
gamepad" 기능을 allowed to use하고, document의 relevant settings object가 secure context이며, 연결된 게임패드가 있을 때, 각 연결된 게임패드에 대해 gamepadconnected 이벤트를 발생(document의 relevant global object 대상,GamepadEvent사용,gamepad속성은 연결된 게임패드 정보를 가진Gamepad새 객체로 초기화).
6.4.14. 암호화 미디어 확장(EME)
[DelayWhilePrerendering]
을 requestMediaKeySystemAccess()
에 추가합니다.
6.4.15. 미디어 자동재생
playing the media resource 구간을 수정하여, HTMLMediaElement
의 current playback position이 Document
가 prerendering
상태가 아닐 때만 단조롭게 증가하도록 명시하세요.
6.4.16. 미디어 캡처 및 스트림
[DelayWhilePrerendering]
을 getUserMedia(),
getUserMedia()
및 enumerateDevices()
에 추가합니다.
MediaDevices
섹션 내 디바이스 변경 알림 단계의 가장 앞에 아래 단계를 추가하세요:
-
this의 relevant global object의 navigable이 prerendering navigable이면 return.
6.4.17. Web Audio API
명세에서는 allowed to start라는 개념을 사용하지만, 자세한 동작은 구현자
정의 상태입니다.
프리렌더링 중 자동 재생을 막으려면 AudioContext
인터페이스 섹션에 아래 규칙을 추가하세요.
AudioContext
는 프리렌더링 중엔 allowed to start 상태가 될 수 없습니다.
또한 AudioContext()
생성자 단계에서, 객체 반환 전 아래 단계를 수행합니다.
-
만약 context가 오직 프리렌더링으로 인해 allowed to start가 아니라면, 아래 단계들을 context의 post-prerendering activation steps list에 추가합니다.
-
[[control thread state]] 를 context에 대해 running으로 설정하세요.
-
control 메시지 queue를 생성하여 context의 resume을 큐에 넣으세요.
-
개발자가 프리렌더링 중 resume()
을 호출할 수 있습니다. 이런 경우 context는 allowed
to start가 아니어서 위에서 Promise
를 [[pending resume promises]]
에 넣어두었다가, 위 활성화 단계에서 resolve 됩니다.
AudioScheduledSourceNode
인터페이스의 start(when)
및 AudioBufferSourceNode
의 start(when, offset, duration)
는 [[control thread state]]
를 변경할 수 있지만, context가 allowed
to start가 아니면 알고리즘에서 해당 상태 변경이 이루어지지 않습니다.
이는 context가 시작될 때 node가 자동으로 시작될 수 있으므로 별 문제가 되지 않습니다.
6.4.18. 오디오 출력 장치 API
[DelayWhilePrerendering]
을 selectAudioOutput()
에 추가하세요.
6.4.19. 푸시 API
[DelayWhilePrerendering]
을 subscribe()
에 추가하세요.
6.4.20. 백그라운드 fetch
[DelayWhilePrerendering]
을 fetch()
에 추가하세요.
6.4.21. 백그라운드 동기화
[DelayWhilePrerendering]
을 register()
에 추가하세요.
6.4.22. 스토리지 API
[DelayWhilePrerendering]
을 persist()
에 추가하세요.
6.4.23. WebUSB API
[DelayWhilePrerendering]
을 getDevices()
와 requestDevice()
에 추가하세요.
6.4.24. Web Bluetooth
[DelayWhilePrerendering]
을 getDevices()
와 requestDevice()
에 추가하세요.
6.4.25. WebHID API
[DelayWhilePrerendering]
을 getDevices()
와 requestDevice()
에 추가하세요.
6.4.26. WebXR 장치 API
[DelayWhilePrerendering]
을 requestSession()
에 추가하세요.
6.4.27. 자격 증명 관리
[DelayWhilePrerendering]
을 get(),
store(),
create()
에 추가하세요.
6.4.28. 웹 음성 API
[DelayWhilePrerendering]
을 speak(utterance),
cancel(),
pause(),
resume()
에 추가하세요.
[DelayWhilePrerendering]
을 start(),
stop(),
abort()
에 추가하세요.
6.4.29. 웹 락 API
[DelayWhilePrerendering]
을 request(name, callback),
request(name, options, callback),
query()
에 추가하세요.
6.4.30. 커스텀 스킴 핸들러
registerProtocolHandler(scheme, url)
메서드 단계를 수정하여, in parallel 가기 전 단계들을 아래로 교체합니다:
-
(normalizedScheme, normalizedURLString)을 normalize protocol handler parameters (scheme, url, this의 relevant settings object) 결과로 둡니다.
-
this의 relevant global object의 navigable이 prerendering navigable이면, 아래 단계를 this의 post-prerendering activation steps list에 추가하고 return.
unregisterProtocolHandler(scheme, url)
메서드 단계를 수정하여, in parallel 가기 전 단계들을 아래와 같이 교체하세요:
-
(normalizedScheme, normalizedURLString)을 normalize protocol handler parameters(scheme, url, this의 relevant settings object) 결과로 둡니다.
-
this의 relevant global object의 navigable이 prerendering navigable이면, 아래 단계를 this의 post-prerendering activation steps list에 추가하고 return.
6.5. 암묵적으로 제한된 API
일부 API는 별도의 수정이 필요하지 않습니다. 왜냐하면 prerendering navigable이나 그 active window, 또는 active document가 결코 갖지 않는 속성이 없으면 자동으로 실패하거나 no-op 동작을 하기 때문입니다. 이런 속성에는 다음이 포함됩니다:
어떤 API들이 점검(감사) 되었는지 보이기 위해, 여기 확인된 API들을 나열합니다.
transient activation 또는 sticky activation이 필요한 API:
-
beforeunload이벤트로 생성되는 프롬프트 [HTML] -
element.requestFullscreen()[FULLSCREEN]-
navigator.keyboard.lock()[KEYBOARD-LOCK], 전체화면이 필요한 경우[KEYBOARD-LOCK]은 브라우징 컨텍스트가 쉽게 키보드 락을 활성화하도록 허용하지만, 전체화면이 아니면 효과가 없으며, 전체화면은 사용자 제스처가 필요합니다. 이 동작이 변경된다면 재논의가 필요합니다.
-
-
showOpenFilePicker(),showSaveFilePicker(),showDirectoryPicker()[FILE-SYSTEM-ACCESS] -
클립보드 이벤트 발생 [CLIPBOARD-APIS]
system focus가 필요한 API:
-
비동기 클립보드 API:
navigator.clipboard.read(),navigator.clipboard.readText(),navigator.clipboard.write(),navigator.clipboard.writeText()[CLIPBOARD-APIS]
"visible" visibility state가 필요한 API:
보다 복잡한 경우:
-
Request Picture-in-Picture는
video.requestPictureInPicture()호출에 의해, transient activation 또는 visibility state가 "visible"이었던 적이 있어야 함. [PICTURE-IN-PICTURE]
7. 보안 고려사항
HTML § 7.6.5 Security considerations를 참고하세요.
No-Vary-Search와 함께 쓸 경우의 명세 통합 보안 고려는 No-Vary-Search Security considerations를 참고하세요.
prerendering에 고유한 보안 사항을 별도로 추가해야 합니다. issue #319 참조.
8. 프라이버시 고려사항
HTML § 7.6.6 Privacy considerations를 참고하세요.
No-Vary-Search와 함께 쓸 경우의 명세 통합 프라이버시 고려는 No-Vary-Search Privacy considerations를 참고하세요.
prerendering 전용 프라이버시 고려를 별도로 추가해야 합니다. issue #319 참조. 한 가지 특히 주목할 점은 cross-partition prerendering이 프라이버시 복잡성 때문에 그냥 금지되어 있다는 것입니다.