본문으로 건너뛰기

비차단 스크립트 로딩의 최적의 방안

무료2015-11-27#JS#Solution#script的defer#defer属性#JavaScript无阻塞加载脚本#js并行加载脚本

비차단 방식으로 외부 스크립트를 로드하여 페이지 렌더링 속도 향상

##최적의 방안

단일한 최적의 방안은 없으며, 진정한 최적의 방안은 요구사항에 달려 있습니다. 최적의 스크립트 다운로드 기술을 선택하기 위한 의사결정 트리는 다음과 같습니다.

[caption id="attachment_860" align="alignnone" width="300"]최적의 스크립트 로딩 기술 선택을 위한 의사결정 트리 최적의 스크립트 로딩 기술 선택을 위한 의사결정 트리[/caption]

의사결정 트리에는 6가지 가능한 결과가 있습니다.

  • 다른 도메인, 순서 무관

메인 페이지의 도메인과 스크립트의 도메인이 다르기 때문에 XHR Eval, XHR 인젝션 및 Script in Iframe 기술은 이러한 상황에서 사용할 수 없습니다. Script Defer 기술은 스크립트가 순서대로 로드되도록 강제하므로 사용하지 않는 것이 좋으며, 반대로 스크립트가 도착하는 즉시 실행될 수 있다면 페이지 로딩이 더 빨라질 것입니다. 이 경우 Script DOM Element 기술이 최선의 선택이지만, Firefox에서 로드할 때 원치 않게 순서가 유지될 수 있습니다. 두 기술 모두 바쁨 표시기(상태 표시줄, 진행 표시줄, 아이콘, 커서)를 트리거하지만, 이를 피할 방법은 없습니다.

JavaScript 광고 및 컨트롤을 포함하는 웹 페이지가 이 경우에 해당합니다. 광고 및 컨트롤 스크립트의 도메인은 종종 메인 페이지와 다르지만, 서로 간의 의존성이 없으므로 로딩 순서는 중요하지 않습니다.

  • 다른 도메인, 순서 유지

앞서와 마찬가지로 메인 페이지와 스크립트의 도메인이 다르기 때문에 XHR Eval, XHR 인젝션 및 Script in Iframe 기술은 작동하지 않습니다. 로딩 순서를 보장하기 위해 Internet Explorer에서는 Script Defer 기술을, Firefox에서는 Script DOM Element 기술을 사용해야 합니다. 두 기술 모두 바쁨 표시기를 트리거한다는 점에 유의하십시오.

다른 서버에서 의존성이 있는 여러 JavaScript 파일을 다운로드하는 페이지가 이 경우에 해당합니다.

  • 동일 도메인, 순서 무관, 바쁨 표시기 없음

XHR Eval과 XHR 인젝션은 바쁨 표시기를 트리거하지 않는 유일한 두 가지 기술입니다. 이 두 가지 XHR 기술 중에서 저는 스크립트 재구성이 필요하지 않은 XHR 인젝션을 더 권장합니다.

백그라운드에서 JavaScript 파일을 다운로드하려는 웹 페이지에 적용할 수 있습니다.

  • 동일 도메인, 순서 무관, 바쁨 표시기 있음

XHR Eval, XHR 인젝션 및 Script in Iframe은 Internet Explorer와 Firefox 전체에서 로딩 순서를 유지하지 않는 유일한 기술입니다. Script in Iframe 기술은 바쁨 표시기를 트리거하고 페이지 크기를 약간만 증가시키기 때문에 최선의 선택처럼 보일 수 있습니다. 하지만 저는 스크립트 재구성 없이 사용할 수 있고 다른 의사결정 트리 분기의 선택지이기도 한 XHR 인젝션을 더 선호합니다. 바쁨 표시기를 활성화하기 위해 추가적인 JavaScript가 필요합니다. XHR이 전송될 때 상태 표시줄과 커서를 활성화하고, XHR이 반환될 때 복구하는 방식을 Managed XHR Injection이라고 합니다.

  • 동일 도메인, 순서 유지, 바쁨 표시기 없음

