프런트엔드 개발에 가장 많은 영향을 주는 크롬 브라우저의 버전별 변경 예정 항목을 정리 및 공유한다.
💡 각 항목은 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를 그대로 인용했다.
<iframe>
이동 시 사용자 입력 일시 제한 📌<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();
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
DOM 변경으로 인해 포인터(PointerEvent
) 또는 마우스 이벤트(MouseEvent
) 발생 시, 브라우저 별로 동작이 다른 현상을 통일한다.
예를 들어 아래와 같은 DOM이 있다고 해 보자.
<div id="parentOfA">
<span>Parent Of A</span>
<div id="a">A</div>
</div>
<div id="b">B</div>
A 요소는 Parent Of A
의 자식이나 화면 상에서 B 요소의 위에 위치한다. 이때 A 요소를 클릭했을 때 A 요소를 사라지게 하면 포인터 이벤트(또는 상응하는 마우스 이벤트)는 현재 크롬에서 다음과 같은 순서로 발생한다(쉬운 이해를 위해 pointerover
, pointerout
이벤트는 생략했다).
pointerenter(parentOfA) -> pointerenter(A) -> pointerdown(A) -> pointerup(A) -> A 제거 -> pointerenter(B)
현재 이 동작은 크롬, 파이어폭스, 사파리가 모두 차이가 있다. 사파리는 pointerleave
이벤트를 제거된 A 요소에 발생시키며, 크롬은 포인터가 A에서 B로 이동했음을 표현하기 위해 일정 조건 동안 A 요소를 메모리에서 제거하지 않는다.
주요 브라우저는 논의를 통해 이 상황에 대한 브라우저의 동작을 통일하기로 결정했으며, 업데이트 이후에는 포인터가 제거된 A 요소의 부모에서 B 요소로 이동했음을 표현하도록 변경할 예정이다.
A 제거 -> pointerleave(parentOfA) -> pointerenter(B)
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
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]]
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
Chrome 121은 2024년 1월 17일에 정식 배포 예정이다.
CSS의 align-content
속성은 flexbox
의 교차축 또는 grid
의 블록 축 정렬을 지정하는 속성이다. align-items
가 축의 한 줄마다의 정렬을 지정하는 속성이라면, align-content
는 여러 줄을 감싸는 컨텐츠 영역의 정렬을 지정하는 속성이다.
업데이트 이후에는 align-content
를 블록 요소(display: block
, display: list-item
, display: table-cell
등)에 사용할 수 있어 수직 축 정렬을 좀 더 쉽게 할 수 있을 것으로 기대된다.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
Chrome 122은 2024년 2월 14일에 정식 배포 예정이다.
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 팀은 먼저 구형 문법을 지원 중단하기 위한 일정을 논의 중이다.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
제3자 쿠키(Third-Party Cookies)는 현재 도메인과 다른 도메인에서 발행한 쿠키를 말한다. 제3자 쿠키를 활용하면 사용자의 취향, 활동 정보 등을 파악할 수 있어 광고 마케팅 분야에서 자주 사용했으나, 원하지 않는 개인정보까지 유출될 수 있다는 큰 단점이 있다.
크롬은 이미 관련 법 준수를 위해 2020년 1월부터 제3자 쿠키의 중단을 예고했다. 그동안 영향이 큰 점을 고려해 지원 중단을 계속 미뤄왔으나, 2024년부터는 본격적으로 제3자 쿠키를 지원 중단할 예정이다.
구글이 대안으로 사용자의 개인정보는 보호하되, 기존의 제3자 쿠키가 하던 역할을 대체할 수 있는 Privacy Sandbox를 개발 중이니 참고하자.
이 항목에 대한 주요 브라우저 및 웹 개발자의 의견은 다음과 같다.
내부망 접근 규칙(Local Network Access) 적용의 일부로 하위 리소스(.js
, .css
등)를 요청할 때 내부망(사설 IP, localhost)에 대한 접근 제한을 검토 중이다. 정식 적용 일정은 불투명하나, 미리 보기로 일부 기능을 체험할 수 있다.
공개 웹 사이트(공개 IP로 접근 가능한 사이트)에서 내부망에 하위 리소스(.js
, .css
등) 요청 시 반드시 보안 컨텍스트(HTTPS)를 사용하도록 제한한다. 내부망의 하위 리소스에 접근하려면 보안 컨텍스트를 사용하도록 변경해야 한다.
Chrome 86 이상에서 실험적 웹 기능을 활성화해 접근 제한을 미리 체험할 수 있다.
내부망에 하위 리소스 요청 시 사전 요청을 보내 연결 허용 여부를 먼저 묻는다. 현재는 사전 요청 실패 시 개발자 콘솔에 경고만 노출한다.