본문으로 건너뛰기

인라인 스크립트 배치

무료2015-11-27#JS#Solution#JavaScript行内脚本#css阻塞渲染#逐步渲染

인라인 스크립트의 위치가 적절하지 않으면 CSS가 페이지 렌더링을 차단할 수 있습니다.

1. 인라인 스크립트의 렌더링 차단 방지

  • 인라인 스크립트를 하단(body 종료 태그 앞)으로 이동

  • 비동기 콜백을 사용하여 자바스크립트 실행 시작

  • script 태그의 defer 속성 사용

인라인 스크립트를 하단으로 이동

인라인 스크립트를 body 종료 태그 바로 앞에 배치합니다.

장점: 사용이 간편하며, 페이지 내의 이미지 등 리소스와 하단에 위치한 인라인 스크립트가 병렬로 다운로드됩니다.

단점: 여전히 페이지 렌더링을 차단합니다. 만약 인라인 스크립트의 실행 시간이 길다면(300ms 이상), 이 간단한 방법은 적절하지 않습니다.

비동기 방식으로 스크립트 실행 시작

setTimeout(doStuff, 0)을 통해 스크립트를 비동기적으로 실행합니다. Firefox에서는 250ms의 지연이 필요합니다(250은 Nglayout.initialpaint.delay 값입니다).

장점: 점진적 렌더링(Progressive Rendering)이 가능합니다. 인라인 스크립트 실행이 시작되기 전에 브라우저가 먼저 DOM 콘텐츠(대부분 텍스트)를 렌더링합니다.

단점: 이미지 렌더링을 차단할 수 있습니다. 이미지 응답이 돌아왔을 때 doStuff가 실행 중이라면, 이미지는 doStuff가 끝날 때까지 표시되지 않습니다. 이럴 때는 setTimeout 대신 window.onload를 사용하여 스크립트 실행을 시작해야 합니다. 물론 인라인 스크립트 실행 시간이 매우 짧다면(300ms 미만), setTimeout을 사용해도 무방합니다.

P.S. 실행 시간이 매우 긴 인라인 스크립트의 경우, 가장 이상적인 해결책은 300ms마다 실행 단위를 나누어 setTimeout(doChunk, 300)과 같이 처리하는 것입니다. 하지만 이를 위해서는 큰 로직을 작은 조각(300ms 내에 완료 가능한 수준)으로 나누는 대규모 코드 리팩토링이 필요합니다.

script 태그의 defer 속성 사용

defer 속성은 인라인 스크립트에도 적용 가능하며, 브라우저가 페이지를 계속 파싱하고 렌더링하는 동안 인라인 스크립트의 실행을 지연시킬 수 있게 해줍니다.

장점: 리소스 병렬 다운로드

단점: 렌더링 차단. 실행 시간이 짧은 인라인 스크립트에만 적합하며, 아주 긴 스크립트는 여전히 setTimeout이 필요합니다.

2. 스타일시트 또한 인라인 스크립트를 차단함

브라우저는 JS를 포함된 순서대로 실행하는 것 외에도, CSS를 포함된 순서대로 파싱하는 것을 보장합니다 (파싱 순서가 다르면 스타일 적용 결과가 달라질 수 있기 때문입니다. 예: 동일 우선순위의 스타일 덮어쓰기 규칙).

잘 알려지지 않은 사실: 브라우저는 CSS와 JS의 파싱 순서 또한 유지합니다. 만약 인라인 스크립트를 스타일시트 뒤에 배치하면 리소스 다운로드가 눈에 띄게 지연됩니다 (결과적으로 스타일시트 다운로드가 완료되고 인라인 스크립트 실행이 끝난 후에야 후속 리소스 다운로드가 시작됩니다).

이는 인라인 스크립트 내에 스타일시트의 스타일에 의존하는 코드(예: document.getElementsByClassName())가 포함되어 있을 수 있기 때문입니다.

결론: 스타일시트 뒤에 오는 인라인 스크립트는 모든 후속 리소스의 다운로드를 차단합니다. (반대로 말하면, 스타일시트 뒤에 인라인 스크립트가 없다면 스타일시트는 다른 리소스와 병렬로 다운로드됩니다. 물론 인라인 스크립트 앞에 스타일시트가 있든 없든, 인라인 스크립트 자체는 후속 리소스 다운로드를 차단합니다.)

3. 요약

인라인 스크립트는 CSS를 차단(Blocking) 상태로 만들 수 있습니다. 오직 외부 스크립트만 사용함으로써 이 문제를 피할 수 있습니다.

참고 자료

  • 《고성능 웹사이트 구축을 위한 고급 가이드(Even Faster Web Sites)》

댓글

아직 댓글이 없습니다

댓글 작성