'LINK'에 해당되는 글 1건

  1. 2013.11.28 HTML import을 이용하여 document.write 개선하기.

document.write을 사용하면 돔 랜더링이 멈추기 때문에 느리게 보인다. 그래서document.write을 대신하기 위한 다양한 방법이 나와있다. 하지만, 광고의 경우 다양한 곳에 삽입되기 때문에 대부분은 document.write을 사용한다.

이 문제를 해결하고자 최근에 웹성능의 본좌인 사우더스 아저씨가 HTML import을 활용한 방법을 제안했다.[링크] (HTML import는 본인과 크게 상관도 없고 아직 완성도가 있는 스팩인데 이런걸 활용하다니 좀 놀랐다.)

HTML import를 간단히 설명하면  Web Components을 사용하기 위한 방법으로 link태그를 이용하여 html을 로딩하는 방법이다.[링크]

자세한 내용은 원문[링크]을 참고하고 요약하면 사우더스 아저씨는 아래와 같이  import안에서 document.write를 하는 방법을 제안했다.

main.html

<link rel="import" href="ad.html">

<div id="ad_area" style="width: 480px; height: 60px; margin-left: 2em; margin-bottom: 2em;"></div>

<script>
var link = document.querySelector('link[rel=import]');
var content = link.import.querySelector('#ad');
document.getElementById('ad_area').appendChild(content.cloneNode(true));
</script>

ad.html
<div id="ad" style="background: #E99; border: 2px; font-size: 2em; text-align: center; padding: 8px;">
<script>
document.write("IMPORTED CONTENT<div style='font-size=0.8em;'>(using document.write)</div>");
</script>

근데 문제가 있다.

1. import는 동기로 로딩된다.[링크]

2. import한 html에서 document.write을 하면 main페이지에서 context로 실행되는 문제가 있다.[링크]

그래서 이를 해결하고자 아래와 같이 스크립트로 import을 삽입하고 ad.html에서 document.write을 재정의하여 현재 context로 실행하도록 했다.

main.html

<div id="ad_area" style="width: 480px; height: 60px; margin-left: 2em; margin-bottom: 2em;"></div>

<script>
  var link = document.createElement('link');
  link.rel = 'import';
  link.onload = function() {
    var link = document.querySelector('link[rel=import]');
    var content = link.import.querySelector('#ad');
    document.getElementById('ad_area').appendChild(content.cloneNode(true));
  };
  link.href = "ad.html";
  document.getElementsByTagName('head')[0].appendChild(link);
</script>

ad.html

<div id="ad" style="background: #E99; border: 2px; font-size: 2em; text-align: center; padding: 8px;">
<script>
document.write = function(msg) {
    document.currentScript.ownerDocument.write(msg);
};
document.write("IMPORTED CONTENT<div style='font-size=0.8em;'>(using document.write)</div>");
</script>


이렇게 document.write를 사용하면서 돔의 랜더링을 지연하지 않도록 개선할 수 있다.[링크]

물론 import의 안에서 실행되는 context의 이슈등 문제가 있어 당장 사용하기 힘들지만 아이디어는 좋은 것 같다.

그리고 사우더스는 HTML import가 기본으로 랜더링을 막지 말고 동작해야 한다고 제안했지만 이 문제는 쉽지 않다. 이 문제에 대해서는 다음에 알아보자. 또한 위의 방법은 오해가 있기 때문에 반드시 [링크]을 추가로 읽기 바란다.


관련글 

알고보면 랜더링을 막지 않는 import

Posted by 전용우
,