서비스 워커가 브라우저에 오프라인에서 작동하는 페이지를 알리도록 사용 설정
Content Indexing API란 무엇인가요?
프로그레시브 웹 앱을 사용하면 네트워크 연결의 현재 상태와 관계없이 사용자가 중요하게 생각하는 정보(이미지, 동영상, 기사 등)에 액세스할 수 있습니다. 서비스 워커, Cache Storage API, IndexedDB와 같은 기술은 사용자가 PWA와 직접 상호작용할 때 데이터를 저장하고 제공하기 위한 구성요소를 제공합니다. 하지만 고품질의 오프라인 우선 PWA를 빌드하는 것만으로는 충분하지 않습니다. 사용자가 웹 앱의 콘텐츠를 오프라인 상태에서도 사용할 수 있다는 사실을 모르면 해당 기능을 구현하는 데 투입한 노력을 충분히 활용하지 못하게 됩니다.
이는 검색 문제입니다. PWA에서 사용자가 오프라인 지원 콘텐츠를 인식하여 사용 가능한 콘텐츠를 검색하고 볼 수 있도록 하려면 어떻게 해야 하나요? Content Indexing API가 이 문제를 해결하는 솔루션입니다. 이 솔루션의 개발자 대상 부분은 서비스 워커의 확장 프로그램으로, 개발자가 브라우저에서 유지 관리하는 로컬 색인에 오프라인 지원 페이지의 URL과 메타데이터를 추가할 수 있습니다. 이 개선사항은 Chrome 84 이상에서 사용할 수 있습니다.
색인이 PWA의 콘텐츠와 설치된 다른 모든 PWA의 콘텐츠로 채워지면 아래와 같이 브라우저에 표시됩니다.
또한 Chrome은 사용자가 오프라인 상태임을 감지하면 콘텐츠를 사전에 추천할 수 있습니다.
Content Indexing API는 콘텐츠를 캐시하는 대체 방법이 아닙니다. 서비스 워커에 의해 이미 캐시된 페이지에 관한 메타데이터를 제공하는 방법으로, 사용자가 이러한 페이지를 보려 할 때 브라우저가 이러한 페이지를 표시할 수 있습니다. Content Indexing API는 캐시된 페이지의 검색 가능성을 높이는 데 도움이 됩니다.
실제 사례 보기
Content Indexing API를 이해하는 가장 좋은 방법은 샘플 애플리케이션을 사용해 보는 것입니다.
- 지원되는 브라우저와 플랫폼을 사용하고 있는지 확인합니다. 현재 이 버전은 Android의 Chrome 84 이상으로 제한됩니다.
about://version
로 이동하여 실행 중인 Chrome 버전을 확인하세요. - https://contentindex.dev를 방문합니다.
- 목록에서 하나 이상의 항목 옆에 있는
+
버튼을 클릭합니다. - (선택사항) 기기의 Wi-Fi 및 모바일 데이터 연결을 사용 중지하거나 비행기 모드를 사용 설정하여 브라우저 오프라인 전환을 시뮬레이션합니다.
- Chrome 메뉴에서 오프라인 저장 항목을 선택하고 추천 도움말 탭으로 전환합니다.
- 이전에 저장한 콘텐츠를 둘러봅니다.
GitHub에서 샘플 애플리케이션 소스를 확인할 수 있습니다.
다른 샘플 애플리케이션인 Scrapbook PWA는 Web Share Target API와 함께 Content Indexing API를 사용하는 방법을 보여줍니다. 이 코드는Cache Storage API를 사용하여 Content Indexing API를 웹 앱에서 저장한 항목과 동기화하는 방법을 보여줍니다.
API 사용
이 API를 사용하려면 앱에 서비스 워커와 오프라인에서 탐색할 수 있는 URL이 있어야 합니다. 웹 앱에 현재 서비스 워커가 없는 경우 Workbox 라이브러리를 사용하면 간편하게 만들 수 있습니다.
오프라인 사용 가능으로 색인 생성할 수 있는 URL 유형은 무엇인가요?
이 API는 HTML 문서에 해당하는 색인 생성 URL을 지원합니다. 예를 들어 캐시된 미디어 파일의 URL은 직접 색인을 생성할 수 없습니다. 대신 미디어를 표시하고 오프라인에서 작동하는 페이지의 URL을 제공해야 합니다.
권장되는 패턴은 기본 미디어 URL을 쿼리 매개변수로 허용할 수 있는 '뷰어' HTML 페이지를 만든 다음 잠재적으로 페이지의 추가 컨트롤이나 콘텐츠와 함께 파일의 콘텐츠를 표시하는 것입니다.
웹 앱은 현재 서비스 워커의 범위에 있는 콘텐츠 색인에만 URL을 추가할 수 있습니다. 즉, 웹 앱은 완전히 다른 도메인에 속한 URL을 콘텐츠 색인에 추가할 수 없습니다.
개요
Content Indexing API는 메타데이터 추가, 나열, 삭제라는 세 가지 작업을 지원합니다. 이러한 메서드는 ServiceWorkerRegistration
인터페이스에 추가된 새 속성 index
에서 노출됩니다.
콘텐츠 색인을 생성하는 첫 번째 단계는 현재 ServiceWorkerRegistration
에 대한 참조를 가져오는 것입니다. navigator.serviceWorker.ready
를 사용하는 것이 가장 간단한 방법입니다.
const registration = await navigator.serviceWorker.ready;
// Remember to feature-detect before using the API:
if ('index' in registration) {
// Your Content Indexing API code goes here!
}
웹페이지 내부가 아닌 서비스 워커 내에서 Content Indexing API를 호출하는 경우 registration
를 통해 ServiceWorkerRegistration
를 직접 참조할 수 있습니다. ServiceWorkerGlobalScope.
의 일부로 이미 정의되어 있습니다.
색인에 추가 중
add()
메서드를 사용하여 URL 및 관련 메타데이터의 색인을 생성합니다. 항목이 색인에 추가되는 시점은 개발자가 선택할 수 있습니다. '오프라인 저장' 버튼을 클릭하는 등 입력에 응답하여 색인에 추가할 수 있습니다. 또는 주기적 백그라운드 동기화와 같은 메커니즘을 통해 캐시된 데이터가 업데이트될 때마다 항목을 자동으로 추가할 수도 있습니다.
await registration.index.add({
// Required; set to something unique within your web app.
id: 'article-123',
// Required; url needs to be an offline-capable HTML page.
url: '/articles/123',
// Required; used in user-visible lists of content.
title: 'Article title',
// Required; used in user-visible lists of content.
description: 'Amazing article about things!',
// Required; used in user-visible lists of content.
icons: [{
src: '/img/article-123.png',
sizes: '64x64',
type: 'image/png',
}],
// Optional; valid categories are currently:
// 'homepage', 'article', 'video', 'audio', or '' (default).
category: 'article',
});
항목을 추가하면 콘텐츠 색인에만 영향을 미치며 캐시에는 아무것도 추가되지 않습니다.
특이 사례: 아이콘이 fetch
핸들러를 사용하는 경우 window
컨텍스트에서 add()
호출
add()
를 호출하면 Chrome은 색인이 생성된 콘텐츠 목록을 표시할 때 사용할 아이콘 사본이 있는지 확인하기 위해 각 아이콘의 URL을 요청합니다.
window
컨텍스트 (즉, 웹페이지)에서add()
를 호출하면 이 요청으로 인해 서비스 워커에서fetch
이벤트가 트리거됩니다.서비스 워커 내에서 (예: 다른 이벤트 핸들러 내에서)
add()
를 호출하면 요청이 서비스 워커의fetch
핸들러를 트리거하지 않습니다. 아이콘은 서비스 워커의 개입 없이 직접 가져옵니다. 아이콘이 네트워크가 아닌 로컬 캐시 내에만 존재하기 때문에fetch
핸들러를 사용하는 경우 이 점에 유의하세요. 이러한 경우window
컨텍스트에서만add()
를 호출해야 합니다.
색인 콘텐츠 나열
getAll()
메서드는 색인 생성된 항목 및 메타데이터의 반복 가능한 목록에 관한 약속을 반환합니다. 반환된 항목에는 add()
로 저장된 모든 데이터가 포함됩니다.
const entries = await registration.index.getAll();
for (const entry of entries) {
// entry.id, entry.launchUrl, etc. are all exposed.
}
색인에서 항목 삭제
색인에서 항목을 삭제하려면 삭제할 항목의 id
를 사용하여 delete()
를 호출합니다.
await registration.index.delete('article-123');
delete()
를 호출하면 색인에만 영향을 미칩니다. 캐시에서 아무것도 삭제하지 않습니다.
사용자 삭제 이벤트 처리
브라우저가 색인이 생성된 콘텐츠를 표시할 때 삭제 메뉴 항목이 포함된 자체 사용자 인터페이스를 포함할 수 있으므로 사용자가 이전에 색인이 생성된 콘텐츠를 더 이상 보지 않겠다고 표시할 수 있습니다. Chrome 80에서 삭제 인터페이스는 다음과 같이 표시됩니다.
사용자가 이 메뉴 항목을 선택하면 웹 앱의 서비스 워커가 contentdelete
이벤트를 수신합니다. 이 이벤트를 처리하는 것은 선택사항이지만, 이를 통해 서비스 워커는 사용자가 완료했다고 표시한 콘텐츠(예: 로컬에 캐시된 미디어 파일)를 '정리'할 수 있습니다.
contentdelete
핸들러 내에서 registration.index.delete()
를 호출할 필요는 없습니다. 이벤트가 실행된 경우 관련 색인 삭제가 이미 브라우저에서 실행되었습니다.
self.addEventListener('contentdelete', (event) => {
// event.id will correspond to the id value used
// when the indexed content was added.
// Use that value to determine what content, if any,
// to delete from wherever your app stores it—usually
// the Cache Storage API or perhaps IndexedDB.
});
API 디자인에 대한 의견
API에 불편하거나 예상대로 작동하지 않는 문제가 있나요? 아니면 아이디어를 구현하는 데 필요한 누락된 부분이 있나요?
Content Indexing API 설명 GitHub 저장소에서 문제를 제출하거나 기존 문제에 의견을 추가하세요.
구현에 문제가 있나요?
Chrome 구현에서 버그를 발견했나요?
https://new.crbug.com에서 버그를 신고합니다. 최대한 많은 세부정보와 간단한 재현 안내를 포함하고 구성요소를 Blink>ContentIndexing
로 설정합니다.
API를 사용하려면 어떻게 해야 하나요?
웹 앱에서 Content Indexing API를 사용할 계획이신가요? 공개적으로 지원하면 Chrome에서 기능의 우선순위를 정하는 데 도움이 되며 다른 브라우저 공급업체에 기능을 지원하는 것이 얼마나 중요한지 보여줍니다.
- 해시태그
#ContentIndexingAPI
와 해시태그를 사용하는 위치와 방식에 관한 세부정보를 사용해 @ChromiumDev로 트윗을 보냅니다.
콘텐츠 색인이 보안 및 개인 정보 보호에 미치는 영향에는 어떤 것이 있나요?
W3C의 보안 및 개인 정보 보호 설문조사에 대한 응답으로 제공된 답변을 확인하세요. 다른 궁금한 점이 있으면 프로젝트의 GitHub 저장소를 통해 논의를 시작해 주세요.
Unsplash의 Maksym Kaharlytskyi님 제공 히어로 이미지