1. 소개
현대 웹 애플리케이션은 전체 페이지 내비게이션을 수행하지 않고도 사용자 상호작용에 응답하여 콘텐츠를 동적으로 업데이트하는 경우가 많습니다. 구조적 DOM 수정, 콘텐츠풀 페인트, 히스토리 상태 변경과 같은 이러한 상호작용으로 시작된 효과는 역사적으로 올바른 사용자 동작에 측정하고 귀속하기 어려웠습니다.
일반적인 단일 페이지 애플리케이션 패턴을 생각해 보십시오. 사용자가 제품 링크를 클릭하면,
click 이벤트 핸들러가 트리거됩니다. 이 핸들러는 제품 세부 정보를 위해 네트워크 fetch를 시작합니다.
응답이 도착하면 새 콘텐츠를 DOM에 동적으로 삽입하고
History 또는 Navigation API를 사용하여 URL을 업데이트하는 콜백이 실행됩니다. 이는 사용자에게
내비게이션처럼 보이지만, Largest Contentful Paint (LCP) ([LARGEST-CONTENTFUL-PAINT]) 같은 기존 지표는
초기 페이지 로드만 측정하고, Interaction to Next Paint (INP)는 클릭 자체의 즉각적인
시각적 피드백만 측정하므로, 그 뒤의 중요한 렌더링과 "소프트"
내비게이션은 포착되지 않습니다.
이 명세는 [EVENT-TIMING] API를 활용하여 상호작용을 정의하고, [ASYNC-CONTEXT] 제안을 활용하여 비동기 작업 경계를 가로지르는 인과관계를 추적함으로써, 수정된 DOM 노드를 상호작용에 매핑하고, 콘텐츠풀 페인트를 그것을 유발한 상호작용에 귀속할 수 있게 합니다. 이 명세는 브라우저가 "소프트 내비게이션"을 포함한 이러한 효과를 식별하고 보고할 수 있는 방법을 정의하며, [PAINT-TIMING] 및 [LARGEST-CONTENTFUL-PAINT]와 통합하여 렌더링 변경을 성능 타임라인에 귀속합니다.
2. 성능 타임라인 슬라이싱
성능 지표(예: 이벤트 타이밍, 레이아웃 이동, 리소스 로드 또는
긴 애니메이션 프레임)를 이를 시작한 탐색에 귀속시키기 위해, 성능 타임라인은 navigationId
속성을 PerformanceEntry에
사용하여
세그먼트로 슬라이스됩니다.
시간에 걸쳐 이어지는 전환의 정확한 슬라이스 지점을 결정하는 것은 복잡합니다. 일관된 귀속을 보장하기 위해, 이 명세는 모든 URL 수정 즉시 타임라인을 슬라이스하지 않는 모델을 채택합니다. 대신 전환은 소프트 탐색이 성능 타임라인에 내보낼 준비가 될 때까지 지연됩니다.
설계상의 절충점, 귀속 규칙 및 경계 사례에 대한 자세한 논의는 [PERFORMANCE-TIMELINE] 이슈 comment를 참조하십시오.
2.1. 탐색 ID
탐색 id는 전역 객체의 수명 동안 각 탐색(하드 및 소프트 모두)에 할당되는 고유한 식별자입니다.
각 Window는
다음을 가집니다.
-
현재 탐색 id, 64비트 부호 없는 정수, 처음에는
Window의 초기 탐색 id 값으로 설정됩니다. -
탐색 횟수, 64비트 부호 없는 정수, 처음에는 0입니다.
-
초기 탐색 id 값, 64비트 부호 없는 정수, 처음에는 100에서 10000 사이의 임의의 정수로 설정됩니다.
-
탐색 id 증가량, 64비트 부호 없는 정수, 처음에는 사용자 에이전트가 선택한 작은 양의 정수로 설정됩니다.
참고: 초기
탐색 id 값 및 탐색 id 증가량은
navigationId
값을 계산하는 데 사용됩니다(
현재 탐색 id 증가시키기 참조).
이는 개발자가 이를 정확한 탐색 횟수를 세는 데 의존하거나
0에서 시작한다고 가정하는 것을 막습니다.
사용자 에이전트는 교차 출처 누수를 방지하기 위해 서로 다른 Window
객체 간에 공유 전역 탐색 값을 사용하지 않을 것으로 기대됩니다.
Window
window가 주어졌을 때 현재 탐색 id 증가시키기는 다음과 같습니다.
2.2. PerformanceEntry 확장
[Exposed =(Window ,Worker )]partial interface PerformanceEntry {readonly attribute unsigned long long ; };navigationId
PerformanceEntry에는
관련된 탐색 id가 있으며,
이는 64비트 부호 없는 정수이고 처음에는 0입니다.
navigationId
속성의 getter는 this의 탐색 id를 반환해야 합니다.
2.3. 성능 타임라인 통합
PerformanceEntry 큐에 넣기에서 1단계(엔트리 초기화) 이후 다음 단계를 추가합니다.
3. 상호작용 인프라
3.1. 상호작용 컨텍스트 소개
이 명세는 이러한 전파를 처리하기 위해 TC39 [ASYNC-CONTEXT] 제안을 활용합니다. 모든
새 사용자 상호작용(Event Timing에서 정의됨) 또는 관련 탐색 이벤트는 새
InteractionContext를 생성합니다. 이 컨텍스트는 숨겨진 내부 전용 AsyncContext
(로 표시됨)에 저장됩니다.
웹 플랫폼과 AsyncContext의 통합은 이 변수가 비동기 연속(예: setTimeout, fetch, )에 자동으로
연결되도록 하여, 브라우저가
이후의 효과를 원래 상호작용에 다시 귀속시킬 수 있게 합니다.
스크립트 전파에 더해, 이 명세는 DOM을 수정하는 사용자 상호작용이 DOM 수립하는 수정된 노드들의 집합을 정의하며, 해당 상호작용과 연결되게 하여, 콘텐츠풀 페인트와 같은 이후의 렌더링 효과를 현재 비동기 스크립트가 실행 중이 아니더라도 이를 시작한 상호작용 컨텍스트까지 거슬러 추적할 수 있게 한다.
3.2. InteractionContext 구조체
-
id, 이 컨텍스트와 연결된
interactionId를 나타내는 64비트 부호 없는 정수. -
컨텍스트 문서, Document.
-
시작 시간, 숫자.
-
내비게이션 타입,
NavigationType또는 null이며, 초깃값은 null이다. -
첫 번째 URL 값, 문자열 또는 null이며, 초깃값은 null이다.
-
첫 번째 URL 갱신 타임스탬프, 숫자이며, 초깃값은 0이다.
-
첫 번째 스크롤 타임스탬프, 숫자이며, 초깃값은 0이다.
-
첫 번째 입력 타임스탬프, 숫자이며, 초깃값은 0이다.
-
첫 번째 콘텐츠풀 페인트,
InteractionContentfulPaint또는 null이며, 초깃값은 null이다. -
가장 큰 콘텐츠풀 페인트,
InteractionContentfulPaint또는 null이며, 초깃값은 null이다. -
현재 가장 큰 콘텐츠풀 페인트 후보, 가장 큰 콘텐츠풀 페인트 후보 또는 null이며, 초깃값은 null이다.
-
마지막 URL 값, 문자열 또는 null이며, 초깃값은 null이다.
-
방출됨, 불리언이며, 초깃값은 false이다.
참고: 이 명세의 향후 버전은
탐색의 더 완전한 이력을 제공하기 위해 상호작용 컨텍스트 중 발생하는
모든 URL 업데이트를 추적할 수도 있습니다. 마지막 URL
값은
현재 PerformanceSoftNavigation의
name에 첫 URL 값만 노출되더라도, 효과를 상호작용의 최종 상태로
정확하게 다시 귀속시키기 위해 내부적으로
추적됩니다.
3.3. 인프라 알고리즘
-
context를 내부
AsyncContext. Variable의 값으로 둔다.[[ ActiveInteractionContext]] -
context가 null이 아니고 context의 컨텍스트 문서가 document와 같지 않으면, null을 반환한다.
-
context를 반환한다.
PerformanceEventTiming
timing entry가 주어졌을 때:
-
interaction id를 timing entry의
interactionId로 둔다. -
interaction id가 0보다 크다고 단언한다.
-
document의 상호작용 id에서 상호작용 컨텍스트로[interaction id]가 존재하면, document의 상호작용 id에서 상호작용 컨텍스트로[interaction id]를 반환한다.
-
interaction context를 새 InteractionContext로 둔다.
-
interaction context의 id를 interaction id로 설정한다.
-
interaction context의 컨텍스트 문서를 document로 설정한다.
-
document의 상호작용 id에서 상호작용 컨텍스트로[interaction id]를 interaction context로 설정한다.
-
interaction context를 반환한다.
-
timestamp를 document의 관련 전역 객체가 주어졌을 때의 현재 고해상도 시간으로 둔다.
-
is scroll을 event의 타입이 "scroll"이면 true로, 그렇지 않으면 false로 둔다.
-
is input을 event의 타입이 has dispatched input event를 트리거할 이벤트 타입이면 true로 두고([EVENT-TIMING]에 정의된 바와 같이), 그렇지 않으면 false로 둔다.
-
is scroll이 false이고 is input이 false이면, 반환한다.
-
document의 상호작용 id에서 상호작용 컨텍스트로의 값들 중 각 interaction context에 대해:
-
is scroll이 true이고 interaction context의 첫 번째 스크롤 타임스탬프가 0이면:
-
interaction context의 첫 번째 스크롤 타임스탬프를 timestamp로 설정한다.
-
-
is input이 true이고 interaction context의 첫 번째 입력 타임스탬프가 0이면:
-
interaction context의 첫 번째 입력 타임스탬프를 timestamp로 설정한다.
-
-
PerformanceEventTiming
객체 timing entry가 주어졌을 때:
-
timing entry가 null이면, null을 반환한다.
-
interaction id를 timing entry의
interactionId로 둔다. -
interaction id가 0이면, null을 반환한다.
-
event를 timing entry의 연결된 이벤트로 둔다.
-
document를 event의 관련 전역 객체의 연결된 Document로 둔다.
-
document와 event가 주어졌을 때 이벤트에 대한 상호작용 컨텍스트들을 갱신한다.
-
interaction context를 document와 timing entry가 주어졌을 때 상호작용에 대한 컨텍스트를 가져오거나 생성한 결과로 둔다.
-
내부
AsyncContext. Variable의 값을 interaction context로 설정한다.[[ ActiveInteractionContext]] -
interaction context를 반환한다.
-
내부
AsyncContext. Variable의 값을 null로 설정한다.[[ ActiveInteractionContext]]
4. 상호작용 콘텐츠풀 페인트
4.1. InteractionContentfulPaint 인터페이스
[Exposed =Window ]interface :InteractionContentfulPaint PerformanceEntry {readonly attribute LargestContentfulPaint ;largestContentfulPaint readonly attribute unsigned long long ;interactionId object (); };toJSON InteractionContentfulPaint includes PaintTimingMixin ;
각 InteractionContentfulPaint에는
다음이 있습니다.
-
연결된 컨텍스트, 즉 InteractionContext.
-
연결된 최대 콘텐츠풀 페인트, 즉
LargestContentfulPaint엔트리. -
연결된 페인트 타이밍 정보.
largestContentfulPaint
속성의 getter는 this의
가장 큰 콘텐츠풀 페인트를 반환해야 한다.
interactionId
속성의 getter는 this의
컨텍스트의 id를 반환해야 한다.
name
속성의 getter는 빈 문자열을 반환해야 한다.
entryType
속성의 getter는 를 반환해야 한다.
startTime
속성의 getter는 this의
컨텍스트의 시작 시간을 반환해야
한다.
duration
속성의 getter는 this의 페인트
타이밍 정보에 대한 기본 페인트 타임스탬프와 this의
컨텍스트의 시작 시간 사이의
차이를 반환해야 한다.
참고: 이 엔트리는 연결된 InteractionContext에서
정적 상호작용 속성(interactionId 및
startTime 등)을 동적으로 질의하지만, 생성 시점의
페인트의 페인트 타이밍 정보와 후보 LargestContentfulPaint
엔트리의 정적 스냅샷을 캡처하여
이러한 메트릭이 해당 시각적 갱신의 정확한 상태를 반영하도록 보장한다.
4.2. 상호작용 콘텐츠풀 페인트 알고리즘
Window
window, InteractionContext interaction
context, LargestContentfulPaint
lcpEntry, 그리고
페인트 타이밍 정보 paintTimingInfo가 주어졌을 때
상호작용 콘텐츠풀 페인트 엔트리 생성하기는 다음과 같습니다.
-
entry를 window의 realm 안의 새
InteractionContentfulPaint객체로 둡니다. -
entry의 컨텍스트를 interaction context로 설정합니다.
-
entry의 최대 콘텐츠풀 페인트를 lcpEntry로 설정합니다.
-
entry의 연결된 페인트 타이밍 정보를 paintTimingInfo로 설정합니다.
-
entry를 반환합니다.
-
interaction context의 첫 번째 스크롤 타임스탬프가 0보다 크고 lcpEntry의
renderTime이 interaction context의 첫 번째 스크롤 타임스탬프보다 크면, 반환한다. -
interaction context의 첫 번째 입력 타임스탬프가 0보다 크고 lcpEntry의
renderTime이 interaction context의 첫 번째 입력 타임스탬프보다 크면, 반환한다. -
lcpEntry를 lcpCandidate, paintTimingInfo, 그리고 document로 LargestContentfulPaint 엔트리를 생성한 결과로 둔다.
-
global을 document의 관련 전역 객체로 둔다.
-
paint timing info를 lcpEntry의 연결된 페인트 타이밍 정보로 둔다.
-
icpEntry를 global, interaction context, lcpEntry, 그리고 paint timing info가 주어졌을 때 상호작용 콘텐츠풀 페인트 엔트리를 생성한 결과로 둔다.
-
icpEntry를 큐에 넣는다.
-
icpEntry를 global의 성능 엔트리 버퍼에 추가한다.
-
interaction context의 첫 번째 콘텐츠풀 페인트가 null이면:
-
interaction context의 첫 번째 콘텐츠풀 페인트를 icpEntry로 설정한다.
-
-
interaction context의 가장 큰 콘텐츠풀 페인트를 icpEntry로 설정한다.
-
interaction context의 현재 가장 큰 콘텐츠풀 페인트 후보를 lcpCandidate로 설정한다.
참고: InteractionContentfulPaint 항목은 상호작용이 최종적으로 소프트 내비게이션으로
이어지는지 여부와는 독립적으로,
감지되는 대로 성능 타임라인에 방출된다. 이를 통해 개발자는 모든 상호작용에 대한 렌더링 업데이트를
모니터링할 수 있다.
Document
document, paint timing info paintTimingInfo,
ordered
set인
pending image records paintedImages, 그리고
ordered
set인 elements
paintedTextNodes가 주어졌을 때
interaction contentful paints 및
soft navigations 보고를 수행하려면:
-
contextToCandidateSets를 새 map으로 둔다.
-
paintedImages의 각 record에 대해 반복한다:
-
element를 record의 element로 둔다.
-
interaction context를 element에 대해 paint attribution interaction context 가져오기를 수행한 결과로 둔다.
-
interaction context가 null이 아니면:
-
-
paintedTextNodes의 각 element에 대해 반복한다:
-
interaction context를 element에 대해 paint attribution interaction context 가져오기를 수행한 결과로 둔다.
-
interaction context가 null이 아니면:
-
-
contextToCandidateSets 안의 각 interaction context → candidateSets에 대해 반복한다:
-
newCandidate를 document, candidateSets[0], candidateSets[1], 그리고 interaction context의 current largest contentful paint candidate가 주어졌을 때 새로운 largest contentful paint candidate 계산을 수행한 결과로 둔다.
-
newCandidate가 null이 아니면:
-
newCandidate, document, interaction context, 그리고 paintTimingInfo가 주어졌을 때 새로운 귀속된 contentful paint candidate 처리를 수행한다.
-
document와 interaction context가 주어졌을 때 soft navigation emission 평가를 수행한다.
-
-
4.3. Interaction Contentful Paint Attribution
-
context, InteractionContext, 처음에는 null.
-
modification id, 64-bit unsigned integer, 처음에는 0.
-
other node state가 null이거나 node state의 modification id가 other node state의 modification id보다 크면 true를 반환하고, 그렇지 않으면 false를 반환한다.
-
document를 node의 node document로 둔다.
-
node state를 document의 propagated node state[node]로 두되, 기본값을 null로 하는 with default를 사용한다.
-
node state가 null이면 null을 반환하고, 그렇지 않으면 node state의 context를 반환한다.
-
document를 node의 node document로 둔다.
-
target node가 document가 주어졌을 때 exposed for paint timing이 아니면, 반환한다.
-
interaction context를 document가 주어졌을 때 current interaction context 가져오기를 수행한 결과로 둔다.
-
interaction context가 null이면 반환한다.
-
document의 last modification context가 interaction context와 같지 않으면:
-
document의 last modification context를 interaction context로 설정한다.
-
document의 current modification generation id를 1 증가시킨다.
-
-
previous node state를 document의 marked node state[target node]로 두되, 기본값을 null로 하는 with default를 사용한다.
-
previous node state가 null이 아니고 previous node state의 modification id가 document의 current modification generation id와 같으면, 반환한다.
-
node state를 새로운 InteractionPaintTimingNodeState로 둔다.
-
node state의 context를 interaction context로 설정한다.
-
node state의 modification id를 document의 current modification generation id로 설정한다.
-
document의 marked node state[node]를 node state로 설정한다.
-
document의 is interaction paint timing dirty를 true로 설정한다.
-
document의 is interaction paint timing dirty가 false이면, 반환한다.
-
document와 null이 주어졌을 때 node 및 그 자손에 대한 interaction context 갱신을 수행한다.
-
document의 is interaction paint timing dirty를 false로 설정한다.
-
document를 node의 node document로 둔다.
-
node state를 document의 marked node state[node]로 두되, 기본값을 null로 하는 with default를 사용한다.
-
node state가 null이 아니면:
-
node state가 inherited node state보다 더 최근이면:
-
inherited node state를 node state로 설정한다.
-
node가
Textnode이면, document의 marked node state[node]를 제거한다.
-
-
그렇지 않으면, document의 marked node state[node]를 제거한다.
-
-
inherited node state가 null이 아니고 node가 timing-eligible이면:
-
attribution element를 node에 대해 attribution element 가져오기를 수행한 결과로 둔다.
-
previous propagated state를 propagated node state[attribution element]로 두되, 기본값을 null로 하는 with default를 사용한다.
-
inherited node state가 previous propagated state보다 더 최근이면:
-
propagated node state[attribution element]를 inherited node state로 설정한다.
-
previous propagated state가 null이거나 previous propagated state의 context가 inherited node state의 context와 같지 않으면, attribution element에 대해 paint tracking 재설정을 수행한다.
-
-
-
node의 각 자식 child node에 대해 반복하여, child node 및 inherited node state가 주어졌을 때 node 및 그 자손에 대한 interaction context 갱신을 수행한다.
참고: 단순화를 위해, 이 알고리즘은 전파된 상태를
다시 처리해야 할 때마다 전체
DOM을 순회한다. 이는 페인트 가능한 DOM의 일부만 처리하도록 최적화할 수 있으며, 예를 들어
보이지 않는 것으로 알려진 하위 트리나
content 또는 CSS containment 같은 기존 메커니즘에 의해 건너뛰어진 하위 트리도
이 과정에서 건너뛸 수 있다. 단, 다음에 페인트되기 전에
업데이트되어야 한다. 또한 관련 상태가 페인트 전에 업데이트되기만 한다면,
이 단계들은 다른(pre-paint) 트리 순회와 병합하여 추가로 최적화할 수 있다.
참고: [CONTAINER-TIMING] API는 공통 DOM 조상별로 렌더링 효과를 그룹화하고 집계된 paint 정보를 성능 타임라인에 보고하는 메커니즘을 제공한다. 이 명세의 향후 버전에서는 단일 container에 대한 여러 client (즉, 전역 "containertiming" 속성과 per-interaction timing)를 지원하도록 Container Timing을 확장하여 Container Timing의 관점에서 interaction paint timing을 구현할 수 있게 할 계획이다. 기록된 각 node는 그것을 수정한 interaction에 대한 container로 간주되어, 각 interaction이 container 집합과 연결되도록 할 것이다. 그러면 이 명세는 각 interaction에 대해 표시된 container에서 발생하는 largest contentful paint를 추적하게 된다. 나아가, Container Timing이 추적하는 다른 유용한 정보, 예를 들어 각 interaction에 대한 container의 집계된 총 페인트 면적도 노출할 수 있다.
5. 소프트 내비게이션
5.1. PerformanceSoftNavigation 인터페이스
[Exposed =Window ]interface :PerformanceSoftNavigation PerformanceEntry {readonly attribute NavigationType ;navigationType readonly attribute unsigned long long ;interactionId InteractionContentfulPaint ?(); };getLargestInteractionContentfulPaint PerformanceSoftNavigation includes PaintTimingMixin ;
각 PerformanceSoftNavigation은
다음을 가진다:
-
연결된 컨텍스트, 즉 InteractionContext.
-
연결된 페인트 타이밍 정보.
navigationType
속성의 getter는 this의
컨텍스트의 내비게이션
타입을 반환해야 한다.
interactionId
속성의 getter는 this의
컨텍스트의 id를 반환해야 한다.
getLargestInteractionContentfulPaint()
메서드는 this의
컨텍스트의 가장 큰 콘텐츠풀 페인트를 반환해야 한다.
name
속성의 getter는 this의
컨텍스트의 첫 번째 URL
값을 반환해야 한다.
entryType
속성의 getter는 을 반환해야 한다.
startTime
속성의 getter는 this의
컨텍스트의 시작 시간을 반환해야
한다.
duration
속성의 getter는 방출 시점의 this의
presentationTime
과 this의
컨텍스트의
시작 시간 사이의 차이를 반환해야 한다.
참고: 실제로는 getLargestInteractionContentfulPaint()가
null이 아닌
항목을 반환할 것으로 기대된다. 확정된 소프트 내비게이션은 그 방출을 트리거하려면 적어도 하나의 감지된 interaction contentful paint가
필요하기 때문이다.
그러나 향후 반복에서는 첫 페인트 이전, URL 수정 즉시 소프트 내비게이션을 커밋된 것으로 간주할 수
있는지 평가할 수 있다. 이러한 모델에서는 이 메서드가 방출 시점에
null을 반환할 수도 있다.
이 타이밍의 주요 설계 고려 사항은 URL 수정과 첫 페인트 사이의 구간에 발생하는 다른 타임라인 항목
(예:
LayoutShift, PerformanceResourceTiming, LongAnimationFrameTiming 등)의 귀속이다. 많은 사이트는 예를 들어 fetch 요청을 시작하는 즉시
새 URL을 커밋하지만, 그동안 현재 페이지는 여전히 이전 내비게이션 상태에 남아 있다.
일관된 타임라인 슬라이싱을 보장하기 위해, 이 명세는 첫 페인트가 전환을 확인할 때까지 이러한 모든 항목을
이전 navigation identifier에 귀속한다.
5.2. 소프트 내비게이션 알고리즘
소프트 내비게이션은 다음 조건을 만족하는 same-document navigation이다:
-
same-document URL 변경이 InteractionContext가 활성 상태인 동안 발생한다.
-
동일한 InteractionContext에 귀속되는 contentful paint가 발생한다.
-
interaction context의 방출됨이 true이면, 반환한다.
-
document의 활성 소프트 내비게이션 후보가 interaction context가 아니면, 반환한다.
-
interaction context의 첫 번째 URL 값이 null이면, 반환한다.
-
interaction context의 첫 번째 콘텐츠풀 페인트가 null이면, 반환한다.
-
window를 document의 관련 전역 객체로 둔다.
-
entry를 window와 interaction context가 주어졌을 때 소프트 내비게이션 엔트리를 생성한 결과로 둔다.
-
window와 entry가 주어졌을 때 소프트 내비게이션 엔트리를 방출한다.
-
interaction context의 방출됨을 true로 설정한다.
Window
window와
InteractionContext interaction
context가 주어졌을 때:
-
entry를 window의 렐름 안에 있는 새
PerformanceSoftNavigation객체로 둔다. -
entry의 컨텍스트를 interaction context로 설정한다.
-
first paint를 interaction context의 첫 번째 콘텐츠풀 페인트로 둔다.
-
first paint가 null이 아니라고 단언한다.
-
entry의 연결된 페인트 타이밍 정보를 first paint의 연결된 페인트 타이밍 정보로 설정한다.
-
entry를 반환한다.
Window
window와
PerformanceSoftNavigation
entry가 주어졌을 때:
-
window가 주어졌을 때 현재 내비게이션 id를 증가시킨다.
-
entry를 큐에 넣는다.
-
entry를 window의 성능 엔트리 버퍼에 추가한다.
참고: 이 navigationId는
이 PerformanceSoftNavigation
엔트리를 성능 타임라인에 큐에 넣는 과정의 일부로 자동 설정되며, 다른
PerformanceEntry
타입의 동작과 일치한다.
NavigationType
navigation type이 주어졌을 때:
-
url이 document의 url과 같으면, 반환한다.
-
interaction context를 document가 주어졌을 때 현재 상호작용 컨텍스트를 가져온 결과로 둔다.
-
interaction context가 null이면, 반환한다.
-
interaction context의 마지막 URL 값을 url로 설정한다.
-
interaction context의 첫 번째 URL 갱신 타임스탬프가 null이면:
-
interaction context의 첫 번째 URL 갱신 타임스탬프를 document의 관련 전역 객체가 주어졌을 때의 현재 고해상도 시간으로 설정한다.
-
interaction context의 첫 번째 URL 값을 url로 설정한다.
-
interaction context의 내비게이션 타입을 navigation type으로 설정한다.
-
-
document의 활성 소프트 내비게이션 후보를 interaction context로 설정한다.
-
document와 interaction context가 주어졌을 때 소프트 내비게이션 방출을 평가한다.
6. 명세 통합
6.1. DOM 통합
6.1.1. Document
각 문서는 상호작용 id에서 상호작용 컨텍스트로, 즉 맵을 가지며, 초깃값은 비어 있다.
각 문서는 활성 소프트 내비게이션 후보, 즉 InteractionContext 또는 null을 가지며, 초깃값은 null이다.
각 문서는 현재 수정 생성 id, 즉 64비트 부호 없는 정수를 가지며, 0으로 초기화된다.
참고: 현재 수정 생성 id는 관련 DOM 수정이 이전 수정과 다른 InteractionContext로 발생할 때 변경된다. 이는 관련 수정들을 함께 그룹화할 수 있게 하며, 이를 통해 InteractionPaintTimingNodeState 객체들을 최신성 측면에서 비교하고 추적해야 하는 노드를 최적화할 수 있다.
각 문서는 마지막 수정 컨텍스트, 즉 InteractionContext 또는 null을 가지며, 초깃값은 null이다.
각 문서는 표시된 노드 상태, 즉 맵을 가지며, 이는 Node에서 InteractionPaintTimingNodeState로의 맵이고, 초깃값은 비어 있다.
각 문서는 전파된 노드 상태, 즉 맵을 가지며, 이는 Node에서 InteractionPaintTimingNodeState로의 맵이고, 초깃값은 비어 있다.
각 문서는 상호작용 페인트 타이밍이 더티인지, 즉 불리언을 가지며, 초깃값은 false이다.
6.1.2. Node
-
요소의
또는class style속성이 수정된다. -
리소스 속성(예:
img또는video요소의src)이 수정된다.
다음 단계를 실행한다:
-
node가 주어졌을 때 interaction paint timing을 위해 수정된 노드로 기록한다.
6.2. HTML 통합
6.2.1. History
documentsEntryChanged가
true이고 documentIsNew가 false인 경우), 동일 문서
커밋을 처리한다. 이때 Document,
대상 엔트리의 url, 그리고 "traverse"가
주어진다.
push"
또는
"replace"
중 하나)이 주어진다.
6.2.2. 하드 내비게이션
새 Window가
생성될 때(예: "hard" 내비게이션 중),
그 current navigation id는 § 2.1
Navigation ID에 명시된 대로 초기화된다.
PerformanceNavigationTiming
entry를 생성할 때,
사용자 에이전트는 그 navigationId를 Window의
current navigation id로 설정해야 한다.
6.3. Event Timing 통합
이 명세는 최신 웹 애플리케이션 및 단일 페이지 애플리케이션과 관련된 추가 이벤트 타입을 포함하도록 [EVENT-TIMING]의 상호작용 정의를 확장한다.
다음 이벤트 타입은 상호작용의 일부로 간주된다([EVENT-TIMING]에 정의된 바와 같이):
-
navigate -
popstate -
hashchange
이러한 이벤트가 사용자 상호작용의 결과로 디스패치될 때, 사용자 에이전트는 문서의
관련 전역 객체에 대해 다음 interactionId를 가져와 얻은
고유한 interactionId를
이 이벤트들에 할당해야 한다. 이벤트가 이미 할당된 interactionId를
가진 이전 상호작용에 의해 트리거된 경우, 사용자 에이전트는
동일한 식별자를 재사용해야 한다.
참고: 이러한 이벤트는 사용자 동작에서
시작된 이벤트인 경우에만 기본 상호작용으로 보고된다
(예: 브라우저 UI의 뒤로 버튼 클릭). 대부분의 다른 시나리오—예를 들어
click 핸들러가 history를 수동으로 조작하는 경우—에서는 이후의 popstate 또는 navigate 이벤트가 독립적인 사용자
상호작용으로 간주되지 않는다.
이러한 프로그래밍 방식으로 트리거된 이벤트에 isTrusted
플래그가 설정되어 있지 않을 수도 있지만,
history 및 navigation API가 시작 작업의 비동기 연속으로 처리되므로,
[ASYNC-CONTEXT]를 통해 원래
상호작용에
올바르게 귀속된다.
참고: navigate, popstate, 그리고 hashchange 이벤트는
소프트 내비게이션을 추적하고 interactionId를 할당하기 위한 내부 신호로
사용된다. 이 명세는 이러한
이벤트 유형이 PerformanceEventTiming entry로 성능 타임라인에 노출될 것을
요구하지 않으며,
그 결정은 [EVENT-TIMING] 명세에
맡긴다.
참고: [EVENT-TIMING] 명세는
processingStart 및 processingEnd 훅을 명시적으로 정의하고,
이 통합에 충분히 이른 시점에 interactionId 할당이 발생하도록
업데이트될 것으로 예상된다. 현재는 interactionId 할당이 일반적으로
이벤트 처리의 끝까지
지연된다.
이 명세는 안전한 전역
카운터를 보장하기 위해 interactionId에 unsigned 을
사용하는 반면, [EVENT-TIMING]은
현재 이를 unsigned 으로 정의한다. 이 불일치는
두 명세의 향후 버전에서 해결될 것으로 예상된다.
Window
window에 대해 다음
interactionId 가져오기를 수행하려면:
-
window의 interaction count를 window의 interaction count에 1을 더한 값으로 설정한다.
-
window의 initial interactionId value에 (window의 interaction count에 window의 interactionId increment를 곱한 값)을 더한 값을 반환한다.
-
timingEntry를 event timing processing start 초기화 및 기록의 결과로 설정하는 단계 직후에 다음 단계를 실행한다:
-
timingEntry가 주어졌을 때 event dispatch에 대한 현재 interaction context 설정을 수행한다.
-
-
event timing processing end 기록을 호출하는 단계 직전에 다음 단계를 실행한다:
6.4. Paint Timing 통합
이 명세는 [PAINT-TIMING] 명세를 확장하여 상호작용에 의해 수정된 요소에 대한 paint tracking을 재설정하고 렌더링된 문서에 대한 paint attribution을 트리거한다.
Document
document가 주어졌을 때 1단계 이후 다음 단계를 추가한다:
-
document가 주어졌을 때 document 및 그 자손에 대한 interaction context 갱신을 수행한다.
Mark paint time은 UA가 문서를 페인트하기 전과 후에 와야 하는 단계들을 함께 섞고 있다. 여기서 추가된 단계는 페인트 전에 발생할 것으로 예상된다. [w3c/paint-timing Issue #126]
Document
document, paint timing info paintTimingInfo,
ordered
set인 pending image records paintedImages, 그리고
ordered
set인
elements paintedTextNodes가 주어졌을 때,
10.3단계(largest contentful paint 보고) 이후 다음 단계를 추가한다:
-
document, paintTimingInfo, paintedImages, 그리고 paintedTextNodes가 주어졌을 때 interaction contentful paints 및 soft navigations 보고를 수행한다.
다음 알고리즘을 추가한다:
-
node에 대한 text element tracking을 재설정한다.
-
node에 대한 image element tracking을 재설정한다.
이는 자리표시자 알고리즘이다. 관련 요소에 대한 repaint를 허용해야 하지만, repaint가 Element Timing 또는 LCP에 영향을 주어서는 안 된다. 텍스트와 이미지는 관련 paint가 발생했는지 감지하는 메커니즘이 다르며, 둘 다 repaint를 지원하도록 업데이트되어야 한다.
다음 알고리즘을 추가한다:
-
node가
Textnode이면, node의 containing block을 결정하는Element를 반환한다. -
그렇지 않으면, node를 반환한다.
6.5. Largest Contentful Paint (LCP) 통합
7. 보안 및 개인정보 보호 고려사항
Soft Navigations를 성능 타임라인에 노출하는 것은 그 자체로 보안 및 개인정보 보호상 영향을 가지지 않습니다. 그러나 감지된 soft navigation의 결과로 다양한 페인트 타이밍 항목을 재설정하는 것은 영향을 가질 수 있으며, 특히 방문한 링크가 분할되기 전에는 더욱 그렇습니다. 따라서 :visited 캐시를 분할하지 않은 상태에서 이러한 페인트 작업을 노출하는 일은, 문제가 되는 페인트 작업이 출처 간에 사용자의 기록을 노출하지 않는지 확인하기 위한 신중한 분석 후에만 이루어져야 합니다.마찬가지로, 자세한 페인트 타이밍 정보(예: Interaction Contentful Paint를 통해)를 노출하면
맞춤법 또는 문법 오류 장식( 또는 을 통해)이 적용될 때 페인트 업데이트를
관찰하는 데 잠재적으로 사용될 수 있습니다. 완화 조치가 없는 경우, 이는
공격자가 텍스트 필드의 단어를 프로그래밍 방식으로 순환하며 해당 단어가 사용자의 사전에
존재하는지 확인할 수 있게 할 수 있습니다. 그러나 브라우저는 맞춤법 및 문법
검사가 사용자 상호작용(예: 키 누름 또는 클릭)당 한 번만 발생하도록 제한하여 이를 완화함으로써 사용자 사전
누수를 방지합니다. 타이밍 및 페인트
정보는 다른 표준 API를 통해 이미 개발자가 관찰할 수 있으므로, 이러한 타이밍
항목을 노출한다고 해서 브라우저의 맞춤법/문법 강조 표시 속도 제한에 의해 이미 제약되는 것 이상의
새로운 정보 누수가 도입되지는 않습니다.
8. 부록: 중첩되는 상호작용과 경합 조건
웹 애플리케이션은 여러 사용자 상호작용을 빠르게 연속해서 처리하는 경우가 많습니다. 이 명세는 다음 모델을 통해 이러한 중첩되는 상호작용을 처리합니다:
-
컨텍스트 독립성: 각 상호작용은 자체 InteractionContext를 독립적으로 관리합니다. 여러 컨텍스트가 동시에 "진행 중"일 수 있으며, 각각은 자체 URL 수정과 콘텐츠풀 페인트를 추적합니다.
-
활성 후보 싱글턴: 많은 상호작용이 활성 상태일 수 있지만, Document는 특정 시점에 단 하나의 active soft navigation candidate만 인식합니다.
-
선점: 상호작용 컨텍스트는 첫 번째 same-document URL 수정을 트리거하는 순간 active soft navigation candidate가 됩니다. 후속 상호작용 수정이 발생하면, 이는 이전 후보를 선점하고 새 후보가 됩니다.
-
방출 검증:
PerformanceSoftNavigation은 방출 기준(URL 변경 + 콘텐츠풀 페인트)이 충족되는 순간 active soft navigation candidate인 상호작용 컨텍스트에 대해서만 방출됩니다. 이를 통해 soft navigation 보고가 문서의 현재 시각적 상태 및 내비게이션 상태와 일관되게 유지됩니다. -
지속적인 귀속: 상호작용이 soft navigation 후보로서 선점되더라도, 활성 상태로 남아 있는 한 자체
InteractionContentfulPaint항목을 계속 귀속하고 보고합니다. 이를 통해 그 자체로는 "내비게이션"으로 간주되지 않는 동시 렌더링 업데이트를 정확하게 측정할 수 있습니다.