通过分析iframe和无阻塞脚本关系能让我们更懂iframe

  在我上篇文章里,我提到一种使用iframe完成无阻塞脚本加载的方式,因为我对iframe的偏见很大,所以上篇文章里我没有展开讨论这个问题。

  文章发表后有位网友问了我这样一个问题,下面是他问题的原文,首先看他发给我的截图,如下所示:

我一个电商后台系统,用的表格控件是flexigrid,,里面是个iframe来的,每一个tab就是一个iframe,现在遇到的问题就是,如果其中一个或者多个iframe在加载数据,还没加载完,如果这个时候,我再去开一个tab,也是查找数据,可能数据量很大,或者提交数据(其他的iframe可能还在加载数据),这个时候很容易出现浏览器卡死,一直转圈的现象,这个跟你说的这个js阻塞也有关系吧。跟这个js单线程的特性,线程阻塞有多大的关系~~

  

  这个现象很有趣,就和我在上篇文章里谈到我思考无阻塞脚本加载的源起一样,研究这个朋友提供的现象应该也能给我们很大的收获。

  首先,这位朋友提到“如果其中一个或者多个iframe在加载数据,还没加载完,如果这个时候,我再去开一个tab,也是查找数据,可能数据量很大,或者提交数据(其他的iframe可能还在加载数据),这个时候很容易出现浏览器卡死,一直转圈的现象”,这个现象让我有个疑问:

  首先我们要明确页面使用iframe时候等于一个页面里嵌套一个页面,iframe的src指向的页面其实和父页面是相对独立的,那么一个带了iframe的页面,父页面的加载过程和iframe加载的过程是怎样的关系了,具体点就是父页面是不是要等待iframe页面里所有资源加载完毕后才会触发onload事件,页面的onload事件触发了,也就代表页面的忙指示结束,而忙指示是我们衡量页面是否被阻塞的一个重要标志。

  幸运的是有人已经帮我们做了这个实验,下面我来描述下这个实验的方式:

  阻塞加载方式即在页面直接写:

<iframe src=”url”></iframe>

  

  Iframe的url指向的页面分为四种类型:

  1.url指向一个空文档,空文档不是指页面指向的网页不存在,而是指向网页里只有最基本的html,例如:

