브라우저 렌더링

2018. 7. 26. 15:44Dev

반응형

HTML 구조를 다루는 DOM 파서 

CSS 구조를 다루는 CSSOM 파서

이 둘의 작업이 완료되면 렌더링 트리를 만들어 렌더링이 시작되고 페인팅되어 브라우저에서 우리가 볼 수 있게 된다.


문제는 이 파서들의 작업을 멈추게 하는 경우가 있다는 것.


크롬 개발자도구의 네트워크 탭 하단을 보면 DOMContentLoaded 항목의 속도가 표시되어 있는데 의미하는 바는 다음과 같다.

HTML 다운로드 시간 + HTML DOM 빌드 시간


렌더링을 빠르게 구축한다는 것은 DOMContentLoaded 에 해당하는 시간을 줄이고 파서 차단을 최소화 시킨다는 말이다.



HTML, CSS, JS 상호작용 메커니즘


서버에 http 요청시 서버는 HTML 을 응답하는데 이 과정에는 우리가 인지하지 못하는 컴퓨터간의 효율적인 낮은 수준 언어로 응답받게 된다. 이 응답받은 코드를 우리가 일반적으로 html 코드라고 보는 형태로 만들게 되는데 DOM 파서가 이를 담당한다.

HTML 파싱 중 스크립트 태그를 만나면 파서를 차단한다.(실제로 스크립트 위치 아래에 있는 DOM은 접근하지 못한다. 파서가 중단된 상태로 스크립트가 실행되기 때문이다. 만약 async 라면 접근 할 수도 있다. 접근 할 수도 있다는 것은 스크립트 실행 시기에 HTML 파서가 DOM을 빌드 완료했을 수도 있고 못했을 수도 있기 때문이다. 그렇기 때문에 모던 프론트프레임워크의 스크립트 태그 위치가 body 가장 하단에 위치하는게 일반적이다. 스크립트가 렌더링까지 맡기 때문이다.)


CSS는 렌더링의 주요 자원이다. 이는 CSS가 있다면 CSS 다운로드 및 파싱이 완료되기 전까지 렌더링 하지 않는다는 것이다.

스크립트가 비동기 요청이 아닐 경우 CSS가 파싱되어 CSSOM을 빌드하기 전까지 DOMContentLoaded 이벤트를 호출하지 못하도록 HTML 파서를 차단한다. 이는 스크립트가 CSS쿼리를 이용한 로직이 있을 수도 있기 때문에 위험성을 피하고자 함이다.


결과적으로 렌더링을 더 빠르게 하기 위해서는 

1. 주요 자원(css, js, html)이 되는 단일 파일 크기를 줄여 다운로드 시간을 줄인다.

2. 외부스크립트로 작성하고 async 속성을 사용하여 HTML 파서를 차단하지 않도록 한다.

3. 주요 자원 요청 수를 최소화 한다.


구글에서 더 보기


여기서 두 번째 방법은 주의해서 적용해야 한다. 어떤 스크립트는 DOM이나 CSSOM 구조에 의존하고 있는 경우도 있기 때문이다. 그리고 모던 웹에서는 스크립트가 렌더링 책임을 맡고 있기 때문에 파서 차단이 중요하지 않을 수도 있다.



참고로 DOMContentLoaded 에는 이미지 처리 시간이 포함되어 있지 않다. 

Load라는 항목도 있는데 이는 우리가 잘 알고 있는 onload 이벤트에 해당하는 항목이다. Load는 이미지 다운로드 시간을 포함한다.

인라인 스크립트나 외부 스크립트 모두 상관없이 동일하게 파서를 차단한다. 차이점은 외부 스크립트같은 경우 async 속성을 사용해 파서 차단을 필할 수 있다는 점.


DOMContentLoaded 이벤트를 감지해서 뭔가 실행시킬 수 있지 않을까 싶지만 이 순간을 포착하기란 쉽지 않다. 왜냐하면 스크립트가 실행되는 시점보다 빠를 수 있기 때문이다.

반응형