Chrome 확장 프로그램: 빠른 탐색을 지원하도록 API 확장

데이브 타푸스카
데이브 타푸스카

요약: Extensions API가 뒤로-앞으로 캐시를 지원하도록 업데이트되어 탐색을 미리 로드했습니다. 자세한 내용은 아래를 참조하세요.

Chrome은 탐색의 속도를 높이기 위해 많은 노력을 기울이고 있습니다. 뒤로-앞으로 캐시(Chrome 96에서 데스크톱에 배송됨) 및 추측 규칙(Chrome 103에서 배송됨)과 같은 인스턴트 탐색 기술은 뒤로 및 향후 환경을 모두 개선합니다. 이 게시물에서는 이러한 새 워크플로를 수용하기 위해 브라우저 확장 프로그램 API의 업데이트를 살펴봅니다.

페이지 유형 이해

뒤로-앞으로 캐시 및 사전 렌더링을 도입하기 전에는 개별 탭에 활성 페이지가 하나만 있었습니다. 항상 눈에 띄는 건 이것이었습니다. 사용자가 이전 페이지로 돌아가면(페이지 B) 활성 페이지가 완전히 재구성되고(페이지 A) 기록의 이전 페이지가 완전히 재구성됩니다(페이지 A). 탭에 활성/표시 상태만 있었기 때문에 확장 프로그램은 수명 주기 페이지의 어느 부분에 있는지 걱정할 필요가 없었습니다.

활성 페이지 제거
활성 페이지 제거.

뒤로-앞으로 캐시와 사전 렌더링을 사용하면 더 이상 탭과 페이지 간에 일대일 관계가 없습니다. 이제 각 탭은 소멸되고 재구성되는 대신 상태 간 전환을 여러 개 저장합니다.

예를 들어 페이지가 사전 렌더링된 (표시되지 않음) 페이지로 시작되어 사용자가 링크를 클릭하면 활성 (표시되는) 페이지로 전환된 후 사용자가 다른 페이지로 이동하면 '뒤로-앞으로 캐시'(표시되지 않음)에 저장될 수 있으며 이 모든 작업이 페이지가 삭제되지 않습니다. 이 도움말의 뒷부분에서는 확장 프로그램이 페이지의 상태를 파악하는 데 도움이 되도록 노출된 새 속성을 살펴보겠습니다.

페이지 유형
페이지 유형

하나의 탭에는 사전 렌더링된 일련의 페이지 (한 개가 아님), 단일 활성 (표시) 페이지, 일련의 뒤로/앞으로 캐시된 페이지가 포함될 수 있습니다.

확장 프로그램 개발자에게 적용되는 변경사항은 무엇인가요?

FrameId == 0

Chromium에서는 최상위/기본 프레임을 가장 바깥쪽 프레임이라고 합니다.

가장 바깥쪽 프레임의 frameId가 0 (이전 권장사항)이라고 가정하는 확장 프로그램 작성자에게 문제가 발생할 수 있습니다. 이제 한 탭에 여러 개의 가장 바깥쪽 프레임 (사전 렌더링 및 캐시된 페이지)이 여러 개 있을 수 있으므로 탭의 가장 바깥쪽에 단일 프레임이 있다는 가정은 잘못되었습니다. frameId == 0는 여전히 활성 페이지의 가장 바깥쪽 프레임을 나타내지만 같은 탭에 있는 다른 페이지의 가장 바깥쪽 프레임은 0이 아닙니다. 이 문제를 해결하기 위해 새 필드 frameType이 추가되었습니다. 이 게시물의 '프레임이 가장 바깥쪽 프레임인지 어떻게 알 수 있나요?' 섹션을 참고하세요.

프레임과 문서의 수명 주기

확장 프로그램에서 문제가 되는 또 다른 개념은 프레임의 수명 주기입니다. 프레임은 커밋된 URL과 연결된 문서를 호스팅합니다. 문서는 탐색 등을 통해 변경될 수 있지만 frameId는 변경되지 않으므로 특정 문서에서 발생한 무언가를 frameIds만으로 연결하기는 어렵습니다. 각 문서의 고유 식별자인 documentId라는 개념이 도입됩니다. 프레임이 탐색되고 새 문서가 열리면 식별자가 변경됩니다. 이 필드는 페이지가 수명 주기 상태 (사전 렌더링/활성/캐시됨 간)를 변경하는 시점을 확인하는 데 유용합니다. 동일하게 유지되기 때문입니다.

웹 탐색 이벤트

chrome.webNavigation 네임스페이스의 이벤트는 포함된 수명 주기에 따라 같은 페이지에서 여러 번 실행될 수 있습니다. '페이지가 어떤 수명 주기에 있는지 어떻게 알 수 있나요?''페이지가 전환되는 시점을 어떻게 알 수 있나요?' 섹션을 참고하세요.

페이지가 어떤 수명 주기에 있는지 어떻게 알 수 있나요?

