これはオリジナルの翻訳記事です。 元のアドレス。
私たちはサードパーティのコンテンツ、広告、プラグインを読み込むために iframe をよく使用します。 iframe が使用されるのは、メイン ページと並行してロードでき、メイン ページをブロックしないためです。もちろん、iframe の使用には長所と短所があります: Steve Souders は彼のブログで説明しています: Iframe を控えめに使用する:
iframe はメイン ページの onload イベントをブロックします
メイン ページと iframe は同じ接続を共有しますpool
メイン ページの onload のブロックは、これら 2 つの問題の中で最もパフォーマンスに影響を与える側面です。一般的に、オンロード時間はできるだけ早くトリガーされるようにしたいと考えています。一方で、ユーザーはそれを経験していますが、さらに重要なことに、Google は Web サイトの読み込み速度をスコアリングしています。ユーザーは IE と FF の Google ツールバーを使用して、次のことを行うことができます。時間を計る。
この記事では、iframe をロードする 4 つの方法について説明します。通常の iframe、onload 後の iframe のロード、setTimeout() iframe、および iframe の非同期ロードです。 IE8 のタイムラインを使用して、各メソッドの読み込み結果を表示します。動的非同期読み込み方法のパフォーマンスが最も優れているため、動的非同期読み込み方法にもっと注意を払うことをお勧めします。さらに、Friendly iframe (フレンドリー iframe) テクノロジーもあります。これは iframe 読み込みテクノロジとはみなされないかもしれませんが、ブロックせずに読み込まれるため、iframe を使用する必要があります。
これはよく知られた通常のロード方法であり、ブラウザの互換性の問題はありません。
<iframe src="/path/to/file" frameborder="0" width="728" height="90" scrolling="auto"> </iframe>
この読み込み方法を使用すると、各ブラウザで次のパフォーマンスが得られます:
frame はメイン ページの onload の前に読み込まれます
iframe は、すべての iframe コンテンツが読み込まれた後に iframe の onload をトリガーします
iframe の onload がトリガーされた後にメイン ページの onload がトリガーされるため、iframe はメイン ページの読み込みをブロックします
iframe の読み込み中、ブラウザーはそのことを示します。何かをロード中でビジー状態です。
これはデモ ページです。タイムラインは、iframe がメイン ページの読み込みをブロックすることを示しています。
私の提案: onload ブロックに注意してください。 iframe のコンテンツのロードと実行に短時間しかかからない場合は、大きな問題はありません。この方法を使用すると、メイン ページと並行してロードできるという利点があります。ただし、この iframe の読み込みに時間がかかると、ユーザー エクスペリエンスが非常に低下します。自分でテストしてから、http://www.webpagetest.org/ でテストを行って、オンロード時間に基づいて他の読み込み方法が必要かどうかを確認する必要があります。
iframe にコンテンツをロードしたいが、そのコンテンツはページにとってそれほど重要ではない場合。または、コンテンツをユーザーにすぐに表示する必要はありませんが、クリックしてトリガーする必要があります。次に、メイン ページが読み込まれた後に iframe を読み込むことを検討できます。
<script type="text/javascript">//doesn't block the load eventfunction createIframe(){ var i = document.createElement("iframe"); i.src = "path/to/file"; i.scrolling = "auto"; i.width = "200px"; i.height = "100px"; i.frameborder = "0"; document.getElementById("div").appendChild(i);};//Check for browser support of event handling capabilityif (window.addEventListener) window.addEventListener("load",createIframe,false);else if(window.attachEvent) window.attachEvent("onload",createIframe);else window.onload = createIframe;</script>
この読み込み方法にはブラウザ互換性の問題もありません:
iframe はメイン ページの onload 後に読み込みを開始します
メイン ページの onload イベント トリガーは iframe とは関係がないため、iframe は読み込みをブロックしないでください
iframe が読み込まれると、ブラウザは読み込み中であることを示します
これはテストページであり、タイムラインは次のとおりです
この方法の利点は何ですか?普通の方法?ロード イベントはすぐにトリガーされ、これには次の 2 つの利点があります:
メイン ページの onload イベントを待機している他のコードをできるだけ早く実行できる
Google ツールバーがページの読み込みを計算するのにかかる時間は、大幅に削減されました
ただし、iframe が読み込まれると、ブラウザのビジー状態が表示されます。通常の読み込み方法と比較して、ユーザーにはビジー状態が長時間表示されます。また、ページが完全に読み込まれる前にユーザーが離脱する可能性もあります。広告など、これが問題となる状況もあります。
このメソッドの目的は、onload イベントをブロックすることではありません。
Steve Souders (また彼?) が、このメソッドのテスト ページを作成しています (http://stevesouders.com/efws/iframe-onload-nonblocking.php)。彼は、「Src は setTimeout を介して動的に設定され、すべてのブラウザでのブロックを回避します。」と書いています。
<iframe id="iframe1" src="" width="200" height="200" border="2"></iframe><script>function setIframeSrc(){ var s = "path/to/file"; var iframe1 = document.getElementById("iframe1"); if( -1 == navigator.userAgent.indexOf("MSIE")){ iframe1.src = s; }else { iframe1.location = s; }}setTimeout(setIframeSrc,5);</script>
は、IE8 を除くすべてのブラウザで次のように動作します:
iframe は、メイン ページの onload の前に読み込みを開始します
iframe のすべてのコンテンツが読み込まれた後に、iframe の onload イベントがトリガーされます
iframeメイン ページの onload イベントをブロックしません (IE8 を除く)
メイン ページの onload イベントをブロックしないのはなぜですか (IE8 を除く)?なぜなら setTimeout()
当iframe加载的时候,浏览器会显示忙碌状态
下面是时间线图
因为IE8的问题,这种技术就不适合很多网站了。如果有超过10%的用户使用IE8,十分之一的用户体验就会差。你会说那也只是比普通加载差一点点,其实普通加载性能上也不差。onload事件对于10%的用户来说都更长。。。。额,你自己考虑吧。但是最好在看了下面这个很赞的异步加载方法之后再决定吧。
我在参加Velocity 2010的时候,Meebo的两个工程师(@marcuswestin and Martin Hunt)做了一个关于他们的Meebo Bar的演讲。他们使用iframe来加载一些插件,并且真正做到了无阻塞加载。对于有的开发者来说,他们的做法还比较新鲜。很赞,超级赞。但是一些原因导致这种技术没有得到相应的关注,我希望这篇blog能把它发扬光大。
<script>(function(d){ var iframe = d.body.append(d.createElement('iframe')); doc = iframe.contentWindow.document; // style the iframe with some css iframe.style.cssText = "position:absolute;width:200px;height:100px;left:0px"; doc.open().write('<body onload="'+'var d = document;d.getElementsByTagName(\'head\')[0].'+'appendChild(d.createElement(\'script\')).src'+'=\'\/path\/to\/file\'">'); doc.close();//iframe onload event happens})(document);</script>
神奇的地方就在
:这个iframe一开始没有内容,所以onload会立即触发。然后你创建一个script元素,用他来加载内容、广告、插件什么的,然后再把这个script添加到HEAD中去,这样iframe内容的加载就不会阻塞主页面的onload!你应该看看他在个浏览器中的表现:iframe会在主页面onload之前开始加载
iframe的onload会立即触发,因为iframe的内容一开始为空
主页面的onload不会被阻塞
为什么这个iframe不会阻塞主页面的onload?因为
如果你不在iframe使用onload监听,那么iframe的加载就会阻塞主页面的onload
当iframe加载的时候,浏览器终于不显示忙碌状态了(非常好)
我的测试页 给出下面的时间线:
转义字符让代码看着有些难受,这都不是问题。试试吧。
这是用来加载广告的。虽然这不是一种iframe的加载技术,但是是用iframe来盛放广告的。他的亮点不在于iframe如何加载,而是主页面、iframe、广告如何协同工作的。如下:
先创建一个iframe。设置他的src为一个相同域名下的静态html文件
在这个iframe里面,设置js变量inDapIF=true来告诉广告它已经加载在这个iframe里面了
在这个iframe里面,创建一个script元素加上广告的url作为src,然后像普通广告代码一样加载
当广告加载完成,重置iframe大小来适应广告
这种方法也没有浏览器的兼容性问题。
Ad Ops Council在推荐过这个方法 ,AOL也是用这种方法。想看看源码: 这里有一个 。一家瑞典的出版社Aftonbladet对于这种加载有很不错的结论:在他们的主页上,加载时间减少30%,用户每周增加7%,新闻部分的点击量增加35%。我建议可以看看他们的资料: High Performance Web Sites, With Ads: Don’t let third parties make you slow
我没有创建相关的测试页,所以也没有第一首的资料。从我调研的结果来说:
如果你只想在你的网页上调用一个确定的src地址的iframe的话这个方法不是很有用。
如果你想在网页上展示多个广告,比较灵活的方法的是:加载一个广告,然后更新iframe加载另一个主页面的DOMContentLoaded时间不会被阻塞,页面渲染也不会被阻塞,当然,主页面的onload事件还是会被阻塞。
作者: BeiYuu
原文地址: iframe异步加载技术及性能