<html><head></head><body><p>ddddd</p></body></html>

  

     这时候iframe加载就不会因为内部静态资源而被阻塞。

  2.url指向的页面里包含图片;

  3.url指向的页面包含外部脚本;

  4.url指向的页面包含外部css样式文件。

  上面的静态资源,实验设计者都让它们的加载有延时,实验的结果是令人失望的,这些静态资源加载都会阻塞父页面的加载,即iframe的加载延长了忙指示结束的时间。

  接下来实验者又做了一个实验,这个时候在父页面里iframe的src设为空,然后使用javascript代码给iframe设定src的值,赋值的时机也是在onload事件之前,而url指向和上个实验一致,结果是在以webkit为内核的safari和chrome下,页面加载明显变快,iframe的加载没有阻塞父页面的加载,但是在其他浏览器下这个结果是令人失望的,阻塞任然存在,甚至比以前还要严重。

  Iframe的加载是能阻塞父页面的加载,上面朋友的现象描述里:一个iframe没有加载完毕,用户可能就会选择另外一个iframe,另一个iframe也在加载新页面,这个描述说明了,这个朋友的iframe的src应该都是使用javascript设置,而不是事先填好的,他的场景符合实验二的情况。这里又会产生一个问题,第一个iframe可能是和主页面资源加载同步的,即主页面很有可能还没触发onload事件,为啥用户还能触发iframe的加载操作,按我原来的逻辑,这时候页面应该是不能接收任何响应的,这里我要纠正下这个观点,页面被阻塞不代表页面会停止接收用户的所做的相关操作,例如在ie浏览器,如果页面被阻塞,用户点击了两次按钮,浏览器会认为用户的操作是有效的,会将用户的操作加入到浏览器执行的UI线程里的,这是浏览器对于性能不佳网页的一个妥协做法。

  Iframe阻塞页面加载的问题还有更多深层次的原因,首先iframe页面dom元素中加载最慢的,大家可以看看下面这张图:

  我们使用dom在页面里创建iframe、a、div、srcipt和style节点,第一栏是创建10个节点,第二栏是创建100个节点,第三栏是创建1000个节点,数值是代表创建的时间,由此可见创建iframe越多,耗时越长,可见iframe本身就是页面性能的瓶颈所在。

  在前面文章里我讲到网站为了提升页面资源并行下载的,可以将通用的静态资源放到一个独立的域名下,跨域可以增加页面连接数,使用iframe的页面会有两个url,iframe能达到增加并行下载的目的吗?如果iframe的url和父页面的url不同,能不能增加我没有做过测试,无法回答,但是针对这个朋友的问题,他使用的iframe的url肯定会和父页面在同一个域下面,因为他使用的iframe目的是为了布局而不是为了嵌入其他web的页面,iframe和父页面同域的结果就是并发连接数是不能被增加的,因为iframe是指向一个完整的页面,在加上上面说的iframe其实也会阻塞页面的加载,因此这个场景下就等于浏览器同时加载两个独立页面却要遵守一个页面加载的方案,结果自然是页面会变得更慢。

  由于这个朋友的应用是内部的控制台,因此它的网站绝对不会有做那些提升网站性能的优化工作,网站优化里有一条就是:将外部的css文件和js文件缓存,所以这个朋友网站肯定会出现这个问题,第一个iframe还没加载完,用户打开了第二个iframe,这两个iframe使用的外部css文件和js文件可能大部分相同,但是它们在每个iframe里都会被重新加载,而且第一个iframe没有加载完毕,还会阻塞第二个iframe对静态资源的加载,如果开启的iframe越多,阻塞就越加严重,后果自然也是网站越来越慢。

  那么我们该怎么帮这个朋友解决他的问题了?最好的方式就是将iframe去掉,使用div来实现选项卡,这么做太残酷,要重构整个前端代码,这个朋友问我的目的就是不想这么干了。

  所以要考虑下代价较少的方法,下面是我晚上想到的,希望看了我博客的大牛们也会有更多更好的建议,我想到的如下:

  1. 这个网站的性能问题源自于iframe使用过多,那么我们应该减少iframe,所以这个朋友可以将页面主页面的布局改为传统布局,即菜单放到页面左边,页面上去掉选项卡,工作区只有一个iframe,这样就只需要修改主页面就行了。不过这样会减少一个用户友好的功能,这个朋友使用选项卡好处就是iframe能有记忆功能,但是左边菜单一个iframe后没点一次菜单就得重新打开页面,不过失去这个功能和性能损失比起来我相信还是性能更加重要。
  2. 将页面的静态资源添加缓存功能,缓存外部的js文件、css文件还有图片,我不知道这个朋友服务端使用什么语言开发,如果是java的话,生产的web容器应该是tomcat,jboss之流了,这些java的web容器怎么设置静态资源缓存我还真的不清楚,最好还是将静态资源放到apache,ngnix这样的web服务器下,如果使用静态资源服务器最好提供一个和主服务器的域名不一样的访问地址,这样还可以提升浏览器并发下载的连接数。

  文章写毕,最后再重申一下希望有大牛看了本人的文章,能告诉我们更多更好的方式。

时间: 2024-09-30 05:32:05

通过分析iframe和无阻塞脚本关系能让我们更懂iframe的相关文章

减少JS对页面加载性能影响的方法以及无阻塞脚本(javascript)模式

JS的阻塞特性:当<script>出现的时候,页面必须等待脚本文件的加载.解析.执行完毕后才能继续进行页面的渲染.不管脚本文件是以内联形式还是外部引入的形式出现在<script>中,页面的加载和渲染都必须停下来等待脚本文件的执行完成.因为在脚本文件中可能会修改页面的内容.这就会出现一个问题,当HTML文件中引入很多的外部脚本文件和内联脚本时,可能会导致页面的严重阻塞,影响页面的加载和渲染,用户体验特别的差.因而需要寻找适当的方法来减小脚本文件对页面加载带来的影响. 改善性能的几种方

javascript性能优化:创建javascript无阻塞脚本

javaScript 在浏览器中的运行性能,在web2.0时代显得尤为重要,成千上万行javaScript代码无疑会成为性能杀手, 在较低版本的浏览器执行JavaScript代码的时候,由于浏览器只使用单一进程来处理ui界面刷新和JavaScript脚本执行, 这意味着在加载javascript文件的时候不能同时做任何其他的事情.   在加载的同时造成了用户交互阻塞: 理论上来说,把样式与行为有关的脚本放在一起率先加载,这样有利于确保正确的用户体验,例如下面的代码: <!DOCTYPE html

探真无阻塞加载javascript脚本技术,我们会发现很多意想不到的秘密

