转载地址:翻译文章-iframe异步加载技术及性能
英文原文:Iframe loading techniques and performance

我们会经常使用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

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

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

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

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

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

我的建议:注意onload阻塞。如果iframe的内容只需要很短的时间来加载和执行,那么也不是个大问题,而且使用这种方法还有个好处是可以和主页面并行加载。但是如果加载这个iframe需要很长时间,用户体验就很差了。你得自己测试一下,然后在 http://www.webpagetest.org/ 也做些测试,根据onload的时间看看是否需要其他加载方法。

在onload之后加载iframe

如果你想在iframe中加载一些内容,但是这些内容对于页面来说不是那么的重要。或者这些内容不需要马上展现给用户的,需要点击触发之类的。那么可以考虑在主页面载入之后加载iframe。

 <script>   //doesn't block the load event
i.src ="path/to/file";
i.scrolling ="auto";
i.frameborder ="0";
i.height ="100px";
if (window.addEventListener)
window.addEventListener("load", createIframe, false);
else if (window.attachEvent)
window.attachEvent("onload", createIframe);
else
window.onload = createIframe;
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

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

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

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

这种方法比普通方法有什么好处呢?load事件会马上触发,有两个好处:
- 其他等待主页面onload事件的代码可以尽早执行
- Google Toolbar计算你页面加载的时间会大大减少

但是,当iframe加载的时候,还是会看到浏览器的忙碌状态,相对于普通加载方法,用户看到忙碌状态的时间更长。还有就是用户还没等到页面完全加载完的时候就已经离开了。有些情况下这是个问题,比如广告。

setTimeout()来加载iframe

这种方法的目的是不阻塞onload事件。

Steve Souders(又是他?)有一个这种方法的测试页面(http://stevesouders.com/efws/iframe-onload-nonblocking.php)。他写道:“src通过setTimeout动态的设置,这种方法可以在所有的浏览器中避免阻塞”。

<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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在除了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;"; 

//iframe onload event happens
})(document); </script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

神奇的地方就在:这个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事件还是会被阻塞。

项目地址:http://www.cnblogs.com/beiyuu/archive/2011/07/18/iframe-tech-performance.html

iframe加载方案及性能的更多相关文章

  1. iframe异步加载技术及性能

    我们会经常使用iframes来加载第三方的内容.广告或者插件.使用iframe是因为它可以和主页面并行加载,不会阻塞主页面.当然使用iframe也是有利有弊的:Steve Souders在他的blog ...

  2. 判断iframe加载完成

    一.js判断 var parFrame = document.getElementById("oIframe"); if(parFrame.attachEvent){ parFra ...

  3. vs2010 未能正确加载方案中的一个或多个项目

    Visual studio在打开解决方案时,往往会碰到一个这样的错误,提示说:未能正确加载方案中的一个或多个项目: 我们可以通过以下步骤来解决该问题:首先,在相应的sln类型文件上点击右键,选择用记事 ...

  4. ECMA Script 6_模块加载方案 ES6 Module 模块语法_import_export

    1. 模块加载方案 commonJS 背景: 历史上,JavaScript 一直没有模块(module)体系, 无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来. 其他语言都有这项功能: ...

  5. iframe 加载闪过白块问题

    每天学习一点点 编程PDF电子书.视频教程免费下载:http://www.shitanlife.com/code 在使用iframe时,iframe背景为白块,刷新时也会闪过白块.如果刷新时间长,就会 ...

  6. iframe 加载外部资源,显示隐藏loading,onload失效

    在项目中使用iframe 来加载外部资源,需要在iframe请求外部资源的时候,需要显示一个loading,在加载完成后,将这个loading隐藏掉,刚开始看到W3C中 iframe有一个 onloa ...

  7. 判断iframe加载完成、用于当ifame加载完成时执行一些操作

    window.frames["iframec"].addEventListener( "load", function(){ window.frames[&qu ...

  8. [JavaScript] iframe加载完成事件

    //iframe加载完成后,对其子元素进行操作 var iframe = document.getElementById("re-img"); if (iframe.attachE ...

  9. 关于 <script type='text/template' > 的妙用 / 使用jquery获取iframe加载完成事件

    https://www.cnblogs.com/ddqyc/p/6200539.html <!DOCTYPE html> <html> <head> <met ...

随机推荐

  1. <数据挖掘导论>读书笔记9聚类分析

    1. 聚类分析仅根据在数据中发现的描述对象及其关系的信息,将数据对象分组. 其目标是组内的对象相互之间是相似的或者相关的,而不同组中的对象是不同的或者不相关的. 2.聚类分析的重要技术 K均值:K均值 ...

  2. 利用css实现搜索过滤

    无意中找到一种利用css就可实现的搜索过滤的方法,不得不说看了代码之后确实被惊艳到了,亏我之前面试还因为做这个功能做太慢而拖了后腿.在此记录下代码: <!DOCTYPE html> < ...

  3. Generic-Host 快速使用指南

    .NETCORE 中的 Generic Host 本文以自己在工作中学习和使用.net core generic-host 作一个总结. 前言 在创建的ASPNETCORE项目中,我们可以在Main( ...

  4. webstorm中sass编译时目录或内容包含中文字符报错

    ruby版本:ruby 2.3.1p112 (2016-04-26 revision 54768) [x64-mingw32] sass版本:Sass 3.4.22 (Selective Steve) ...

  5. Idea软件Vim插件问题

    人家说用webstorm是纯前端,用Idea是java+前端,好,那就用Idea,装上试试,全选所有插件安装,奇迹出现了,选中一行代码,backspace,删不了,我的天,好吧,复制粘贴的快捷键也不行 ...

  6. SQL SERVER学习1——数据库概念

    <SQL Server实例教程>(科学出版社) 数据库的基本概念 数据是载荷信息的物理符号,是数据库中存储的基本对象. 信息可以通过手势,眼神表达,但是表达信息的最佳方式还是数据. 数据有 ...

  7. 使用Docker镜像部署ELK日志系统

    使用Docker部署elasticsearch.logstash.kibana 指定版本:6.7.1 (建议使用同一的版本.屏蔽三个软件间的不兼容性) 下载镜像: docker pull elasti ...

  8. MySQL建表语句的一些特殊字段

    这里的字段会不断更新 unsigned 这个字段一般在建表的时候写在Id上,用来表示不分正负号 tinyint 这个字段如果设置为UNSIGNED类型,只能存储从0到255的整数,不能用来储存负数. ...

  9. ckeditor添加自定义按钮整合swfupload实现批量上传图片

    ckeditor添加自定义按钮整合swfupload实现批量上传图片给ckeditor添加自定义按钮,由于ckeditor只能上传一张图片,如果要上传多张图片就要结合ckfinder,而ckfinde ...

  10. C++ STL:stack和queue

    http://blog.csdn.net/wallwind/article/details/6858634 http://blog.csdn.net/chao_xun/article/details/ ...