프런트엔드 개발에 가장 많은 영향을 주는 크롬 브라우저의 버전별 변경 예정 항목을 정리 및 공유한다.
💡 각 항목은 Chrome Platform Status의 Roadmap과 한 달간의 blink-dev 활동 요약을 바탕으로 정리했다.
💡 각 항목의 🚫는 지원 중단 및 제거(Removed), ⚠️는 지원 중단(Deprecated), ✅는 새로운 기능(Enabled by default), 🧪는 미리 보기(Developer Trial, Origin Trial)를 의미한다.
💡 각 항목 중 기존 서비스에 미치는 영향이 크다고 판단한 항목은 소제목 뒤에 📌 표시를 했다.
💡 지원 중단 및 제거(🚫), 지원 중단(⚠️) 외의 항목은 공유 가치가 있다고 판단한 경우에만 포함했다.
💡 개발자 미리 보기(🧪)는 chrome://flags
에서 Experimental Web Platform features
항목을 활성화하거나(Developer Trial), Origin Trial을 활성화해 사용할 수 있다.
💡 각 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 Chrome Platform Status를 그대로 인용했다.
SVGUseElement
의 data:
URL 차단<details>
요소에 아코디언 기능 추가FontFaceSet.check()
버그 수정<iframe>
이동 시 사용자 입력 일시 제한Theora는 2000년 초 발표된 오픈소스 비디오 코덱으로, .ogv
, ..ogg
등의 파일 형식에서 드물게 사용한다. 특정 미디어 코덱에 대한 보안 위협을 발견했고, 사파리와 안드로이드 크롬은 해당 코덱을 지원한 적이 없으며, 사용률도 과거에 비해 거의 감지하기 어려운 수준으로 낮아져 Theora 코덱을 지원 중단할 예정이다.
현재 지원 중단 미리 보기는 Chrome 120에 배포 예정이다. 지원 중단 기간부터 Theora 코덱은 사용이 불가능하며, chrome://flags/#theora-video-codec
에서 기능을 다시 활성화해 기존처럼 Theora 코덱을 사용할 수 있다.
해당 코덱의 완전한 제거는 내년 3월에 배포 예정인 Chrome 123으로 계획 중이다. 만약 업데이트 이후에도 계속 Theora 코덱을 사용해야 한다면 ogv.js
폴리필이 있으니 참고하자.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
CSPEE(Content-Security-Policy Embedded Enforcement)는 구글에서 제안한 기능으로, 하위 요소(<iframe>
등)가 특정 CSP
를 지키기로 했을 때만 하위 요소를 불러오는 기능이다.
이 기능은 동일 출처일 때 손쉽게 사용이 가능했으나, 특정 요소를 차단해 잠재적으로 XSS에 노출될 수 있다는 보안 위협이 있었다. 또한 A 사이트에서 B 사이트를, B 사이트에서 다시 A 사이트의 페이지를 중첩해 렌더링하는 경우 이 기능이 제대로 동작하지 않는 버그도 있었다.
아직 CSPEE를 사용하는 사이트는 전체 사이트의 0.000017% 정도여서 동일 출처에 대한 특권을 제거한다. 업데이트 이후에는 동일 출처도 교차 출처처럼 CSPEE를 활성화해야 한다.
<iframe
src="https://advertisements-r-us.example.com/ad1.cfm"
csp="script-src https://trusted-cdn.example.com/"
>
</iframe>
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
SVGUseElement
의 data:
URL 차단SVG의 <use>
를 사용하면 href
속성으로 이미지를 불러와 현재 문서에 붙여넣을 수 있다. 유용한 기능이나, 보안 문제가 있는 만큼 <use>
에는 동일 출처 정책(same-origin policy)이 적용된다. 하지만 data:
URL을 사용하는 경우는 항상 동일 출처로 취급하며, 일부 보안 모듈을 거치지 않았다.
Chrome 120부터는 보안 문제를 이유로 data:
URL을 지원 중단할 예정이다. 기존에 data:
URL을 사용했다면 해당 이미지를 동일 출처의 .svg
이미지로 변환하거나, 인라인에서 직접 이미지를 관리하는 방법으로 전환하기를 권장한다.
<!-- SVG로 변환 -->
<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<circle id="circle" cx="5" cy="5" r="4" stroke="blue" />
<use href="#circle" />
</svg>
// 스크립트로 직접 이미지를 관리
const url = URL.createObjectURL(blob);
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
const use = document.createElementNS('http://www.w3.org/2000/svg', 'use');
use.setAttribute('href', `${url}#circle`);
svg.appendChild(use);
document.body.appendChild(svg);
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
<details>
요소에 아코디언 기능 추가아코디언은 웹에서 자주 사용하는 UI이다. 하지만 <input type="date" />
처럼 브라우저에서 기본 제공해주지 않아 매번 개발자가 해당 UI를 개발해야 했다.
이런 불편을 덜기 위해 Chrome 120에서 기존 <details>
요소에 name
속성을 추가할 예정이다. name
속성으로 묶인 <details>
요소는 하나의 그룹으로 취급하며, 그룹에서는 한 번에 최대 하나의 <details>
요소만 열 수 있다.
<details name="foo">
<summary>요약 하나</summary>
<p>첫 번째입니다!</p>
</details>
<details name="foo">
<summary>요약 둘</summary>
<p>두 번째 아코디언입니다!</p>
</details>
<details name="foo">
<summary>요약 셋</summary>
<p>세 번째입니다!</p>
</details>
위 예시에서는 <details>
요소를 foo
라는 이름의 그룹으로 묶었다. 같은 그룹에서는 최대 한 개의 <details>
요소만 열 수 있기에 다른 <details>
요소를 열면 기존에 열렸던 요소는 자동으로 닫힌다.
만약 open
속성을 한 개 이상 지정하면 HTML 기준으로 제일 먼저 나타나는 요소만 열린다.
<details name="foo">
<summary>요약 하나</summary>
<p>첫 번째입니다!</p>
</details>
<details name="foo" open>
<summary>요약 둘</summary>
<p>두 번째입니다!</p>
</details>
<details name="foo" open>
<summary>요약 셋</summary>
<p>세 번째입니다!</p>
</details>
Chrome 115 이상이라면 chrome://flags
에서 Experimental Web Platform features
를 켜고 해당 기능을 체험해 볼 수 있다.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
사용자가 무언가를 취소하거나 닫는 행위를 했을 때 이를 감지할 수 있는 CloseWatcher
를 추가한다.
CloseWatcher
는 키보드의 esc
버튼을 누르거나, 모바일에서 뒤로가기 제스처를 실행하는 등, 사용자가 무언가 닫는 동작을 요청했을 때 리스너에 이벤트를 전파한다.
현재는 이런 동작을 구현하기 위해 직접 keydown
이벤트에 리스너를 추가하거나, 각 플랫폼(iOS, Android 등)에 맞춘 전용 코드를 작성해야 해 번거롭다. CloseWatcher
를 사용하면 이런 동작을 보다 간편하게 구현할 수 있다.
const watcher = new CloseWatcher();
watcher.addEventListener('close', () => {
myModal.close();
});
myModalCloseButton.addEventListener('click', () => {
watcher.destroy();
myModal.close();
});
Chrome 팀은 내부적으로 <dialog>
, popover
등의 오버레이도 해당 API를 사용하도록 변경할 예정이다.
Chrome 97 이상이라면 chrome://flags
에서 Experimental Web Platform features
를 켜고 해당 기능을 체험해 볼 수 있다.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
FontFaceSet.check()
버그 수정해당 글꼴의 렌더링 가능 여부를 반환하는 FontFaceSet.check()
메서드의 버그를 수정한다. 현재도 사용할 수 있는 기능이나, Blink 엔진에서만 로컬에 설치한 폰트를 확인할 때 false
를 반환하는 버그가 있었다.
if (document.fonts.check('12px Pretendard')) {
showDocument();
}
이 기능을 사용하면 화면을 렌더링한 뒤에 폰트가 바뀌는 현상을 방지할 수 있다. CSS의 font-display
속성으로도 비슷한 기능을 구현할 수 있으나, font-display
는 글꼴만 보이지 않게 막을 수 있다는 점이 다르다.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
요소가 실제로 화면에 있는지 여부를 감지하는 IntersectionObserver
에 scrollMargin
옵션을 추가한다.
문법은 rootMargin
과 같으며, root
요소와 실제 스크롤 컨테이너가 다를 경우 스크롤 컨테이너의 rootMargin
처럼 사용할 수 있다.
<style>
.scroll-container {
width: 300px;
height: 300px;
background-color: lightcoral;
overflow: scroll;
}
.content {
width: 100%;
height: 1000px;
}
#target {
width: 50px;
height: 50px;
background-color: pink;
}
</style>
<div class="scroll-container">
<div class="content"></div>
<div id="target"></div>
</div>
const observer = new IntersectionObserver(
(entries) => {
// ...
},
{
// #target이 .scroll-container보다 상하좌우 50px 씩 큰 영역 안에 들어왔을 때 실행
scrollMargin: '-50px',
}
);
observer.observe(document.getElementById('#target'));
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
CSS의 scripting
미디어 규칙을 추가한다. 이 속성을 사용하면 브라우저의 스크립트 허용 설정에 따른 스타일을 작성할 수 있다.
@media (scripting: none) {
.message {
color: red;
}
}
@media (scripting: initial-only) {
.message {
color: orange;
}
}
@media (scripting: enabled) {
.message {
color: green;
}
}
속성에 사용 가능한 값은 none
, initial-only
, enabled
로 각각 스크립트 차단, 초기 로드 시에만 허용, 활성화 상태를 가리킨다.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
Private Network Access는 구글에서 제안 중인 기능으로, 외부망(public internet)에서 제공하는 웹 사이트의 내부망(private internet) 접근을 제한하여 보안을 더욱 강화하는 것을 목적으로 한다. 이미 Chrome 104와 Chrome 110에서 내부망 접근 확인이 실패했을 때 개발자 도구에 경고를 남기는 기능을 추가하여 동작을 어느 정도 미리 확인해 볼 수 있다.
이번 적용 대상은 안드로이드 Automotive 빌드로, 자동차의 인포테인먼트 시스템에 주로 활용된다. 자동차의 인포테인먼트 시스템은 사용자의 실제 안전과도 연결되어 Automotive 빌드를 대상으로 Private Network Access의 기능을 먼저 적용할 예정이다.
업데이트 이후에는 외부망에서 제공하는 웹 사이트가 내부망(사설 IP, localhost 등을 통해)의 하위 요소(이미지, js, css 등)에 접근하는 경우, 해당 서버에 사전 요청을 보내며, 이 요청이 실패할 경우 하위 요소에 대한 요청을 실패 처리한다. 또한 Web Worker를 사용할 때도 보안 연결을 사용하지 않으면 요청을 거부한다.
다만 이 기능에 대해 부정적인 의견이 많아 개발 환경에서 이 기능에 대한 완화 조치를 미리 보기로 같이 배포할 예정이니 참고하자.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
Chrome 120은 2023년 11월 29일에 정식 배포 예정이다.
<iframe>
이동 시 사용자 입력 일시 제한교차 출처의 <iframe>
이 화면에서 이동한 경우, 사용자의 입력을 일정 시간 무시하도록 변경한다. 갑자기 화면을 이동해 사용자가 원치 않는 클릭을 하도록 유도하는 공격을 방지하기 위한 조치로, 기존에는 <iframe>
내부에서 IntersectionObserver
의 최신 버전을 사용하는 경우에만 적용했던 기능이다.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
스크롤바에 대한 스타일을 설정할 수 있는 scrollbar-color
와 scrollbar-width
속성의 미리 보기를 추가한다.
scrollbar-color
속성은 스크롤바의 색상을 결정하며, 첫 번째 값은 스크롤바의 thumb
, 두 번째 값은 스크롤바의 track
색상으로 사용한다.
.scroll {
width: 300px;
height: 100px;
overflow-y: scroll;
scrollbar-color: lightcoral pink;
}
scrollbar-width
속성은 스크롤바의 너비를 결정하며, auto | thin | none
을 값으로 설정할 수 있다. 아직 숫자값은 사용이 불가능해 적극적인 사용은 어려워 보이나, none
값을 설정하면 간단하게 네이티브 스크롤바를 없앨 수 있다는 점은 장점이다.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
키보드, 음성 입력, 전차펜 필기 등을 입력 받아 스크립트에서 처리할 수 있는 EditContext API
를 추가한다. 지금도 contenteditable
속성을 활용해 DOM을 직접 편집할 수 있는 기능이 있으나, contenteditable
은 DOM을 직접 편집하는 것에 초점을 맞춘 기능이어서 API가 깔끔하지 않다. 특히 한글과 같은 조합 문자를 입력할 때 조합 모드를 제어할 수 없는 등 기능도 제한적이다.
EditContext
을 활성화하면 contenteditable
처럼 해당 요소를 편집할 수 있게 변한다. 하지만 목적이 다른 API인 만큼 개발자가 직접 어떻게 입력을 처리할지는 코드로 직접 작성해야 한다.
const canvas = document.getElementById('canvas');
const editContext = new EditContext();
editContext.addEventListener('textupdate', (event) => {
console.log(event.text);
});
canvas.editContext = editContext;
canvas.focus();
contenteditable
은 HTML 컨텐츠를 가질 수 있는 요소에만 적용할 수 있으나, EditContext
는 <canvas>
등의 요소에도 적용할 수 있다. 예시처럼 요소의 editContext
속성에 EditContext
의 인스턴스를 할당해 기능을 활성화할 수 있으며, 문서의 초점이 해당 요소에 있는 동안은 EditContext
에서 사용자 입력을 처리한다. 이때 해당 요소에는 input
이벤트가 발생하지 않는다.
EditContext
는 DOM을 편집하는 것이 목적이 아니기에 해당 DOM을 자동으로 업데이트하지 않는다. 위 예시는 콘솔에 로그만 남길 뿐, 화면상에는 아무런 변화가 없다. 화면에 입력한 텍스트를 노출하려면 개발자가 직접 코드를 작성해야 한다.
const canvas = document.getElementById('canvas');
const editContext = new EditContext();
editContext.addEventListener('textupdate', (event) => {
const context2d = canvas.getContext('2d');
context2d.font = '24px Pretendard';
context2d.strokeText(event.text);
});
canvas.editContext = editContext;
canvas.focus();
EditContext
의 초안 문서에 따르면 현재 textupdate
이벤트 말고도 조합 모드에서 글자 형식이 변했을 때 발생하는 textformatupdate
, 사용자 선택 범위가 변했을 때 발생하는 characterboundsupdate
이벤트를 추가로 사용할 수 있다.
EditContext
는 아직 초안으로 세부 스펙이 바뀔 수 있음에 유의하자.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
HTMLSelectElement
, <select>
요소에 showPicker()
메서드를 추가한다. <input type="color" />
, <input type="date" />
등의 일부 인풋 타입은 이미 사용가능한 메서드로, Chrome 121에서는 <select>
요소에도 해당 메서드를 추가할 예정이다.
기존에는 <select>
요소의 옵션 창을 간편하게 열 수 있는 방법이 없었으나, 업데이트 이후에는 아래처럼 메서드 호출로 직접 옵션 창을 열 수 있다.
const selectEl = document.getElementById('select');
selectEl.showPicker();
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
Array.from()
의 비동기 버전인 Array.fromAsync()
메서드의 미리 보기를 추가한다. 열거 가능한 Promise 객체를 받아 결과를 하나의 배열 Promise로 반환한다는 점은 Promise.all()
과 같으나, 다음 값을 가져오는 부분에서 차이가 있다.
const createAsyncIterable = async function* () {
for (let i = 0; i < 5; i++) {
await new Promise((resolve) => {
setTimeout(resolve, 100);
});
yield i;
}
};
console.time('Array.fromAsync()');
await Array.fromAsync(createAsyncIterable());
console.timeEnd('Array.fromAsync()'); // 약 500ms
console.time('Promise.all()');
await Promise.all(createAsyncIterable());
console.timeEnd('Promise.all()'); // 약 100ms
Promise.all()
이 객체의 모든 요소에 한 번에 접근하는 것과 달리, Array.fromAsync()
는 이전 요소가 settled
상태여야지만 다음 요소에 순서대로 접근한다.
동기 값을 넣는다면 결과를 Promise
로 반환할 뿐 Array.from()
과 동일하게 동작한다.
console.log(
await Array.fromAsync(
new Map([
['valueA', 1],
['valueB', 2],
])
)
);
// [['valueA', 1], ['valueB', 2]]
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
Private Network Access와 관련해 외부망에서 제공하는 사이트의 0.0.0.0
에 접근을 제한하는 기능의 미리 보기를 추가할 예정이다. 리눅스 기반의 운영체제에서 Private Network Access의 제한을 0.0.0.0
으로 접근해 우회할 수 있어 구글에서 제안 중인 기능이다.
Private Network Access의 자세한 기능에 관해서는 이 글의 안드로이드 Automotive 빌드에서 내부망 접근 제한
을 참고하자.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
Chrome 121은 2024년 1월 17일에 정식 배포 예정이다.
MutationEvent
는 DOM 요소에 변경이 있을 때 발생하는 이벤트로, DOMSubtreeModified
, DOMNodeInserted
, DOMNodeRemoved
등이 있다.
element.addEventListener(
'DOMNodeInserted',
(event) => {
console.log('새로운 요소를 감지했습니다.', event.srcElement);
},
false
);
element.append(document.createElement('span'));
// 새로운 요소를 감지했습니다. <span></span>
이 이벤트를 사용하면 DOM 변경을 추적할 수 있으나, 설계상 결함과 치명적인 성능 문제를 이유로 2011년에 표준에서 퇴출되었다.
2012년에 더 안정적인 MutationObserver
가 등장하여 현재 대부분의 브라우저에서 이 이벤트 사용 시 콘솔에 경고를 노출한다. 아직 MutationEvent
를 사용한다면 MutationObserver
로 전환할 것을 적극 권장한다.
const observer = new MutationObserver((mutations) => {
for (const mutation of mutations) {
if (mutation.type === 'childList') {
console.log('새로운 요소를 감지했습니다.', ...mutation.addedNodes);
}
}
});
observer.observe(element, { childList: true });
element.append(document.createElement('span'));
// 새로운 요소를 감지했습니다. <span></span>
Chrome 115부터는 Mutation 이벤트 사용 시 좀 더 강력한 경고를 노출하며, 2024년 7월 말 배포 예정인 Chrome 127에서는 해당 API를 제거할 예정이다.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
unload
이벤트는 해당 문서를 떠나거나 하위 리소스를 메모리에서 해제할 때 발생하는 이벤트이다. 이 이벤트를 이용하면 사용자가 페이지를 종료하기 전에 특정 동작을 실행할 수 있다.
window.addEventListener('unload', (event) => {
navigator.sendBeacon('/api/log', 'unload!');
});
하지만 unload
이벤트는 beforeunload
이벤트와 달리 기본 동작을 취소(event.preventDefault()
)할 수 없어 이벤트가 아예 발생하지 않기도 한다. W3C의 통계에 따르면 unload
이벤트가 제대로 발생하는 경우가 Chrome 데스크탑에서는 95%, 모바일에서는 57% ~ 68% 정도로, 이는 모바일 환경의 특성상 브라우저가 아닌 다른 앱을 보다가 브라우저 자체를 종료하는 경우가 빈번하기 때문이다.
Chrome은 점진적으로 unload
이벤트를 제거한다는 계획으로, 먼저 Permission-Policy
를 추가하고, 기본값을 deny
로 바꾸며, 결과적으로는 unload
이벤트 자체를 제거할 계획이다. Chrome 117에서 unload
이벤트의 허용 여부를 결정하는 Permission-Policy
의 미리 보기를 추가했으니 참고하자.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
CSS의 사용자 지정 상태 문법은 사용자가 직접 요소의 상태를 지정해 가상 선택자 등으로 사용할 수 있는 기능으로, 현재 초안 상태다.
class MyCustomElement extends HTMLElement {
set checked(flag) {
if (flag) {
this._internals.states.add('--foo');
} else {
this._internals.states.delete('--foo');
}
console.log(this._internals.states.has('--foo'));
}
}
.custom:--foo {
color: red;
}
기존에는 예시처럼 --foo
와 같은 문법을 사용했으나, 이 문법이 현재 제안 중인 @custom-selectors
문법과 겹쳐 :state(foo)
로 문법을 변경하였다.
.custom:state(foo) {
color: red;
}
현재 Chrome 90에서 구현한 구형 문법을 사용하는 사이트는 약 0.03%로 Chrome 팀은 먼저 구형 문법을 지원 중단하기 위한 일정을 논의 중이다.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.