DocumentLifecycle 유형이 이전에 frameId를 사용할 수 있었던 여러 확장 프로그램 API에 추가되었습니다. DocumentLifecycle 유형이 이벤트에 있는 경우(예: onCommitted) 값은 이벤트가 생성된 상태입니다. 언제든지 WebNavigation getFrame()getAllFrames() 메서드에서 정보를 쿼리할 수 있지만 항상 이벤트의 값을 사용하는 것이 좋습니다. 두 메서드 중 하나를 사용하면 이벤트가 생성된 시점과 두 메서드에서 반환된 프로미스 반환이 확인되는 시점 사이에 프레임 상태가 변경될 수 있다는 점에 유의하세요.

DocumentLifecycle의 값은 다음과 같습니다.

  • "prerender' : 현재 사용자에게 표시되지 않지만 사용자에게 표시될 수 있도록 준비 중입니다.
  • "active": 현재 사용자에게 표시됩니다.
  • "cached": 뒤로-앞으로 캐시에 저장됩니다.
  • "pending_deletion": 문서가 폐기됩니다.

프레임이 가장 바깥쪽 프레임인지 어떻게 알 수 있나요?

이전에는 확장 프로그램에서 frameId == 0가 발생한 이벤트가 가장 바깥쪽 프레임에 관한 것인지 확인하기 위해 확인했을 수 있습니다. 이제 탭에 여러 페이지가 있으므로 가장 바깥쪽 프레임이 여러 개 있으므로 frameId 정의가 문제가 됩니다. 뒤로-앞으로 캐시된 프레임에 관한 이벤트는 절대 수신되지 않습니다. 그러나 사전 렌더링된 프레임의 경우 가장 바깥쪽 프레임에서는 frameId이 0이 아닙니다. 따라서 frameId == 0를 가장 바깥쪽 프레임인지 확인하는 신호로 사용하는 것은 잘못된 것입니다.

이를 위해 FrameType라는 새로운 유형을 도입했으므로 이제 프레임이 실제로 가장 바깥쪽 프레임인지 쉽게 확인할 수 있습니다. FrameType에는 다음과 같은 값이 있습니다.

  • "outermost_frame": 일반적으로 최상위 프레임이라고 합니다. 여기에는 여러 개가 있습니다. 예를 들어 사전 렌더링 및 캐시된 페이지가 있는 경우 각 페이지에는 최상위 프레임이라고 할 수 있는 가장 바깥쪽 프레임이 있습니다.
  • "fenced_frame": 나중에 사용하기 위해 예약되어 있습니다.
  • "sub_frame": 일반적으로 iframe입니다.

DocumentLifecycleFrameType를 결합하여 프레임이 가장 바깥쪽에 있는 활성 프레임인지 확인할 수 있습니다. 예: js tab.documentLifecycle == “active” && frameType == “outermost_frame”

프레임 사용 시간 문제를 해결하려면 어떻게 해야 하나요?

위에서 언급했듯이 프레임은 문서를 호스팅하며 프레임이 새 문서로 이동할 수 있지만 frameId는 변경되지 않습니다. 따라서 frameId만 있는 이벤트를 수신하면 문제가 발생합니다. 프레임의 URL을 조회하면 이벤트가 발생한 시점과 다를 수 있는 경우 이를 사용 시간 문제라고 합니다.

이 문제를 해결하기 위해 documentId(및 parentDocumentId)를 도입했습니다. 이제 webNavigation.getFrame() 메서드는 documentId가 제공된 경우 frameId를 선택사항으로 만듭니다. documentId는 프레임을 이동할 때마다 변경됩니다.

페이지가 전환되는 시점을 어떻게 알 수 있나요?

페이지가 상태 간에 전환되는 시점을 결정하는 명시적 신호가 있습니다.

WebNavigation 이벤트를 살펴보겠습니다.

페이지를 맨 처음 탐색하면 아래 나열된 순서대로 4개의 이벤트가 표시됩니다. 이러한 네 가지 이벤트는 DocumentLifecycle 상태가 "prerender" 또는 "active"일 때 발생할 수 있습니다.

onBeforeNavigate
onCommitted
onDOMContentLoaded
onCompleted

사전 렌더링된 페이지가 활성 페이지가 되면 documentId"xyz"로 변경되는 아래 다이어그램에 설명되어 있습니다.

사전 렌더링된 페이지가 활성 페이지가 되면 documentId가 변경됩니다.
사전 렌더링된 페이지가 활성 페이지가 되면 documentId가 변경됩니다.

페이지가 뒤로-앞으로 캐시에서 전환되거나 사전 렌더링이 활성 상태로 전환되면 이벤트가 세 개 더 있습니다 (단, DocumentLifecyle"active"임).

onBeforeNavigate
onCommitted
onCompleted

documentId는 기존 이벤트와 동일하게 유지됩니다. 위에 나와 있는 것은 documentId == xyz 활성화될 때를 보여줍니다. 페이지가 이미 로드되었으므로 onDOMContentLoaded 이벤트를 제외하고 동일한 탐색 이벤트가 실행됩니다.

의견이나 질문이 있는 경우 언제든지 chromium-extensions 그룹에 문의하시기 바랍니다.