原文:探真无阻塞加载javascript脚本技术,我们会发现很多意想不到的秘密 下面的图片是我使用firefox和chrome浏览百度首页时候记录的http请求 下面是firefox: 下面是chrome: 在浏览百度首页前我都将浏览器的缓存全部清理掉,让这个场景最接近第一次访问百度首页的情景. 在firefox的请求瀑布图里有个表现非常之明显:就是javascript文件下载完毕后,有一段时间是没有网络请求被处理的,这段时间过后http请求才会接着执行,这段空闲时间就是所谓的http请求被阻塞

无阻塞加载脚本

一个页面,从被请求访问,到用户可以看到页面.操作页面,到最后页面完全加载完毕,中间需要经历一个相当奇幻的过程,这个过程的速度被"web性能师"孜孜不倦.前赴后继的优化.本文讨论的是其中一个优化. 浏览器线程和阻塞 虽然大家耳熟能详的一句话是: JavaScript是单线程的. 但是: 浏览器当然不是单线程的. 浏览器的多线程中,有的线程负责加载资源,有的线程负责执行脚本,有的线程负责渲染界面,有的线程负责轮询.监听用户事件. 这些线程,根据浏览器自身特点以及web标准等等,有的会被浏览

脚本无阻塞加载

(图片来源:http://www.cnblogs.com/sharpxiajun/p/4072396.html) 这是清除浏览器缓存后,第一次访问百度首页的场景,在Firefox的瀑布图中可以看到:javascript文件下载完毕后,有一段时间没有请求处理.这段时间过后,请求才会接着执行,这段时间就是HTTP请求阻塞. 当浏览器遇到<script>标签时,浏览器会停止处理页面,先执行Javascript代码,然后再继续解析和渲染页面.在这个过程中,页面和用户的交互完全被阻塞了.通常表现为显示空

性能优化之无阻塞加载脚步方法比较

秋招结束了~~,好像偷懒了很久,没更博了.总结一下自己近来看书的内容. 说明一下,内容大部分来自<高性能网站建设进阶指南>. 乱入内容 Web应用和传统桌面应用有一个共同的目标:尽可能快地响应用户输入. 怎样才算是快?Jakob Nielsen是Web可用性领域知名且备受推崇的专家,引用他的观点来说就是:如果JavaScript代码执行时间超过了0.1秒,页面将会给人不够平滑快捷的感觉,如果执行时间超过了1秒,则会感到应用程序缓慢,超过了10秒,那么用户将会非常沮丧. 性能分析器:Firebu

编写无Java脚本的JSP页面

在上一章中总结了Web开发中应用MVC架构模式,将Servlet 用做控制器,JSP作为视图,JavaBean作为模型,实现业务流程控制,页面逻辑和业务逻辑的分离.然而,使用前面的技术实现MVC,并不是最完美的. 在当代的一个最佳的JavaWeb开发实践就是在MVC架构模式中,中和使用JavaBean,EL(expression language),JSP自定义标记库以及JSP标准标记库JSTL,编写无java脚本的JSP页面. 一 JSP表达式语言EL 在使用基于MVC架构模式的Web应用开发

SQL Server 监控统计阻塞脚本信息

原文:SQL Server 监控统计阻塞脚本信息 数据库产生阻塞(Blocking)的本质原因 :SQL语句连续持有锁的时间过长 ,数目过多, 粒度过大.阻塞是事务隔离带来的副作用,它是不可避免的,而且是一个数据库系统常见的现象. 但是阻塞的时间和出现频率要控制在一定的范围内,阻塞持续的时间过长或阻塞出现过多(过于频繁),就会对数据库性能产生严重的影响. 很多时候,DBA需要知道数据库在出现性能问题时,有没有发生阻塞? 什么时候开始的?发生在那个数据库上? 阻塞发生在那些SQL语句之间? 阻塞的

Web Worker无阻塞UI的牛逼技术,html5,可惜无法敢于UI

众所周知,JavaScript是单线程的,JS和UI更新共享同一个进程的部分原因是它们之间互访频繁,但由于共享同一个进程也就会造成js代码在运行的时候用户点击界面元素而没有任何响应这样的情况,这么糟糕的用户体验HTML5怎么会不修订了,这样Web Worker诞生了. Web Worker进程加载的js运行的时候不仅不会影响浏览器UI,而且也不会影响其它Web Worker进程加载的JS代码.由于Web Worker进程加载的js运行的时候不会影响浏览器UI,也就说明Web Worker中加载的