프론트 엔드 개발자라면 리플로우에 대해서 정확한 개념을 이해하고 있어야 한다. 사용자 경험을 개선하기 위해서는 과도한 리플로우가 발생하지 않도록 해야한다. 그렇다면 reflow
란 무엇일까. reflow
를 알기 위해서는 우선 브라우저가 렌더링 되는 과정을 이해해야 한다.
아래 이미지를 참고로 이해해보자.
Load
: 브라우저는 HTML
, CSS
, JS
, 이미지, 폰트 파일 등 렌더링에 필요한 리소스를 서버에게 요청하고 응답을 받는다.
HTML
과 CSS
는 렌더링 엔진에 의해 파싱되고 트리구조가 생성되며, 자바스크립트는 자바스크립트 엔진에 의해 파싱되고 AST
를 생성된다.
렌더링 엔진은 HTML
과 CSS
파일을 로드받은 다음, 파싱하여 DOM
과 CSSOM
을 생성하고, 그를 결합하여 렌더 트리를 생성한다.
자바스크립트 엔진은 JS
파일을 로드 받은 다음, 파싱하여 AST(Abstract Syntax Tree)
를 생성하고, 바이트 코드로 변환하여 실행한다. 자바스크립트는 인터프리터 언어이므로 문 단위로 해석되고 실행된다. 이때 자바스크립트는 DOM API
를 통해서 DOM
이나 CSSOM
을 변경할 수 있다. 변경된 DOM
과 CSSOM
은 다시 렌더 트리로 결합된다.
렌더 트리를 기반으로 HTML
요소의 레이아웃(위치와 크기)을 계산하고 브라우저 화면에 페인팅 한다.
이때 4번 과정에
dom
또는cssom
이 변경 되어 5번 과정을 다시 실행시켜야 하는 상황을Reflow
라고 한다.
크롬 개발자 도구에서 성능탭 > 기록 버튼 클릭 > 이벤트 로그탭을 보면 첫 레이아웃 이후에 의한 로그 이후부터 리플로우가 발생한 것을 확인할 수 있다.
위에서 언급했듯이 reflow
는 자바스크립트에 의한 dom
, cssom
의 조작에 의한 레이아웃의 변경때문에 일어난다. 특정 요소의 레이아웃이 변경이 되면 변경되는 요소 외에 모든 요소들의 위치와 크기도 다시 재계산 해야 하기 때문에 요소의 크기, 위치, 폰트 사이즈, 요소 생성, 요소 삭제등의 요인은 reflow
를 발생시키는 요인이 된다. 아래의 사진은 reflow
를 발생시키는 CSS
프로퍼티 들이다.
평소에 자주 사용하던 것들이 너무 많아서 놀라웠다. 이 프로퍼티들을 scroll 이벤트에 적용을 했을 때 reflow
얼마나 발생했을지... (충격적...)
reflow
의 발생을 최소화 하기위해서는 최대한 레이아웃과 관련된 css 의 사용을 피하는게 중요하다.
가능 한 경우 position
을 absolute
또는 fixed
로 설정하여 위치를 변경하는 방법도 있으며, 스크롤 이벤트 시 getBoundingClientRect 을 사용하지 않고 Intersection Observer API 를 사용하는 방법도 있을 수 있다.
프론트 엔드 개발자에게 사용자 경험을 고려하는것은 필수적인 요소이며 스레드에 부하를 줄 수 있는 요인은 가급적 피하는것이 좋다. 하지만 reflow
는 자바스크립트를 통해 동적인 페이지를 만들 때 필연적으로 발생하기 때문에 reflow
는 반드시 발생할 수 밖에 없다. 따라서 reflow
를 없앤다기 보다는 최소한으로 발생하는 방법에 대해서 고민하며 작업에 임하면 좋을 거 같다.