1. 소개
이 섹션은 비규범적입니다.
웹 번들로 서브리소스 로딩하기 명세는 여러 리소스를 하나의 번들로 묶을 수 있는 포맷(Web Bundles)을 사용하여 다수의 리소스를 효율적으로 로딩하는 방법을 설명합니다. 이 명세는 웹 브라우저가 이러한 리소스를 어떻게 로딩하는지 기술하며, 여기 정의된 알고리즘을 호출하는 [HTML], [FETCH], [CSP] 명세에 대한 여러 몽키패치(monkeypatches)로 구성되어 있습니다.
참고: 이 명세는 작성 중입니다. #708을 참고하세요.
2. 구조
가져온 웹 번들(fetched web bundle)은 [draft-ietf-wpack-bundled-responses-latest]에서 정의된 웹 번들 포맷의 표현입니다.
웹 번들 fetch 엔트리(web bundle fetch entry)는 다음 항목을 갖는 struct입니다.
-
source: 웹 번들의 URL
-
credentials: credentials mode
-
state: 내부 상태이며, "fetching", "fetched", 또는 "failed" 중 하나입니다. 초기값은 "fetching"입니다.
-
fetched bundle: 가져온 웹 번들(fetched web bundle) 또는 null
웹 번들 fetch 엔트리의 더 나은 이름?
웹 번들 fetch 엔트리 entry는, 문서(Document) document의 웹 번들 등록 리스트(web bundle registration list)가 웹 번들 등록(web bundle registration)을 fetch entry가 entry인 경우 등록에 의해 사용됨(used by a registration)이라 부릅니다.
번들 규칙(bundle rule)은 다음 항목을 갖는 struct입니다.
웹 번들 등록(web bundle registration)은 다음 항목을 갖는 struct입니다.
-
fetch entry: 웹 번들 fetch 엔트리
-
rule: 번들 규칙(bundle rule)
웹 번들 파싱 결과(web bundle parse result)는 다음 항목을 갖는 struct입니다.
-
source: 웹 번들의 URL
-
credentials: credentials mode
-
rule: 번들 규칙(bundle rule)
각 환경 설정 객체(environment settings object)는, 웹 번들 등록 리스트 반환 알고리즘(web bundle registration list)을 가지게 되며, 웹 번들 등록 리스트를 반환합니다.
Document는
웹 번들 등록 리스트(web bundle registration list)를 가지며, 이는 웹 번들 등록 리스트이고,
초기값은 빈 리스트입니다.
윈도우 환경 설정 객체를 설정할 때, settings object의 웹 번들 등록 리스트는 window의 문서의 웹 번들 등록 리스트를 반환합니다.
워커 환경 설정 객체를 설정할 때, settings object의 웹 번들 등록 리스트는 빈 리스트를 반환합니다.
Document는
웹 번들 fetch 엔트리 리스트(web bundle fetch entry list)를 가지며, 이는
웹 번들 fetch 엔트리
리스트이고, 초기값은 빈 리스트입니다.
list가 웹 번들 fetch 엔트리 리스트에 사용되지만, 순서는 중요하지 않을 수 있습니다.
3. HTML 몽키패치
스크립트 요소 준비 알고리즘 (prepare the script element)에서 웹 번들을 기존 스크립트 타입(클래식, 모듈 타입 등)과 일관성 있게 처리하기 위해 다음과 같이 변경합니다.
-
스크립트의 타입은 "classic", "module", "webbundle" 중 하나가 될 수 있습니다.
-
웹 번들 결과(web bundle result)를 도입하며, 이는 두 개의 항목을 가지는 struct입니다.
-
registration: 웹 번들 등록(web bundle registration)
-
error to rethrow: null이 아닐 때 파싱 에러를 나타내는 JavaScript 값
-
-
스크립트의 실행 결과는 "uninitiated", null, script, 또는 웹 번들 결과(web bundle result)가 될 수 있습니다.
참고: 웹 번들 결과를 script의 새로운 서브클래스로 정의하지 않으므로, 다른 스크립트 실행 관련 명세에는 영향을 주지 않습니다.
3.1. 스크립트 요소 준비
스크립트 요소 준비 알고리즘 내부에서 다음과 같이 변경합니다.
-
스크립트 요소 준비 10단계에 다음 단계를 삽입합니다.
-
스크립트 블록의 타입 문자열이 "
webbundle"와 ASCII 대소문자 무시로 일치하는 경우, el의 타입을 "webbundle"으로 설정합니다.
-
-
스크립트 요소 준비 26.7단계에 다음 case를 삽입합니다.
-
"
webbundle":-
작업 큐에 추가하여, 요소에 error 이벤트 발생 및 반환
참고:
<script type="webbundle" src=...>는 지원하지 않습니다. 여기서는 에러 처리를 위한 특별한 요구사항이 없으므로,src속성이 비어있는 경우와 같이error이벤트만 발생합니다.
-
-
-
스크립트 요소 준비 27.2단계에 다음 case를 삽입합니다.
-
"
webbundle":-
웹 번들 준비를 element, source text 및 base URL로 실행
-
-
-
스크립트 요소 준비 28단계에 다음 case를 삽입합니다.
-
만약 스크립트의 타입이 "
webbundle"이면:-
단언: 스크립트의 parser-executed 준비 상태가 true여야 합니다.
-
병렬로 웹 번들에 대한 이벤트 처리 실행, element 전달
-
-
참고: CSP는 15단계(스크립트 요소 준비)에서 인라인 웹 번들에도 적용되며, 클래식/모듈 스크립트와 동일하게 적용됩니다.
웹 번들 준비(prepare a web
bundle): HTMLScriptElement
element, string sourceText, URL baseURL을
인자로 받음:
-
parse result를 웹 번들 문자열 파싱(sourceText, baseURL 사용) 결과로 설정
-
예외가 발생한다면:
-
스크립트의 실행 결과를 웹 번들 결과(registration: null, error to rethrow: 예외값)로 설정
-
return
-
-
document를 element의 node document로 설정
-
fetch entry를 null로 설정
-
document의 웹 번들 fetch 엔트리 리스트의 각 r에 대해:
-
만약 r의 source가 parse result의 source와 같고, r의 credentials가 parse result의 credentials와 같다면:
-
만약 r이 document에서 등록에 의해 사용됨이 아니라면, fetch entry를 r로 설정
참고: 즉, 웹 번들 fetch 엔트리를 사용하는 다른 스크립트 요소가 제거된 상황을 의미합니다. 동일한 웹 번들 source와 credentials로
HTMLScriptElement가 삭제되었다가 다시 추가되어도, fetch 엔트리가 재구축되지 않고 재사용됩니다.
-
-
-
fetch entry가 null이라면:
-
fetch entry를 (source: parse result의 source, credentials: parse result의 credentials, state: "fetching", fetched bundle: null)로 새 웹 번들 fetch 엔트리 생성
-
추가 (document의 웹 번들 fetch 엔트리 리스트에 fetch entry)
-
병렬로 웹 번들 fetch 실행, fetch entry 인자로 전달
-
-
registration을 (fetch entry: fetch entry, rule: parse result의 rule)로 새 웹 번들 등록 생성
-
추가 (document의 웹 번들 등록 리스트에 registration)
-
스크립트의 실행 결과를 (registration: registration, error to rethrow: null)로 새 웹 번들 결과로 설정
3.2. 이벤트 발생
스크립트 요소 실행에서, Step 6에 다음 case를 추가합니다.
-
"
webbundle":-
단언: 절대 도달하지 않음.
참고: 웹 번들은 웹 번들 이벤트 처리(process events for a web bundle)에서 처리되며, 스크립트 요소 실행에서는 처리되지 않습니다.
-
웹 번들 이벤트
처리 알고리즘, HTMLScriptElement
element를 입력값으로 받음:
-
result는 element의 스크립트 실행 결과로 설정.
-
단언: element의 스크립트 타입은 "
webbundle"임. -
단언: result는 웹 번들 결과임.
-
다음 조건 중 하나가 충족될 때까지 비동기로 대기:
-
result의 error to rethrow가 null이 아님
-
result의 registration이 null이 아니고, result의 registration의 fetch entry의 state가 "fetched" 또는 "failed"가 됨.
참고: 다른 스크립트 타입들과 달리, 여기서는 웹 번들 fetch를 기다린 뒤에
HTMLScriptElement에load이벤트를 발생시킵니다. (load 이벤트 딜레이는 사용하지 않음; 준비 단계에서 동기적으로 mark as ready가 호출되기 때문임) 이는 웹 번들 fetch가 preloading과 비슷한 성격임을 반영한 것입니다. -
-
스크립트 실행 결과가 null이면 return.
참고: element가 이전 단계 도중에 문서에서 제거된 경우 발생할 수 있습니다.
참고: 이것은 whatwg/html#2673과 일관되게 지정됨. 현재 이 경우에는
error이벤트를 발생시키지 않음. 만약 whatwg/html#2673에서 에러 이벤트를 발생시키도록 변경된다면 이 단계도 수정할 것. -
단언: element의 node document가 element의 preparation-time document와 동일함.
-
result의 error to rethrow가 null이 아니면:
-
예외 리포트 실행 (인자: result의 error to rethrow)
script에 해당하는 값이 없음(웹 번들 결과는 script가 아님). 이 부분은 whatwg/html#958이 해결된 후에 변경 필요.
-
Return.
-
-
단언: result의 registration이 null이 아님.
-
result의 registration의 fetch entry의 state가 "failed"이면:
-
error 이벤트 발생 (element 대상)
-
Return.
-
-
단언: result의 registration의 fetch entry의 state가 "fetched".
-
load 이벤트 발생 (element 대상)
3.3. 제거
script 요소가 문서에서
제거될 때, user agent는 다음 알고리즘을 실행해야 합니다.
-
스크립트 타입이 "
webbundle"이 아니면 return. -
스크립트 실행 결과가 null이면 return.
-
스크립트 실행 결과는 웹 번들 결과여야 함.
-
registration을 스크립트 실행 결과의 registration으로 설정.
-
스크립트 실행 결과를 null로 설정.
-
registration이 null이면 return.
-
document를 node document로 설정.
-
단언: document의 웹 번들 등록 리스트에 registration이 포함됨.
-
웹 번들 등록 리스트에서 registration 제거.
-
마이크로태스크 큐에 다음 단계를 수행하도록 큐잉:
-
fetch entry를 registration의 fetch entry로 설정
-
fetch entry가 document 내 다른 등록(registration)에 의해 사용 중이면 return.
-
fetch entry 리스트에서 fetch entry 제거.
참고: fetch entry가 여러
script요소의 등록에서 공유되어 해당 script들이 제거되었을 때, 이미 리스트에 포함되지 않을 수 있습니다.참고: 이 시점에서 fetch entry는 추가 fetch나 웹 번들 준비에 사용될 수 없으나, 가져온 번들(fetched bundle)은 여전히 진행 중인 fetch에서 활용될 수 있음.
-
4. Fetch 몽키패치
4.1. Fetch 몽키패치
fetch 알고리즘에서,
Let taskDestination be null.
이 전에 다음 단계를 추가합니다.
-
find a matching web bundle registration 결과가 null이면 request의 service-workers mode를 "
none"으로 설정.
참고: 이는 웹번들 서브리소스 요청은 서비스워커에서 이벤트를 받지 않는다는 의미입니다.
4.2. Fetch scheme 몽키패치
fetch
scheme에 "uuid-in-package"를 추가합니다.
참고: 이렇게 하면 navigate 알고리즘이 uuid-in-package: URL에 대해 process a navigate fetch 알고리즘을 사용하도록 보장합니다.
참고: "uuid-in-package" 스킴의 URL origin은
opaque origin입니다.
4.3. HTTP-network-or-cache fetch 몽키패치
HTTP-network-or-cache fetch에서,
8.22. Set httpCache to the result of determining the HTTP cache partition, given httpRequest.
이전에 다음 단계를 추가합니다.
-
response를 웹 번들에서 서브리소스 fetch 결과로 설정 (httpRequest 인자)
-
response가 네트워크 에러면, network error 반환
-
response가 null이 아니면, 8.22~8.24 단계를 건너뛰고 step 9로 이동
참고: 즉, 웹번들에서의 서브리소스는 HttpCache와 상호작용하지 않습니다. 향후 HttpCache 관련 기능은 계획 중입니다.
-
5. CSP 몽키패치
5.1. 요청이 소스 목록과 일치하는지 몽키패치
Does request match source list?를 다음 단계로 재정의:
-
url을 request의 current url로 설정
-
url의 scheme이 "
uuid-in-package"이면:-
registration을 find a matching web bundle registration 결과로 설정 (request 인자)
-
registration이 null이 아니면 url을 registration의 fetch entry의 source로 설정
-
-
Does url match source list in origin with redirect count?를 url, source list, policy의 self-origin, request의 redirect count로 실행한 결과를 반환
참고: CSP는 uuid-in-package: URL이 아니라 번들의 URL을
기준으로 평가됩니다. 동기는 #651 참고.
5.2. 응답이 소스 목록과 일치하는지 몽키패치
Does response to request match source list?를 다음 단계로 재정의:
-
url을 response의 url로 설정
-
url의 scheme이 "
uuid-in-package"이면:-
registration을 find a matching web bundle registration 결과(request 인자)를 저장
-
registration이 null이 아니면 url을 registration의 fetch entry의 source로 설정
-
-
Does url match source list in origin with redirect count?를 url, source list, policy의 self-origin, request의 redirect count로 실행한 결과 반환
참고: CSP는 uuid-in-package: URL이 아니라 번들의 URL로
평가됩니다. 동기는 #651 참고.
6. 알고리즘
6.1. 파싱
웹 번들 문자열을 파싱하려면, 문자열 sourceText와 URL baseURL이 주어졌을 때:
-
parsed를 JSON을 Infra 값으로 파싱하는 결과로 한다. 입력은 sourceText이다.
-
parsed가 맵이 아니라면,
TypeError예외를 던진다. 최상위 값은 JSON 객체이어야 한다고 알린다. -
source를 파싱 (parsed["
source"]와 baseURL을 기준으로) -
source가 null이면,
TypeError를 던진다. -
credentials를 "
same-origin"으로 한다. -
parsed["
credentials"]가 존재하면:-
parsed["
credentials"]가 "omit"이면 credentials를 "omit"로 설정한다. -
아니고 parsed["
credentials"]가 "include"이면 credentials를 "include"로 설정한다.
-
-
resources를 빈 리스트로 한다.
-
parsed["
resources"]가 존재하면:-
resources를 URL 리스트 파싱 결과로 덮어쓴다. 입력값은 parsed["
resources"], source이다.
-
scopes를 빈 리스트로 한다.
-
parsed["
scopes"]가 존재하면:-
scopes를 URL 리스트 파싱 결과로 덮어쓴다. 입력값은 parsed["
scopes"], source이다.
-
parsed의 키들이 "
source", "credentials", "resources", "scopes" 외의 항목을 포함 하면, 웹 번들 문자열에 유효하지 않은 최상위 키가 있었음을 콘솔에 경고로 보고한다.참고: 오타 감지에 도움이 된다. 오류로 간주하지 않는 이유는, 추후 확장성과의 호환을 막지 않기 위함이다.
-
웹 번들 파싱 결과를 반환한다. source는 source, credentials는 credentials, rule은 rule이다.
URL 리스트 파싱을 하려면, 리스트 originalList와 URL baseURL이 주어졌을 때:
-
parsed URL list를 빈 리스트로 한다.
-
각 item을 originalList에서 반복하여,
-
item이 문자열이면
-
URL을 파싱 결과로 한다. 입력값은 item, baseURL이다.
-
URL이 null이 아니면, URL을 parsed URL list에 추가한다.
-
-
-
parsed URL list를 반환한다.
6.2. 웹 번들 가져오기
웹 번들 가져오기를 하려면, 웹 번들 fetch 엔트리 fetch entry와 fetch 파라미터 fetch params가 주어졌을 때:
-
단언: fetch entry의 state는 "fetching"이다.
-
request를 fetch params의 request로 한다.
-
request의 url을 fetch entry의 source로 설정한다.
참고: 소스 URL은 문서의 base URL을 기준으로 결정된다.
-
request의 destination을 "webbundle"로 설정한다,
-
request의 mode를 "cors"로 설정한다,
-
request의 credentials mode를 fetch entry의 credentials로 설정한다.
-
request의 service-workers mode를 "
none"으로 설정한다. -
헤더("Accept", "application/webbundle;v=b2")를 request의 header list에 추가한다.
참고: 최종 [draft-ietf-wpack-bundled-responses-latest]는
1버전을 사용하지만, 현재 명세는 브라우저 구현에서 실제 사용 중인 draft 버전을 기준으로 한다. -
Fetch request를 하고, processResponse 알고리즘을 process web bundle response로 적용, 이때 fetch entry를 인자로 준다.
참고: 크로미움의 현재 구현에서는 중첩 번들을 허용하지 않는다. 웹 번들은 다른 웹 번들에서 가져오지 않는다.
6.3. 웹 번들 응답 처리
웹 번들 응답 처리를 하려면 웹 번들 fetch entry fetch entry와 response response가 주어졌을 때:
-
response의 status가 ok status이면,
-
response의 body를 웹 번들로 파싱한다 ([draft-ietf-wpack-bundled-responses-latest]).
참고: response의 body는 이 시점에 완전히 사용 가능하지 않을 수 있다. UA가 body를 점진적으로 비동기적으로 읽으며 일부 서브리소스를 빠르게 서비스할 수 있다.
참고: 파싱 시 크로미움의 실험적 구현은 "b2"만 웹 번들 포맷 버전으로 허용한다 ([draft-ietf-wpack-bundled-responses-latest]).
-
파싱 알고리즘이 비동기적으로 완료되면 fetch entry의 fetched bundle에 파싱 결과를 넣고, fetch entry의 state를 "fetched"로 한다. 파싱 실패나 조건 불충족시 fetched bundle은 null로, state는 "failed"로 한다.
-
-
그 외의 경우, fetch entry의 state를 "failed"로 한다.
6.4. 웹 번들에서 서브리소스 가져오기
웹 번들에서 서브리소스를 가져오기를 하려면 요청 httpRequest가 주어졌을 때:
-
registration을 적합한 웹 번들 등록 찾기를 httpRequest에 대해 실행 결과로 한다.
-
registration이 null이 아니면:
-
response를 웹 번들 fetch entry에서 응답 얻기 실행 결과로 한다. 입력값은 httpRequest의 url 및 registration의 fetch entry이다.
-
response가 null이면 네트워크 에러를 반환한다.
참고: 브라우저는 서브리소스를 네트워크로 가져오는 fallback을 수행하지 않음을 의미한다.
-
그렇지 않으면 response를 반환한다.
-
-
null을 반환한다.
참고: 여기서 null을 반환하면 HTTP 캐시 및 일반 네트워크 패치로 fallback 처리 가능. 위의 네트워크 에러 반환과는 다르다.
웹 번들 fetch entry에서 응답 얻기를 하려면 url url과 웹 번들 fetch entry fetch entry가 주어졌을 때:
-
fetch entry의 state가 "fetching"이면 state가 "fetched" 또는 "failed"가 될 때까지 비동기적으로 대기한다.
-
fetch entry의 state가 "failed"이면 null을 반환한다.
-
단언: fetch entry의 fetched bundle은 null이 아니다.
-
response를 fetch entry의 fetched bundle에서 url로 가져와 반환한다 ([draft-ietf-wpack-bundled-responses-latest]). url에 해당하는 표현이 fetched bundle에 없으면 null을 반환한다.
6.5. 적합한 등록 찾기
적합한 웹 번들 등록 찾기를 하려면 요청 httpRequest가 주어졌을 때: