웹 번들로 서브리소스 로딩하기

커뮤니티 그룹 초안 보고서,

이 버전:
https://wicg.github.io/webpackage/subresource-loading.html
이슈 트래킹:
GitHub
명세 내 인라인
편집자:
(Google Inc.)
(Google)

초록

UA가 웹 번들에서 서브리소스를 어떻게 로드하는지에 대해 설명합니다.

이 문서의 상태

이 명세는 웹 플랫폼 인큐베이터 커뮤니티 그룹에서 발행하였습니다. 이는 W3C 표준이 아니며 W3C 표준 트랙에도 포함되어 있지 않습니다. W3C 커뮤니티 기여자 라이선스 계약(CLA) 하에서는 제한적 옵트아웃과 기타 조건이 적용됩니다. W3C 커뮤니티와 비즈니스 그룹에 대해 더 알아보세요.

1. 소개

이 섹션은 비규범적입니다.

웹 번들로 서브리소스 로딩하기 명세는 여러 리소스를 하나의 번들로 묶을 수 있는 포맷(Web Bundles)을 사용하여 다수의 리소스를 효율적으로 로딩하는 방법을 설명합니다. 이 명세는 웹 브라우저가 이러한 리소스를 어떻게 로딩하는지 기술하며, 여기 정의된 알고리즘을 호출하는 [HTML], [FETCH], [CSP] 명세에 대한 여러 몽키패치(monkeypatches)로 구성되어 있습니다.

참고: 이 명세는 작성 중입니다. #708을 참고하세요.

2. 구조

가져온 웹 번들(fetched web bundle)[draft-ietf-wpack-bundled-responses-latest]에서 정의된 웹 번들 포맷의 표현입니다.

웹 번들 fetch 엔트리(web bundle fetch entry)는 다음 항목을 갖는 struct입니다.

웹 번들 fetch 엔트리의 더 나은 이름?

웹 번들 fetch 엔트리 entry는, 문서(Document) document웹 번들 등록 리스트(web bundle registration list)웹 번들 등록(web bundle registration)fetch entryentry인 경우 등록에 의해 사용됨(used by a registration)이라 부릅니다.

번들 규칙(bundle rule)은 다음 항목을 갖는 struct입니다.

웹 번들 등록(web bundle registration)은 다음 항목을 갖는 struct입니다.

웹 번들 파싱 결과(web bundle parse result)는 다음 항목을 갖는 struct입니다.

환경 설정 객체(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 엔트리 리스트에 사용되지만, 순서는 중요하지 않을 수 있습니다.

워커(worker)에서는 지원되지 않습니다.

3. HTML 몽키패치

스크립트 요소 준비 알고리즘 (prepare the script element)에서 웹 번들을 기존 스크립트 타입(클래식, 모듈 타입 등)과 일관성 있게 처리하기 위해 다음과 같이 변경합니다.

참고: 웹 번들 결과script의 새로운 서브클래스로 정의하지 않으므로, 다른 스크립트 실행 관련 명세에는 영향을 주지 않습니다.

3.1. 스크립트 요소 준비

스크립트 요소 준비 알고리즘 내부에서 다음과 같이 변경합니다.

참고: CSP는 15단계(스크립트 요소 준비)에서 인라인 웹 번들에도 적용되며, 클래식/모듈 스크립트와 동일하게 적용됩니다.

웹 번들 준비(prepare a web bundle): HTMLScriptElement element, string sourceText, URL baseURL을 인자로 받음:

  1. parse result웹 번들 문자열 파싱(sourceText, baseURL 사용) 결과로 설정

  2. 예외가 발생한다면:

    1. 스크립트의 실행 결과웹 번들 결과(registration: null, error to rethrow: 예외값)로 설정

    2. 준비된 상태로 표시

    3. return

  3. documentelementnode document로 설정

  4. fetch entry를 null로 설정

  5. document웹 번들 fetch 엔트리 리스트의 각 r에 대해:

    1. 만약 rsourceparse resultsource와 같고, rcredentialsparse resultcredentials와 같다면:

      1. 만약 rdocument에서 등록에 의해 사용됨이 아니라면, fetch entryr로 설정

        참고: 즉, 웹 번들 fetch 엔트리를 사용하는 다른 스크립트 요소가 제거된 상황을 의미합니다. 동일한 웹 번들 sourcecredentialsHTMLScriptElement가 삭제되었다가 다시 추가되어도, fetch 엔트리가 재구축되지 않고 재사용됩니다.

  6. fetch entry가 null이라면:

    1. fetch entry를 (source: parse resultsource, credentials: parse resultcredentials, state: "fetching", fetched bundle: null)로 새 웹 번들 fetch 엔트리 생성

    2. 추가 (document웹 번들 fetch 엔트리 리스트fetch entry)

    3. 병렬로 웹 번들 fetch 실행, fetch entry 인자로 전달

  7. registration을 (fetch entry: fetch entry, rule: parse resultrule)로 새 웹 번들 등록 생성

  8. 추가 (document웹 번들 등록 리스트registration)

  9. 스크립트의 실행 결과를 (registration: registration, error to rethrow: null)로 새 웹 번들 결과로 설정

  10. 준비된 상태로 표시

3.2. 이벤트 발생

스크립트 요소 실행에서, Step 6에 다음 case를 추가합니다.

웹 번들 이벤트 처리 알고리즘, HTMLScriptElement element를 입력값으로 받음:

  1. resultelement스크립트 실행 결과로 설정.

  2. 단언: element스크립트 타입은 "webbundle"임.

  3. 단언: result웹 번들 결과임.

  4. 다음 조건 중 하나가 충족될 때까지 비동기로 대기:

    참고: 다른 스크립트 타입들과 달리, 여기서는 웹 번들 fetch를 기다린 뒤에 HTMLScriptElementload 이벤트를 발생시킵니다. (load 이벤트 딜레이는 사용하지 않음; 준비 단계에서 동기적으로 mark as ready가 호출되기 때문임) 이는 웹 번들 fetch가 preloading과 비슷한 성격임을 반영한 것입니다.

  5. 스크립트 실행 결과가 null이면 return.

    참고: element가 이전 단계 도중에 문서에서 제거된 경우 발생할 수 있습니다.

    참고: 이것은 whatwg/html#2673과 일관되게 지정됨. 현재 이 경우에는 error 이벤트를 발생시키지 않음. 만약 whatwg/html#2673에서 에러 이벤트를 발생시키도록 변경된다면 이 단계도 수정할 것.

  6. 단언: elementnode documentelementpreparation-time document와 동일함.

  7. resulterror to rethrow가 null이 아니면:

    1. 예외 리포트 실행 (인자: resulterror to rethrow)

      script에 해당하는 값이 없음(웹 번들 결과는 script가 아님). 이 부분은 whatwg/html#958이 해결된 후에 변경 필요.

    2. Return.

  8. 단언: resultregistration이 null이 아님.

  9. resultregistrationfetch entrystate가 "failed"이면:

    1. error 이벤트 발생 (element 대상)

    2. Return.

  10. 단언: resultregistrationfetch entrystate가 "fetched".

  11. load 이벤트 발생 (element 대상)

3.3. 제거

script 요소가 문서에서 제거될 때, user agent는 다음 알고리즘을 실행해야 합니다.

  1. 스크립트 타입이 "webbundle"이 아니면 return.

  2. 스크립트 실행 결과가 null이면 return.

  3. 스크립트 실행 결과웹 번들 결과여야 함.

  4. registration스크립트 실행 결과registration으로 설정.

  5. 스크립트 실행 결과를 null로 설정.

  6. registration이 null이면 return.

  7. documentnode document로 설정.

  8. 단언: document웹 번들 등록 리스트registration이 포함됨.

  9. 웹 번들 등록 리스트에서 registration 제거.

  10. 마이크로태스크 큐에 다음 단계를 수행하도록 큐잉:

    1. fetch entryregistrationfetch entry로 설정

    2. fetch entrydocument 내 다른 등록(registration)에 의해 사용 중이면 return.

    3. fetch entry 리스트에서 fetch entry 제거.

      참고: fetch entry가 여러 script 요소의 등록에서 공유되어 해당 script들이 제거되었을 때, 이미 리스트에 포함되지 않을 수 있습니다.

      참고: 이 시점에서 fetch entry는 추가 fetch나 웹 번들 준비에 사용될 수 없으나, 가져온 번들(fetched bundle)은 여전히 진행 중인 fetch에서 활용될 수 있음.

4. Fetch 몽키패치

4.1. Fetch 몽키패치

fetch 알고리즘에서,

  1. Let taskDestination be null.

이 전에 다음 단계를 추가합니다.

  1. find a matching web bundle registration 결과가 null이면 requestservice-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.

이전에 다음 단계를 추가합니다.

  1. response웹 번들에서 서브리소스 fetch 결과로 설정 (httpRequest 인자)

    1. response네트워크 에러면, network error 반환

    2. response가 null이 아니면, 8.22~8.24 단계를 건너뛰고 step 9로 이동

      참고: 즉, 웹번들에서의 서브리소스는 HttpCache와 상호작용하지 않습니다. 향후 HttpCache 관련 기능은 계획 중입니다.

5. CSP 몽키패치

5.1. 요청이 소스 목록과 일치하는지 몽키패치

Does request match source list?를 다음 단계로 재정의:

  1. urlrequestcurrent url로 설정

  2. urlscheme이 "uuid-in-package"이면:

    1. registrationfind a matching web bundle registration 결과로 설정 (request 인자)

    2. registration이 null이 아니면 urlregistrationfetch entrysource로 설정

  3. Does url match source list in origin with redirect count?url, source list, policyself-origin, requestredirect count로 실행한 결과를 반환

참고: CSP는 uuid-in-package: URL이 아니라 번들의 URL을 기준으로 평가됩니다. 동기는 #651 참고.

5.2. 응답이 소스 목록과 일치하는지 몽키패치

Does response to request match source list?를 다음 단계로 재정의:

  1. urlresponseurl로 설정

  2. urlscheme이 "uuid-in-package"이면:

    1. registrationfind a matching web bundle registration 결과(request 인자)를 저장

    2. registration이 null이 아니면 urlregistrationfetch entrysource로 설정

  3. Does url match source list in origin with redirect count?url, source list, policyself-origin, requestredirect count로 실행한 결과 반환

참고: CSP는 uuid-in-package: URL이 아니라 번들의 URL로 평가됩니다. 동기는 #651 참고.

6. 알고리즘

6.1. 파싱

웹 번들 문자열을 파싱하려면, 문자열 sourceTextURL baseURL이 주어졌을 때:

  1. parsedJSON을 Infra 값으로 파싱하는 결과로 한다. 입력은 sourceText이다.

  2. parsed이 아니라면, TypeError 예외를 던진다. 최상위 값은 JSON 객체이어야 한다고 알린다.

  3. parsed["source"]가 존재하지 않으면 TypeError를 던진다.

  4. parsed["source"]가 문자열이 아니라면, TypeError를 던진다.

  5. source파싱 (parsed["source"]와 baseURL을 기준으로)

  6. source가 null이면, TypeError를 던진다.

  7. credentials를 "same-origin"으로 한다.

  8. parsed["credentials"]가 존재하면:

    1. parsed["credentials"]가 "omit"이면 credentials를 "omit"로 설정한다.

    2. 아니고 parsed["credentials"]가 "include"이면 credentials를 "include"로 설정한다.

  9. resources를 빈 리스트로 한다.

  10. parsed["resources"]가 존재하면:

    1. parsed["resources"]가 리스트가 아니면, TypeError를 던진다.

    2. resourcesURL 리스트 파싱 결과로 덮어쓴다. 입력값은 parsed["resources"], source이다.

  11. scopes를 빈 리스트로 한다.

  12. parsed["scopes"]가 존재하면:

    1. parsed["scopes"]가 리스트가 아니면, TypeError를 던진다.

    2. scopesURL 리스트 파싱 결과로 덮어쓴다. 입력값은 parsed["scopes"], source이다.

  13. parsed키들이 "source", "credentials", "resources", "scopes" 외의 항목을 포함 하면, 웹 번들 문자열에 유효하지 않은 최상위 키가 있었음을 콘솔에 경고로 보고한다.

    참고: 오타 감지에 도움이 된다. 오류로 간주하지 않는 이유는, 추후 확장성과의 호환을 막지 않기 위함이다.

  14. rule번들 규칙으로 한다. 리소스resources, 스코프scopes이다.

  15. 웹 번들 파싱 결과를 반환한다. sourcesource, credentialscredentials, rulerule이다.

URL 리스트 파싱을 하려면, 리스트 originalListURL baseURL이 주어졌을 때:

  1. parsed URL list를 빈 리스트로 한다.

  2. itemoriginalList에서 반복하여,

    1. item문자열이면

      1. URL파싱 결과로 한다. 입력값은 item, baseURL이다.

      2. URL이 null이 아니면, URL을 parsed URL list에 추가한다.

  3. parsed URL list를 반환한다.

6.2. 웹 번들 가져오기

웹 번들 가져오기를 하려면, 웹 번들 fetch 엔트리 fetch entryfetch 파라미터 fetch params가 주어졌을 때:

  1. 단언: fetch entrystate는 "fetching"이다.

  2. requestfetch paramsrequest로 한다.

  3. requesturlfetch entrysource로 설정한다.

    참고: 소스 URL은 문서의 base URL을 기준으로 결정된다.

  4. requestdestination을 "webbundle"로 설정한다,

  5. requestmode를 "cors"로 설정한다,

  6. requestcredentials modefetch entrycredentials로 설정한다.

  7. requestservice-workers mode를 "none"으로 설정한다.

  8. 헤더("Accept", "application/webbundle;v=b2")를 requestheader list에 추가한다.

    참고: 최종 [draft-ietf-wpack-bundled-responses-latest]1 버전을 사용하지만, 현재 명세는 브라우저 구현에서 실제 사용 중인 draft 버전을 기준으로 한다.

  9. Fetch request를 하고, processResponse 알고리즘을 process web bundle response로 적용, 이때 fetch entry를 인자로 준다.

    참고: 크로미움의 현재 구현에서는 중첩 번들을 허용하지 않는다. 웹 번들은 다른 웹 번들에서 가져오지 않는다.

6.3. 웹 번들 응답 처리

웹 번들 응답 처리를 하려면 웹 번들 fetch entry fetch entryresponse response가 주어졌을 때:

  1. responsestatusok status이면,

    1. responsebody를 웹 번들로 파싱한다 ([draft-ietf-wpack-bundled-responses-latest]).

      참고: response의 body는 이 시점에 완전히 사용 가능하지 않을 수 있다. UA가 body를 점진적으로 비동기적으로 읽으며 일부 서브리소스를 빠르게 서비스할 수 있다.

      참고: 파싱 시 크로미움의 실험적 구현은 "b2"만 웹 번들 포맷 버전으로 허용한다 ([draft-ietf-wpack-bundled-responses-latest]).

    2. 파싱 알고리즘이 비동기적으로 완료되면 fetch entryfetched bundle에 파싱 결과를 넣고, fetch entrystate를 "fetched"로 한다. 파싱 실패나 조건 불충족시 fetched bundle은 null로, state는 "failed"로 한다.

  2. 그 외의 경우, fetch entrystate를 "failed"로 한다.

6.4. 웹 번들에서 서브리소스 가져오기

웹 번들에서 서브리소스를 가져오기를 하려면 요청 httpRequest가 주어졌을 때:

  1. registration적합한 웹 번들 등록 찾기httpRequest에 대해 실행 결과로 한다.

  2. registration이 null이 아니면:

    1. response웹 번들 fetch entry에서 응답 얻기 실행 결과로 한다. 입력값은 httpRequesturlregistrationfetch entry이다.

    2. response가 null이면 네트워크 에러를 반환한다.

      참고: 브라우저는 서브리소스를 네트워크로 가져오는 fallback을 수행하지 않음을 의미한다.

    3. 그렇지 않으면 response를 반환한다.

  3. null을 반환한다.

참고: 여기서 null을 반환하면 HTTP 캐시 및 일반 네트워크 패치로 fallback 처리 가능. 위의 네트워크 에러 반환과는 다르다.

웹 번들 fetch entry에서 응답 얻기를 하려면 url url웹 번들 fetch entry fetch entry가 주어졌을 때:

  1. fetch entrystate가 "fetching"이면 state가 "fetched" 또는 "failed"가 될 때까지 비동기적으로 대기한다.

  2. fetch entrystate가 "failed"이면 null을 반환한다.

  3. 단언: fetch entryfetched bundle은 null이 아니다.

  4. responsefetch entryfetched bundle에서 url로 가져와 반환한다 ([draft-ietf-wpack-bundled-responses-latest]). url에 해당하는 표현이 fetched bundle에 없으면 null을 반환한다.

6.5. 적합한 등록 찾기

적합한 웹 번들 등록 찾기를 하려면 요청 httpRequest가 주어졌을 때:

  1. urlhttpRequesturl로 한다.

  2. registrationhttpRequest클라이언트웹 번들 등록 리스트에서 반복한다:

    1. ruleregistrationrule로 한다.

    2. urlscheme이 "uuid-in-package"가 아니라면,

      1. urloriginregistrationfetch entrysourceorigin동일 출처가 아니면 계속한다.

      2. allowed path단축(registrationfetch entrysourcepath)로 한다.

      3. urlpathallowed path로 시작하지 않으면 계속한다.

    3. ruleresourcesurl을 포함하면 registration을 반환한다.

    4. urlrulescopes 중 하나로 시작하면 registration을 반환한다.

  3. null을 반환한다.

적합성

문서 규약

적합성 요구사항은 설명적 단언과 RFC 2119 용어의 조합으로 표현됩니다. 본 문서의 규범 부분에 나타나는 "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", "OPTIONAL" 등 주요 단어들은 RFC 2119에 설명된 대로 해석되어야 합니다. 다만 가독성을 위해 이 명세서에서는 이 단어들을 모두 대문자로 표기하지 않습니다.

명시적으로 비규범 섹션, 예시, 참고로 표시된 부분을 제외한 명세서의 모든 텍스트는 규범적입니다. [RFC2119]

본 명세서에 등장하는 예시는 “예를 들어”라는 서두나, 규범적인 텍스트와 구분되는 class="example" 특성으로 도입됩니다. 예시:

이것은 참고용 예시입니다.

참고(Informative) 표기는 “참고”라는 단어로 시작하며, 규범 본문과 class="note" 특성으로 구분됩니다. 예시:

참고, 이것은 참고용 안내문입니다.

색인

이 명세서에서 정의된 용어

참조에 의해 정의된 용어

참조

규범적 참조

[CONSOLE]
Dominic Farolino; Robert Kowalski; Terin Stock. Console Standard. Living Standard. URL: https://console.spec.whatwg.org/
[CSP]
Mike West; Antonio Sartori. Content Security Policy Level 3. URL: https://w3c.github.io/webappsec-csp/
[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[FETCH]
Anne van Kesteren. Fetch Standard. Living Standard. URL: https://fetch.spec.whatwg.org/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[URL]
Anne van Kesteren. URL Standard. Living Standard. URL: https://url.spec.whatwg.org/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/

참고용 참조

[DRAFT-IETF-WPACK-BUNDLED-RESPONSES-LATEST]
Web Bundles. URL: https://wpack-wg.github.io/bundled-responses/draft-ietf-wpack-bundled-responses.html

이슈 색인

web bundle fetch entry에 더 적합한 이름이 있을까요?
listweb bundle fetch entry list에 사용되지만, 순서는 중요하지 않아야 합니다.
워커에서는 지원되지 않습니다.
관련 script가 존재하지 않습니다. web bundle resultscript가 아니기 때문입니다. 이는 whatwg/html#958이 해결될 때까지 대기해야 합니다.