Chrome 105의 NavigationEvent 변경사항

조 메들리
조 메들리

Chrome 105에서는 실제로 문제가 있는 것으로 입증된 메서드를 개선하기 위해 Navigation API (102에서 도입됨)의 NavigateEvent에 두 가지 새로운 메서드를 도입했습니다. 개발자가 탐색 후 상태를 제어할 수 있는 intercept()가 사용하기 어려운 transitionWhile()를 대체합니다. URL에 지정된 앵커로 스크롤되는 scroll() 메서드가 일부 탐색 유형에서 작동하지 않는 restoreScroll()를 대체합니다.

이 도움말에서는 두 가지 모두의 문제와 새로운 방법으로 이러한 문제를 해결하는 방법을 설명합니다.

Chrome 102의 Navigation API에 도입된 NavigateEvent.trasitionWhile() 메서드는 단일 페이지 앱에서 클라이언트 측 전환을 위한 탐색을 가로챕니다. 첫 번째 인수는 브라우저와 웹 애플리케이션의 다른 부분에 완료되었음을 알리는 프로미스입니다.

실제로는 제대로 작동하지 않았습니다. 다음과 같은 일반적인 코딩 패턴을 살펴보세요.

event.transitionWhile((async () => {
  doSyncStuff();
  await doAsyncStuff();
})());

이는 아래 코드와 기능적으로 동일합니다. 이렇게 하면 API가 개발자가 탐색을 가로채려고 한다는 것을 인지하기 전에 탐색의 일부가 실행됩니다.

doSyncStuff();
event.transitionWhile((async () => {
  await doAsyncStuff();
})());

이 때문에 앱이 문제를 일으킬 수 있는 한 가지 예는 DOM 변경 후의 스크롤 위치를 캡처하는 스크롤 복원 로직입니다.

변경된 내용

transitionWhile()를 대체하기 위해 현재 사양에는 NavigateEvent.intercept()가 도입됩니다. 새 메서드는 transitionWhile()에서 지원하는 focusResetscrollRestoration 속성과 더불어 핸들러를 사용합니다. 새 핸들러는 탐색 커밋 후에 항상 실행되고 스크롤 위치와 같은 항목이 캡처되어 transitionWhile() 관련 문제를 방지합니다.

transitionWhile() 메서드는 계속 사용할 수 있지만 지원 중단되었으며 Chrome 108에서 삭제될 예정입니다.

Intersection() 사용

NavigateEvent.intercept()에는 모든 탐색 이벤트에서 호출할 수 없으므로 transitionWhile()와 동일한 제한사항이 있습니다. 교차 출처 탐색은 가로챌 수 없으며 문서 간 순회도 가능합니다. 이렇게 하면 "SecurityError" 유형의 DOMException이 발생합니다.

intercept()를 사용하려면 호출할 때 맞춤 핸들러를 전달하기만 하면 됩니다.

navigation.addEventListener("navigate", event => {
  event.intercept({
    async handler() {
      doSyncStuff();
      await doAsyncStuff();
    }
  });
});

페이지 상단에서 앵커로의 탐색 (/a에서 /a#id로 이동)과 같은 탐색은 단일 페이지 앱에서도 브라우저가 완전히 처리합니다. 그러나 멀티 페이지 앱에서 간단한 다른 '페이지' (/a에서 /b#id으로 이동)의 앵커로 이동하는 것은 단일 페이지 앱의 경우 더 복잡합니다. 앱은 NavigateEvent.transitionWhile()를 사용하여 /b#id로의 탐색을 가로채고 NavigateEvent.restoreScroll()를 호출하여 앵커를 뷰로 가져와야 합니다. 위에서 언급했듯이 현재로서는 쉽지 않은 작업입니다.

변경된 내용

이제 단일 페이지 앱에서는 브라우저가 앵커로 스크롤하는 것을 처리할지 코드에서 처리하는지 여부를 제어할 수 있습니다.

scroll() 사용

기본적으로 브라우저는 인터셉트 핸들러가 처리되고 나면 스크롤을 자동으로 처리하려고 시도합니다. 스크롤을 직접 처리하려면 scroll"manual"로 설정한 다음 브라우저에서 스크롤 위치를 설정해야 할 때 NavigateEvent.scroll()를 호출합니다.

navigation.addEventListener("manual", event => {
  scroll: "manual",
  event.intercept({
    async handler() {
      doSyncStuff();
      // Handle scrolling earlier than by default:
      event.scroll();
      await doAsyncStuff();
    }
  });
});

restoreScroll() 메서드는 계속 사용할 수 있지만 지원 중단되었으며 Chrome 108에서 삭제될 예정입니다.

결론

Navigation API에 관한 도움말이 곧 업데이트될 예정입니다. 그때까지는 이 API의 사양에서 웹 개발자를 위한 다양한 정보를 확인하시기 바랍니다.

사진: 팀 고우(Unsplash 제공)