XHR Eval과 XHR 인젝션은 바쁨 표시기를 트리거하지 않는 두 가지 기술입니다. 저는 스크립트 재구성이 필요 없는 XHR 인젝션을 더 선호합니다. 로딩 순서를 유지하려면 또 다른 유형의 Managed XHR Injection이 필요합니다. 이 경우 필요에 따라 XHR 응답을 큐에 넣고 순서대로 실행할 수 있습니다. 지연 로드되는 스크립트는 이전의 모든 스크립트가 다운로드되고 실행된 후에 시작되어야 합니다.

내부 의존성이 있는 여러 스크립트가 백그라운드에서 다운로드되는 페이지가 이 경우에 해당합니다.

  • 동일 도메인, 순서 유지, 바쁨 표시기 있음

Internet Explorer의 Script Defer 기술과 Firefox의 Script DOM Element 기술이 가장 선호되는 솔루션입니다. Managed XHR Injection 및 Managed XHR Eval 기술도 가능합니다. 하지만 메인 페이지에 추가 코드를 더하게 되며 구현이 좀 더 복잡합니다.

P.S. 위의 내용은 참고 자료에서 발췌한 것입니다.

##XHR Eval

xhr로 스크립트 str을 가져온 후 eval(str)로 실행합니다.

장점: 비차단(다른 리소스의 다운로드를 차단하지 않음)

단점: 동일 출처 정책(Same Origin Policy, SOP) 제한으로 외부 스크립트가 실행 중인 스크립트와 동일한 도메인(프로토콜, 포트 번호, 도메인 이름)에 있어야 합니다. 또한 외부 스크립트의 재구성이 필요할 수 있습니다.

##XHR 인젝션

xhr로 스크립트 str을 가져온 다음, strscript 요소에 넣고 DOM 트리에 삽입하여 실행합니다.

장점: 비차단

단점: SOP 제한

##Script in Iframe

페이지의 iframe과 다른 리소스는 병렬로 로드됩니다. 이 특징을 이용해 스크립트의 비차단 로딩을 구현할 수 있습니다.

<!-- 在主页面中内包含iframe,jsWrapper.html应该与主页面同域 -->
<iframe src="jsWrapper.html" frameborder="0" width="0" height="0" id="myIframe"></iframe>

//---js通信
// 主页面 -> iframe
var winIframe = window.frames['myIframe'].contentWindow;
winIframe.fun();    // winFrame是iframe中的window对象
// iframe -> 主页面
var winMain = window.parent;
winMain.fun();      // winMain是主页面中的window对象

주의: srcx.js가 아니라 x.html이어야 합니다. iframe은 반환된 내용을 html 문서로 간주하므로, 스크립트를 html을 이용해 인라인 스크립트로 감싸야 합니다.

장점: 비차단

단점: SOP 제한 및 외부 스크립트 재구성 필요

##Script DOM Element

동적으로 script 요소를 생성하고 src를 설정하여 DOM 트리에 삽입합니다.

장점: 비차단, 교차 도메인 허용, 외부 스크립트 재구성 불필요, 스크립트 실행 순서 보장 가능

단점: IE에서는 스크립트 실행 순서를 보장할 수 없음

##Script Defer

IE는 script 태그의 defer 속성을 지원하여 다른 리소스의 병렬 다운로드를 허용합니다.

장점: 쉬움(script 태그에 속성 하나만 추가하면 됨), 스크립트 실행 순서 보장 가능

단점: 일부 브라우저(예: 구버전 FF)는 이 속성을 지원하지 않을 수 있습니다. 하지만 HTML5 표준에서 deferasync의 지위가 확립되었고 onload 콜백이 추가되어 현재 호환성 문제는 심각하지 않습니다. 더 자세한 정보는 HTML5 <script>元素async,defer异步加载를 확인하십시오.

##document.write Script Tag

document.write를 사용하여 script 태그를 페이지에 씁니다.

장점: IE에서 document.write로 작성된 여러 스크립트는 병렬로 로드될 수 있습니다.

단점: IE에서만 비차단이며, 이러한 스크립트를 로드할 때 다른 리소스(이미지, DOM)는 모두 차단됩니다.

###참고 자료

  • 《High Performance Web Sites》(국내 번역서명: 고성능 웹사이트 제작)

댓글

아직 댓글이 없습니다

댓글 작성