
우리가 보이는 지금 이 화면이 사용자에게 보여지려면, 결국 컴퓨터가 이해할 수 있는 형태로 전달되어야 한다. 하지만 사람이 기계어를 직접 작성하기는 어렵기 때문에 HTML, CSS, JavaScript 같은 코드로 작성하고, 이를 브라우저나 엔진이 해석해서 실행한다.
HTML, CSS, JS는 컴파일 방식이 아닌 인터프리터로 실행되며 브라우저나 Node.js 같은 런타임 환경에서 실행된다.
이렇게 해석한 결과를 화면에 시각적으로 출력하는 것을 렌더링이라고 한다.
리렌더링 시 상황에 따라 어디 지점부터 다시 처리되는지, API 통신에서 받은 데이터를 보여줄 때 글자들을 어떤 태그로 감싸고 어떻게 추가할지, 데이터 결과가 10개면 10개의 컴포넌트를 어떻게 만들지 등을 고려할 때 어떻게 최적화할 수 있을지 이 과정으로 알아보려 한다.

브라우저는 일반적으로 사진과 같은 순서로 화면을 만든다.
DOM은 HTML 자체가
<html>
<body>
</body>
</html>
이렇듯 트리로 구성되어 있다. 브라우저는 이 구조를 읽어서 그에 맞는 객체를 만들고 트리 구조를 만든다.
HTML은 문자열로 이루어진 순수한 텍스트이고, 브라우저 렌더링 엔진에서는 이를 파싱해서 트리 구조인 DOM을 생성한다.
이 만들어진 DOM을 통해
const menu = document.getElementById("menu"); //type: object
위와 같이 JavaScript는 요소를 찾고 수정할 수 있다. document.getElementById 같은 메서드를 DOM API라고 한다. JS는 DOM이 되지는 않지만 DOM 구조에 변화를 줄 수 있다.
브라우저는 HTML을 읽다가 CSS가 나오면 HTML 파싱을 잠시 멈추고 CSS를 파싱한다. 그리고 CSS 내용을 바탕으로 CSSOM을 생성한다. 참고로 CSSOM도 트리 구조이다.
렌더트리는 DOM과 CSSOM이 합쳐진 트리 구조로, 실제 화면에 표시되는 요소들만 포함한다.
<button style="display: none;">☰</button>
위와 같은 코드처럼 DOM에는 존재하지만 화면에는 보이지 않는다면 렌더 트리에는 포함되지 않는다.
만약 컴포넌트 하나를 보였다 안 보였다 해야 하는데 display: none, 리액트 삼항연산자 중 뭐가 비효율적일까?
삼항연산자이다. display: none은 DOM에는 남아 있고 렌더 트리에서 빠진다. 반면 삼항연산자는 DOM 자체가 바뀌기 때문에 더 오래걸릴것이다.
렌더 트리를 기준으로 각 요소의 크기와 위치를 계산하는 과정이다.
ex) 햄버거 아이콘 버튼이 어디에 놓일지, 너비와 높이가 얼마인지 등
계산이 끝난 요소를 기준으로 실제 화면에 그리는 과정이다. 이때 사용자가 우리가 만든 화면을 실제로 보게 된다.
만약 z-index를 지정해서 element 여러 개가 겹칠 때 어떠한 단계에서 변경되고 어떠한 게 보여야할까?
레이아웃에서 위치와 크기가 먼저 결정되어 페인트때 좌표의 색이나 겹침 순서 등이 실제 화면에 그려진다. 그래서 z-index가 더 큰게 먼저 보이는 것도 페인트때 일어난다.
그럼 최적화를 어디서 해야하고 언제 성능이 느려지고 어떤 과정이 제일 오래걸릴까?
레이아웃이 계산할 게 많아서 제일 오래걸리는 편이다. DOM은 글자를 읽고 바로 그에 맞는 객체를 만들어 넣으면 되는데, 레이아웃은 CSS에 따라서 각 요소의 크기와 위치를 모두 계산해야 하기 때문이다. 예를 들어 화면 크기가 변했을 때도 DOM을 다시 만들기보다 레이아웃을 다시 계산하고 페인트가 다시 일어난다.
버튼 색이 바뀌었을 때, 화면 사이즈 축소, 삼항연산자, API 결과 반영은 어디서 일어날까?
버튼 색만 바뀌면 페인트, 화면 사이즈 축소는 레이아웃, 삼항연산자 및 API 결과 반영은 DOM 변경으로 이어질 것이다.
이처럼 리렌더링은 상황마다 다를 텐데, 이 과정을 고려하지 않는다면 성능에 악영향을 줄 수 있기 때문에 불필요한 DOM 변경이나 잦은 스타일 변경을 줄이면서 코드를 작성하는 것이 필요하다.
또한, 브라우저는 위에서 아래로 파싱되기 때문에, 자바스크립트가 찾을 요소가 먼저 생성되었는지를 생각하고 짜야 한다. 중간에 script 태그를 만나면 HTML 파싱이 잠시 중단되고 JavaScript가 먼저 실행된다.
그래서 보통은 자바스크립트를 body 태그 맨 아래에 두거나, DOM 생성 이후에 실행되도록 작성한다.
API 통신도 마찬가지로 자바스크립트가 브라우저와 서버 사이를 연결해서 데이터를 받아오고, 그 데이터를 다시 화면에 반영하기 때문에 이런 과정들을 이해하고 페이지 로딩 시간 단축이나 화면을 더 효율적으로 그리는 것이 중요하다.
이번에 개념을 다시 정리하면서 흐름을 더 명확하게 이해할 수 있었는데 앞으로 더 안정적이고 성능을 고려한 개발을 하고 싶다.