这是一篇原创翻译文章<原翻译网址:http://www.cnblogs.com/beiyuu/archive/2011/07/18/iframe-tech-performance.html>。原文地址 。
我们会经常使用iframes来加载第三方的内容、广告或者插件。使用iframe是因为他可以和主页面并行加载,不会阻塞主页面。当然使用iframe也是有利有弊的:Steve Souders在他的blog里面有阐述:Using Iframes Sparingly :
- iframe会阻塞主页面的onload事件
- 主页面和iframe共享同一个连接池
阻塞主页面的onload是这两个问题中最影响性能的方面。一般都是想让onload时间越早触发越好,一方面是用户体验过更重要的是google给网站的加载速度的打分:用户可以用IE和FF中Google工具栏来计时。
那么为了提高页面性能,怎样才能不阻塞主页面的onload事件的来加载iframe呢?
这篇讲了四种加载iframe的方法:普通iframe,onload之后加载iframe,setTimeout() iframe和异步加载iframe。每种方法的加载结果我都用IE8的时间线来展示。我建议多注意下动态异步加载这个方法,因为这是性能表现最佳的。另 外,还有一种友好iframe(friendly iframe)技术。他可能算不上是iframe加载的技术,但是必须使用iframe,他是无阻塞加载的。
普通方法加载iframe
这是一种人尽皆知的普通加载方法,它没有浏览器的兼容性问题。
1 < iframe src ="/path/to/file" frameborder ="0" width ="728" height ="90" scrolling ="auto" > </ iframe >
使用这种加载方法会在各浏览器中有如下表现:
- iframe会在主页面的onload之前加载
- iframe会在所有iframe的内容都加载完毕之后触发iframe的onload
- 主页面的onload会在iframes的onload触发之后触发,所以iframe会阻塞主页面的加载
- 当iframe在加载的过程中,浏览器的会标识正在加载东西,处于忙碌状态。
这里 是一个演示页面,时间线图显示出iframe会阻塞主页面的加载。
在onload之后加载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>
这种加载方法也是没有浏览器的兼容性问题的:
- iframe会在主页面onload之后开始加载
- 主页面的onload事件触发与iframe无关,所以iframe不会阻塞加载
- 当iframe加载的时候,浏览器会标识正在加载
这是 是一个测试页面,时间线图如下
- 其他等待主页面onload事件的代码可以尽早执行
- Google Toolbar计算你页面加载的时间会大大减少
setTimeout()来加载iframe
< 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>
- iframe会在主页面onload之前开始加载
- iframe的onload事件会在iframe的内容都加载完毕之后触发
- iframe不会阻塞主页面的onload事件(IE8除外)
- 为什么不会阻塞主页面的onload呢(IE8除外)?因为setTimeout()
- 当iframe加载的时候,浏览器会显示忙碌状态
< 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>
- iframe会在主页面onload之前开始加载
- iframe的onload会立即触发,因为iframe的内容一开始为空
- 主页面的onload不会被阻塞
- 为什么这个iframe不会阻塞主页面的onload?因为<body onload=”">
- 如果你不在iframe使用onload监听,那么iframe的加载就会阻塞主页面的onload
- 当iframe加载的时候,浏览器终于不显示忙碌状态了(非常好)
友好型iframe加载
- 先创建一个iframe。设置他的src为一个相同域名下的静态html文件
- 在这个iframe里面,设置js变量inDapIF=true来告诉广告它已经加载在这个iframe里面了
- 在这个iframe里面,创建一个script元素加上广告的url作为src,然后像普通广告代码一样加载
- 当广告加载完成,重置iframe大小来适应广告
- 这种方法也没有浏览器的兼容性问题。