게시일: 2026년 7월 3일
문서 편집기, 스프레드시트 앱 또는 클립보드에서 콘텐츠를 붙여넣는 것이 기본 상호작용인 앱을 사용해 본 적이 있다면 사용자 기대치를 알 수 있습니다. 붙여넣기는 즉각적으로 이루어져야 합니다.
하지만 많은 경우 웹 앱은 필요한 것보다 더 많은 클립보드 데이터를 읽으므로 콘텐츠 붙여넣기가 예상보다 느리게 느껴지고, CPU 주기가 낭비되며, 앱에 전혀 필요하지 않은 데이터에 메모리가 사용될 수 있습니다.
선택적 형식 읽기는 Async Clipboard API 를 수정하여 사용자 기대치를 더 잘 충족하고 개발자에게 필요한 것, 즉 앱에 실제로 필요한 형식만 읽도록 제공함으로써 이 성능 문제를 해결합니다.
문제: 모든 데이터 형식을 미리 읽기
사용자가 Excel, Google Docs 또는 Photoshop과 같은 앱에서 복사하면 앱은 일반적으로 동일한 데이터의 여러 표현을 시스템 클립보드에 작성합니다. 일반 텍스트, HTML, 이미지, 때로는 맞춤 형식이 있습니다. 사용자가 클립보드에서 붙여넣을 때 데이터를 읽는 웹 앱은 이러한 표현을 모두 필요로 하는 경우가 거의 없습니다. 스프레드시트 편집기는 HTML을 원할 수 있습니다. 텍스트 편집기는 '일반 텍스트로 붙여넣기' 명령어를 노출할 수 있습니다. 코드 편집기는 텍스트만 원할 수 있습니다.
지금까지
navigator.clipboard.read()
시스템
클립보드에서 사용 가능한 데이터의 모든 표현을 가져오고, 정리 (특히 대용량 HTML 또는
이미지 페이로드의 경우 시간이 걸릴 수 있음)를 실행하고, 앱에서 절대 사용하지 않는 형식의 경우에도 바이트를 메모리에 보관했습니다. 사용하지 않는 페이로드가 클수록 사용자가 기다려야 하는 시간이 길어지고, 붙여넣기 응답성이 가장 중요한 시점에 탭에서 더 많은 메모리를 사용했습니다.
해결 방법: 열거만 하고 필요할 때 읽기
Chrome 및 Edge 149부터
ClipboardItem
메서드에서 반환된 navigator.clipboard.read() 객체는 데이터에 바로 액세스할 수 있는 것이 아니라
클립보드에 있는 내용만 설명합니다. 특정 형식의 실제 바이트는
`ClipboardItem.getType(mimeType)`을 호출할 때만 클립보드에서 읽습니다.
ClipboardItem.getType(mimeType)
API 노출 영역은 변경되지 않습니다. 어제 작성한 동일한 코드가 오늘도 계속 작동하여 즉각적인 성능 이점을 제공합니다.
// Enumerate the available MIME types.
// No payload is fetched yet.
const items = await navigator.clipboard.read();
for (const item of items) {
if (item.types.includes('text/html')) {
// Only read the HTML data.
// The data is fetched (and sanitized) here only.
const blob = await item.getType('text/html');
useThePastedHtml(await blob.text());
break;
}
// text/plain, image/png, or any other custom formats
// stored in the clipboard are never read.
}
여기서 또 다른 성능 이점은 캐싱이 자동으로 이루어진다는 것입니다. 동일한 ClipboardItem에서
getType('text/html')을 두 번 호출하면 시스템
클립보드에서 한 번만 읽고 두 번째 호출에서 캐시된 Blob을 반환합니다.
이점
지연 시간. navigator.clipboard.read()가 호출될 때 발생해야 하는 작업(예: 프로세스 간 바이트 복사, HTML 정리, 이미지 디코딩)은 이제 앱에 실제로 필요한 형식에 대해서만 발생합니다. 단일 형식만 읽는 앱은 대부분의 절약을 얻습니다. 건너뛰는 형식이 클수록 이점이 커집니다. HTML 정리는 비용이 많이 들기 때문에 HTML이 가장 큰 이점을 얻습니다.
메모리. 이전에는 클립보드에 50MB 이미지가 있을 때 navigator.clipboard.read()를 호출하면 앱에 데이터의 text/plain 표현만 필요하더라도 ClipboardItem이 출시될 때까지 웹페이지의 렌더러 메모리에서 50MB를 사용해야 했습니다. 이제 ClipboardItem.getType()을 호출할 때 앱에서 읽는 형식만 렌더러 프로세스에서 메모리를 사용합니다. 문서 편집기, 메일 작성기, 디자인 도구와 같이 붙여넣기가 일반적인 앱의 경우 특히 여러 편집기가 클립보드를 병렬로 읽을 수 있는 멀티 탭 세션에서 붙여넣기 중에 메모리 사용량이 크게 줄어듭니다.
옵트인 없음. 웹의 모든 사이트에서 이러한 이점을 자동으로 얻을 수 있습니다. 코드 또는 기능 감지 로직 뒤에 게이트 코드를 이전할 필요가 없습니다.
알아두어야 할 동작 변경사항
나중에 데이터를 읽으면 동작이 약간 변경됩니다. ClipboardItem 객체는 더 이상 navigator.clipboard.read() 호출이 해결되는 순간의 클립보드의 고정 스냅샷이 아닙니다.
read()가 호출되고 ClipboardItem을 반환하면 이 항목은 시스템 클립보드의 데이터에 대한 지연 핸들 일 뿐입니다.
read() 호출과 나중에 getType() 호출 사이에 클립보드의 콘텐츠가 변경되면 해당 호출은 InvalidStateError와 함께 거부됩니다. 이전에 동일한 ClipboardItem에서 성공적으로 읽은 형식의 경우에도 마찬가지입니다.
// Read from the clipboard.
const items = await navigator.clipboard.read();
// Get the first ClipboardItem.
const item = items[0];
// Actually fetch the data now, which works fine.
const text = await item.getType('text/plain');
// The user writes something new to the clipboard
// by copying from another app, or your own code writes to
// the clipboard again.
await navigator.clipboard.writeText('something new');
// Fetching the data from the earlier ClipboardItem
// rejects with InvalidStateError, because the contents
// of the clipboard changed.
const html = await item.getType('text/html');
이는 더 이상 클립보드를 반영하지 않는 데이터를 반환하면 혼란스럽고 디버그하기 어려운 문제가 발생하기 때문입니다.
실제로 앱은 일반적으로 동일한 붙여넣기 핸들러 내에서 read() 및 getType()을 연속으로 호출하므로 대부분의 코드에서 변경사항이 표시되지 않습니다. 하지만 비동기 경계에서 ClipboardItem을 보유하는 코드가 있는 경우를 확인하는 것이 좋습니다.
다음은 이 변경사항이 문제가 될 수 있는 예입니다. window에서 ClipboardItem 객체를 캐싱하거나, 클립보드 기록 UI에 표시하거나, getType()을 호출하기 전에 사용자 상호작용을 기다리는 경우입니다. 이와 같은 시나리오에서 문제를 방지하려면 다음을 따르세요.
getType()호출을try / catch블록으로 래핑하고InvalidStateError를 클립보드가 이동했으며 코드를 다시 읽어야 한다는 신호로 처리합니다.- 클립보드 데이터를 보관해야 하는 경우
getType()하는 즉시Blob을 자체 구조로 복사합니다.ClipboardItem을 장기 저장소로 취급하지 마세요. -
clipboardChange이벤트를 사용하여 오래된 핸들을 사전에 무효화합니다.
표준 및 브라우저 지원
선택적 형식 읽기는 클립보드 API 사양 변경사항으로, 웹 편집 워킹 그룹과 Microsoft Edge 웹 플랫폼팀에서 추진합니다.
Safari도 이 동작을 지원하며 Firefox는 긍정적인 표준 입장 과 정렬 의도를 나타냈습니다.
Chromium이 이제 동일한 모델로 수렴되면서 클립보드 API의 조용하지만 의미 있는 성능 및 상호 운용성 개선이 이루어집니다.