iframe异步加载技术及性能

原文地址php

咱们会常用iframes来加载第三方的内容、广告或者插件。使用iframe是由于他能够和主页面并行加载,不会阻塞主页面。固然使用iframe也是有利有弊的:Steve Souders在他的blog里面有阐述:Using Iframes Sparingly:css

  • iframe会阻塞主页面的onload事件
  • 主页面和iframe共享同一个链接池

阻塞主页面的onload是这两个问题中最影响性能的方面。通常都是想让onload时间越早触发越好,一方面是用户体验过更重要的是google给网站的加载速度的打分:用户能够用IE和FF中Google工具栏来计时。html

那么为了提升页面性能,怎样才能不阻塞主页面的onload事件的来加载iframe呢?web

这篇讲了四种加载iframe的方法:普通iframe,onload以后加载iframe,setTimeout() iframe和异步加载iframe。每种方法的加载结果我都用IE8的时间线来展现。我建议多注意下动态异步加载这个方法,由于这是性能表现最佳的。另外,还有一种友好iframe(friendly iframe)技术。他可能算不上是iframe加载的技术,可是必须使用iframe,他是无阻塞加载的。ajax

普通方法加载iframe

这是一种人尽皆知的普通加载方法,它没有浏览器的兼容性问题。浏览器

1 <iframe src="/path/to/file" frameborder="0" width="728" height="90" scrolling="auto"> </iframe>

使用这种加载方法会在各浏览器中有以下表现:app

  • iframe会在主页面的onload以前加载
  • iframe会在全部iframe的内容都加载完毕以后触发iframe的onload
  • 主页面的onload会在iframes的onload触发以后触发,因此iframe会阻塞主页面的加载
  • 当iframe在加载的过程当中,浏览器的会标识正在加载东西,处于忙碌状态。

这里是一个演示页面,时间线图显示出iframe会阻塞主页面的加载。异步

个人建议:注意onload阻塞。若是iframe的内容只须要很短的时间来加载和执行,那么也不是个大问题,并且使用这种方法还有个好处是能够和主页面并行加载。可是若是加载这个iframe须要很长时间,用户体验就不好了。你得本身测试一下而后在 http://www.webpagetest.org/也作些测试,根据onload的时间看看是否须要其余加载方法。

在onload以后加载iframe

若是你想在iframe中加载一些内容,可是这些内容对于页面来讲不是那么的重要。或者这些内容不须要立刻展示给用户的,须要点击触发之类的。那么能够考虑在主页面载入以后加载iframe。
 1 <script>  2   3 //doesn't block the load event  4 function createIframe() { 5  var i = document.createElement("iframe"); 6  i.src = "path/to/file"; 7  i.scrolling = "auto"; 8  i.frameborder = "0"; 9  i.width = "200px";10  i.height = "100px";11  document.getElementById("div-that-holds-the-iframe").appendChild(i);12 };13 // Check for browser support of event handling capability 14 if (window.addEventListener) window.addEventListener("load", createIframe, false);15 else if (window.attachEvent) window.attachEvent("onload", createIframe);16 else window.onload = createIframe;17 </script>

这种加载方法也是没有浏览器的兼容性问题的:async

  • iframe会在主页面onload以后开始加载
  • 主页面的onload事件触发与iframe无关,因此iframe不会阻塞加载
  • 当iframe加载的时候,浏览器会标识正在加载

这是是一个测试页面,时间线图以下ide

这种方法比普通方法有什么好处呢?load事件会立刻触发,有两个好处:
  • 其余等待主页面onload事件的代码能够尽早执行
  • Google Toolbar计算你页面加载的时间会大大减小
可是,当iframe加载的时候,仍是会看到浏览器的忙碌状态,相对于普通加载方法,用户看到忙碌状态的时间更长。还有就是用户还没等到页面彻底加载完的时候就已经离开了。有些状况下这是个问题,好比广告。

setTimeout()来加载iframe

这种方法的目的是不阻塞onload事件。
Steve Souders(又是他?)有一个这种方法的测试页面(http://stevesouders.com/efws/iframe-onload-nonblocking.php)。他写道:“src经过setTimeout动态的设置,这种方法能够再全部的浏览器中避免阻塞”。
按 Ctrl+C 复制代码
<iframe id="iframe1" src="" width="200" height="100" 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>
按 Ctrl+C 复制代码
在除了IE8之外的全部浏览器中会有以下表现:
  • iframe会在主页面onload以前开始加载
  • iframe的onload事件会在iframe的内容都加载完毕以后触发
  • 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.appendChild(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>
神奇的地方就在<body onload=”">:这个iframe一开始没有内容,因此onload会当即触发。而后你建立一个script元素,用他来加载内容、广告、插件什么的,而后再把这个script添加到HEAD中去,这样iframe内容的加载就不会阻塞主页面的onload!你应该看看他在个浏览器中的表现:
  • iframe会在主页面onload以前开始加载
  • iframe的onload会当即触发,由于iframe的内容一开始为空
  • 主页面的onload不会被阻塞
  • 为何这个iframe不会阻塞主页面的onload?由于<body onload=”">
  • 若是你不在iframe使用onload监听,那么iframe的加载就会阻塞主页面的onload
  • 当iframe加载的时候,浏览器终于不显示忙碌状态了(很是好)
个人测试页给出下面的时间线:
转义字符让代码看着有些难受,这都不是问题。试试吧。

友好型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事件仍是会被阻塞。
相关文章
相关标签/搜索