본문 바로가기

자바스크립트

[JS] 자바스크립트의 렌더링 블록과 방지방법에 대한 정리(defer 와 async)

반응형

렌더링 블록

렌더링 블록이란 이름 그대로 브라우저의 렌더링을 막는다는 의미이다. 즉, 브라우저가 HTML 를 렌더링하는 것을 막는 것을 뜻하는데, 이러한 현상은 HTML을 파싱하는 도중 자바스크립트(스크립트 코드)나 CSS 가 존재하는 경우 발생하게 된다. 

 

블록 리소스

앞서 렌더링 블록이 브라우저의 렌더링을 막는 것이라 했는데, 여기서 렌더링을 막는 장애물을 블록 리소스라고 한다. 블록 리소스는 앞서 자바스크립트 코드나 CSS 가 해당된다.

 

자바스크립트의 렌더링 블록

렌더링 블록이 발생하는 이유 중 스크립트 태그로 인한 것이 있다. 보통 HTML 파싱 중에 스크립트를 만나게 되면 해당 스크립트를 파싱하기 위해 HTML 파싱은 잠시동안 중지되게 된다. 이로 인해 사용자는 로딩중인 빈화면을 오랫동안 보게 되는 문제가 생길 수 있다. 이를 해결하기 위한 제일 간단한 방법은 스크립트를 body 태그의 끝 부분에 위치시키는 것이다.

 

렌더링 블록 방지 방법 1 - 스크립트 태그를 body 태그 하단에 위치시키기

<body>
...
<script src="javascropt.js"></script>
</body>

 

단, 위와 같은 방식으로도 오랜 렌더링 지연이 걸릴 수 있는데, HTML 파일 자체가 아주 큰 경우,  자주 변경되는 동적인 코드가 존재하는 경우 등의 이유가 해당될 수 있다.

 

다행히도 이 문제를 개선하기 위한 <script> 태그의 속성으로 defer 와 async 가 존재한다. 

 

렌더링 블록 방지 방법2 - 스크립트 태그 속성 :: defer

defer 를 사용하게 되면, 브라우저의 HTML 파싱을 도중에 중지 시키지 않도록, 백그라운드에서 스크립트를 다운로드 한다. 즉, 보이지 않는 뒷면에서 이루어지기 때문에 브라우저는 브라우저대로 스크립트는 스크립트대로 별도 처리가 가능하다.

 

defer 속성은 다음과 같이 지정해서 사용한다.

<script defer src="a.js"></script>

 

위와 같이 지정해주면, 해당 스크립트는 백그라운드에서 다운로드 되어 브라우저 HTML 파싱에 영향을 미치지 않는다.  이렇게 다운로드된 스크립트는 DOMContentLoaded 이벤트 발생 이전에 실행되며, 이 때도 DOM 트리는 완성된 상태이다. 즉, DOM 트리에 접근하여 요소를 조작하는 것이 가능하다는 말이다.

 

<script defer src="a.js"></script> -- 순위 1
<script defer src="b.js"></script> -- 순위 2
<script defer src="c.js"></script> -- 순위 3

 

defer 속성의 특징이 한 가지 더 있는데, 이는 defer 속성이 부여된 스크립트가 여러 개 있을 경우, 속성을 부여한 순서대로 스크립트 실행 순서가 결정된다는 것이다. 즉, 동기적으로 실행되기 때문에 우선적으로 실행될 필요가 있는 스크립트를 젤 앞에 위치시키는 것이 좋다.

 

렌더링 블록 방지방법3- 스크립트 태그 속성 :: async

<script async src="a.js"></script>

 

async 라는 이름만 봐도 알겠지만, 비동기적으로 스크립트를 다운로드 한다. 비동기적이기 때문에 브라우저 파싱과정에 영향을 미치지 않는 것은 당연하고, 비동기적이므로 스크립트 간의 실행 순서도 우선 다운로드된 스크립트가 실행순위 1위가 된다. 

 

<script async src="a.js"></script>  -- 먼저 다운로드 되면 우선 실행
<script async src="b.js"></script>  -- 먼저 다운로드 되면 우선 실행
<script async src="c.js"></script>  -- 먼저 다운로드 되면 우선 실행

 

즉, 스크립트의 실행순서를 엄격하게 지켜야 하는 상황에서 사용 시 주의가 필요하다는 말이다. 다시 말해 정확한 실행 순서를 가지는 스크립트를 나열 할 때는 별도 추천되지 않으며, 광고나 데이터 분석 등과 같이 비동기적으로 실행되어도 문제 없는 스크립트(즉, 다른 스크립트 간 의존성이 없는 스크립트)에 부여해서 사용하는 것이 좋다.

 

반응형