Chrome 버전 133에서 사용할 수 있는 새로운 moveBefore()
DOM API를 발표합니다. 이 API를 사용하면 상태를 잃지 않고 DOM에서 요소를 더 쉽게 이동할 수 있습니다. 프로젝트에서 이를 사용하는 방법을 알아보려면 계속 읽어보세요.
DOM 변형 중에 상태 손실
appendChild()
API를 사용하여 DOM에 새 요소를 삽입하나요? 많은 개발자가 그렇습니다. 하지만 이미 DOM에 있는 요소를 사용하여 삽입 API(예: insertBefore()
)를 호출해 보신 적이 있나요? 그렇다면 먼저 요소를 이전 상위 요소에서 삭제한 다음 새 상위 요소에 다시 삽입하면 이 작업이 조용히 실행된다는 사실을 인지하지 못했을 수 있습니다. 1998년에 첫 번째 DOM 표준 초안이 도입된 이후 Document Object Model에는 삭제 및 삽입 원시만 있었기 때문입니다. DOM에서 한 위치에서 다른 위치로 '이동'한다고 생각할 때마다 실제로는 삭제하고 삽입하는 것입니다.
'이동'이 실제로는 '삭제 및 삽입'이라는 사실은 일반적으로 사용자 환경에 영향을 미치지 않습니다. 예를 들어 DOM에서 <p>
를 '이동'할 때는 이러한 두 작업이 방해가 되는 부작용이 없지만, 중요한 상태를 보유한 복잡한 노드(예: <iframe>
요소, 전체 화면의 요소, CSS 애니메이션 등)를 이동할 때는 암시적 '삭제' 작업이 모든 종류의 상태를 재설정합니다.
이로 인해 예상치 못한 부작용이 발생할 수 있습니다.
DOM 트리의 이동을 조작하여 상태 보존 데모 웹사이트에서 재설정되는 상태 유형을 확인할 수 있습니다. 다음 예는 요소를 한 상위 컨테이너에서 다른 상위 컨테이너로 이동할 때 CSS 애니메이션과 <iframe>
상태가 재설정되는 것을 보여줍니다.
이 제한으로 인해 동적 사용자 환경을 빌드하기가 어렵거나 불가능할 수 있습니다. 애플리케이션 상태가 갑자기 재설정되면 사용자는 불편함을 느끼고 혼란스러워하며, JavaScript 프레임워크 작성자는 이 문제를 해결하기 위해 프런트엔드 코드를 재구성하고, MorphDOM과 같은 복잡한 라이브러리를 작성하거나, 해결할 수 없는 문제를 강조 표시하는 버그 신고를 처리하는 데 수많은 시간을 소비하면서 이 문제를 해결합니다.
새로운 moveBefore()
API
Google은 DOM에 새로운 원시 작업을 추가하여 이 문제를 해결하기 시작했습니다. 이는 적절하게 '이동' 원시라고 하며, 새로운 moveBefore()
DOM API를 통해 개발자에게 노출됩니다.
moveBefore()
는 insertBefore()
와 동일한 인수를 사용하지만, 노드가 이미 DOM에 연결되어 있을 때 노드를 삭제하고 다시 삽입하는 대신 이 새로운 API는 대부분의 상태를 재설정하지 않고 타겟 노드를 새 상위 요소로 동시에 이동합니다. 이제 JavaScript 개발자는 이동 가능한 애니메이션, iframe, 전체 화면 요소 등으로 동적 환경을 빌드할 수 있습니다. chrome://flags/#atomic-move
실험 플래그를 사용 설정하고 데모 사이트를 방문하거나 2025년 2월 4일에 출시된 Chrome 버전 133을 사용해 직접 테스트해 볼 수 있습니다.
이 새 원시를 통해 JavaScript 작성자가 달성할 수 있는 동작의 예는 다음과 같습니다.
- 사용자가 웹사이트를 탐색할 때 동영상의 재생 상태를 유지합니다 (동영상이
<video>
또는<iframe>
요소에서 제공되는지 여부와 관계없음). - DOM에서 이동할 때 사용자 입력 필드의 포커스를 유지합니다.
- 새 콘텐츠가 DOM에 추가되거나 삭제될 때 애니메이션이 원활하게 완료되도록 허용합니다.
- 기존 DOM을 새 콘텐츠와 조정하기 위한 고화질 모핑 알고리즘
- 모달 대화상자, 팝오버, 전체 화면 요소를 열어 둡니다.
Google은 다른 브라우저와 함께 이 API를 웹 플랫폼에 도입하기 위해 노력하고 있으며, 오랜 기간의 개발자 요청을 충족하고 웹 플랫폼의 상당한 공백을 메우기 위해 곧 개발자에게 이 API를 제공할 수 있게 되어 기쁩니다.
언제나 그렇듯이 트위터 또는 아래 댓글을 통해 의견을 보내 주시고 crbug.com/new에 버그를 제출해 주세요.