推荐!Iframe 的4种加载技术和性能优化!
yuyutoo 2024-10-24 17:47 2 浏览 0 评论
大家好,很高兴又见面了,我是"高级前端?进阶?",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!
前言
我们会经常使用iframes来加载第三方的内容、广告或者插件。使用iframe是因为可以和主页面并行加载,不会阻塞主页面。当然使用iframe也有利弊:Steve Souders在blog里面有阐述:
- iframe会阻塞主页面的onload事件
- 主页面和iframe共享同一个连接池
阻塞主页面的onload是这两个问题中最影响性能的方面。一般都是想让onload时间越早触发越好,一方面是用户体验,不过更重要的是google给网站的加载速度的打分:用户可以用IE和FF中Google工具栏来计时。
那么为了提高页面性能,怎样才能不阻塞主页面的onload事件来加载iframe呢?
这篇文章讲了四种加载iframe的方法:普通iframe,onload之后加载iframe,setTimeout() iframe和异步加载iframe。每种方法的加载结果我都用IE8的时间线来展示。我建议多注意下动态异步加载这个方法,因为这是性能表现最佳的。另外,还有一种友好iframe(friendly iframe)技术。可能算不上是iframe加载的技术,但是必须使用iframe,而且是无阻塞加载的。
1.普通方法加载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的内容只需要很短的时间来加载和执行,那么也不是个大问题,而且使用这种方法还有个好处是可以和主页面并行加载。但是如果加载这个iframe需要很长时间,用户体验就很差了。
2.在onload之后加载iframe
如果想在iframe中加载一些内容,但是这些内容对于页面来说不是那么的重要。或者这些内容不需要马上展现给用户的,需要点击触发之类的。那么可以考虑在主页面载入之后加载iframe。
<script>
//doesn't block the load event
function createIframe(){
var i = document.createElement("iframe");
i.src = "path/to/file";
i.scrolling = "auto";
i.frameborder = "0";
i.width = "200px";
i.height = "100px";
document.getElementById("div-that-holds-the-iframe").appendChild(i);
};
// Check for browser support of event handling capability
if (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加载的时候,浏览器会标识正在加载
这种方法比普通方法有什么好处呢?load事件会马上触发,有两个好处:
- 其他等待主页面onload事件的代码可以尽早执行
- Google Toolbar计算你页面加载的时间会大大减少
但是,当iframe加载的时候,还是会看到浏览器的忙碌状态,相对于普通加载方法,用户看到忙碌状态的时间更长。还有就是用户还没等到页面完全加载完的时候就已经离开了。有些情况下这是个问题,比如广告。
3.setTimeout()来加载iframe
这种方法的目的是不阻塞onload事件。
Steve Souder说到:“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>
在除了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加载的时候,浏览器终于不显示忙碌状态了(非常好)
测试页给出下面的时间线:
转义字符让代码看着有些难受,这都不是问题。试试吧。
4.友好型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%。
没有创建相关的测试页,所以也没有第一手的资料。从我调研的结果来说:
如果只想在网页上调用一个确定的src地址的iframe的话这个方法不是很有用。
如果你想在网页上展示多个广告,比较灵活的方法的是:加载一个广告,然后更新iframe加载另一个主页面的DOMContentLoaded时间不会被阻塞,页面渲染也不会被阻塞,当然,主页面的onload事件还是会被阻塞。
注意:友好型iframe的实现可以参考文末的Vue实现版本,即vue-friendly-iframe
5.本文总结
本文主要和大家介绍下Iframe的四种加载方案 ,上次使用cheerjp加载webassembly的时候遇到iframe阻塞主页面onload、浏览器一直显示数据加载中等诸多问题,遇到了这篇文章,所以翻译出来分享给大家。当然,很多探索也没有很深入,但是文末的参考资料提供了大量优秀文档以供学习,如果有兴趣可以自行阅读。
参考资料
https://www.aaronpeters.nl/blog/iframe-loading-techniques-and-performance/
https://github.com/officert/vue-friendly-iframe
https://www.toutiao.com/article/7198047359320801832
英文原文:https://www.aaronpeters.nl/blog/iframe-loading-techniques-and-performance/
英文作者:Aaron Peters
相关推荐
- jQuery VS AngularJS 你更钟爱哪个?
-
在这一次的Web开发教程中,我会尽力解答有关于jQuery和AngularJS的两个非常常见的问题,即jQuery和AngularJS之间的区别是什么?也就是说jQueryVSAngularJS?...
- Jquery实时校验,指定长度的「负小数」,小数位未满末尾补0
-
在可以输入【负小数】的输入框获取到焦点时,移除千位分隔符,在输入数据时,实时校验输入内容是否正确,失去焦点后,添加千位分隔符格式化数字。同时小数位未满时末尾补0。HTML代码...
- 如何在pbootCMS前台调用自定义表单?pbootCMS自定义调用代码示例
-
要在pbootCMS前台调用自定义表单,您需要在后台创建表单并为其添加字段,然后在前台模板文件中添加相关代码,如提交按钮和表单验证代码。您还可以自定义表单数据的存储位置、添加文件上传字段、日期选择器、...
- 编程技巧:Jquery实时验证,指定长度的「负小数」
-
为了保障【负小数】的正确性,做成了通过Jquery,在用户端,实时验证指定长度的【负小数】的方法。HTML代码<inputtype="text"class="forc...
- 一篇文章带你用jquery mobile设计颜色拾取器
-
【一、项目背景】现实生活中,我们经常会遇到配色的问题,这个时候去百度一下RGB表。而RGB表只提供相对于的颜色的RGB值而没有可以验证的模块。我们可以通过jquerymobile去设计颜色的拾取器...
- 编程技巧:Jquery实时验证,指定长度的「正小数」
-
为了保障【正小数】的正确性,做成了通过Jquery,在用户端,实时验证指定长度的【正小数】的方法。HTML做成方法<inputtype="text"class="fo...
- jquery.validate检查数组全部验证
-
问题:html中有多个name[],每个参数都要进行验证是否为空,这个时候直接用required:true话,不能全部验证,只要这个数组中有一个有值就可以通过的。解决方法使用addmethod...
- Vue进阶(幺叁肆):npm查看包版本信息
-
第一种方式npmviewjqueryversions这种方式可以查看npm服务器上所有的...
- layui中使用lay-verify进行条件校验
-
一、layui的校验很简单,主要有以下步骤:1.在form表单内加上class="layui-form"2.在提交按钮上加上lay-submit3.在想要校验的标签,加上lay-...
- jQuery是什么?如何使用? jquery是什么功能组件
-
jQuery于2006年1月由JohnResig在BarCampNYC首次发布。它目前由TimmyWilson领导,并由一组开发人员维护。jQuery是一个JavaScript库,它简化了客户...
- django框架的表单form的理解和用法-9
-
表单呈现...
- jquery对上传文件的检测判断 jquery实现文件上传
-
总体思路:在前端使用jquery对上传文件做部分初步的判断,验证通过的文件利用ajaxFileUpload上传到服务器端,并将文件的存储路径保存到数据库。<asp:FileUploadI...
- Nodejs之MEAN栈开发(四)-- form验证及图片上传
-
这一节增加推荐图书的提交和删除功能,来学习node的form提交以及node的图片上传功能。开始之前需要源码同学可以先在git上fork:https://github.com/stoneniqiu/R...
- 大数据开发基础之JAVA jquery 大数据java实战
-
上一篇我们讲解了JAVAscript的基础知识、特点及基本语法以及组成及基本用途,本期就给大家带来了JAVAweb的第二个知识点jquery,大数据开发基础之JAVAjquery,这是本篇文章的主要...
- 推荐四个开源的jQuery可视化表单设计器
-
jquery开源在线表单拖拉设计器formBuilder(推荐)jQueryformBuilder是一个开源的WEB在线html表单设计器,开发人员可以通过拖拉实现一个可视化的表单。支持表单常用控件...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- mybatis plus (70)
- scheduledtask (71)
- css滚动条 (60)
- java学生成绩管理系统 (59)
- 结构体数组 (69)
- databasemetadata (64)
- javastatic (68)
- jsp实用教程 (53)
- fontawesome (57)
- widget开发 (57)
- vb net教程 (62)
- hibernate 教程 (63)
- case语句 (57)
- svn连接 (74)
- directoryindex (69)
- session timeout (58)
- textbox换行 (67)
- extension_dir (64)
- linearlayout (58)
- vba高级教程 (75)
- iframe用法 (58)
- sqlparameter (59)
- trim函数 (59)
- flex布局 (63)
- contextloaderlistener (56)