【分享】iframe,img,script,link空路径对页面性能影响的解决方案

在做google统计时碰到的一个问题,用户点击下载时,iframe隐藏打开一个统计页面统计计数。初始化载入时,iframe得有个默认src值(因为考虑到为空会引发一些副作用 SD9019: 插入空白页面 IFRAME 元素时 Chrome Safari Opera 浏览器中会触发 load 事件),所以,所有的iframe都写了个blank.html页面作为src的默认加载页。结果就是这个blank.html页面访问量超乎寻常的高。。
于是,搜集解决方案,接着就发现了如下几篇好文章:

 

文章一:空路径对页面性能影响的解决方案

前几天在 Google Reader 中看到玉伯博客的分享——空路径对页面性能的影响。确实,在写 CSS 的时候,用 background:url(#) 还是会对页面进行多一次请求的。

空路径对页面性能影响的解决方案

不过,因为写多 CSS,一般需要用空背景来解决 bug 的时候,测试结果用 background:url(about:blank) 才是我们想要的:解 bug,不影响性能。那很简单,解决方案不就不出来?等等,让我们来做个测试吧。

测试地址:http://sofish.de/file/demo/empty_source.html

 懒得截图了,自己自行搞搞吧,浏览结果已经把大致的都写在测试页面上了。最终的解决方案是:

  1. 大胆使用 about:blank 来代替空,或者‘#’,特别是在 background-image 中使用
  2. 在 img / script / iframe 这些推荐使用 javascript:” 来解决问题

其他更好的办法?这个测试结果有问题?随时欢迎提供、指正。谢谢。

 

 

文章二:空路径对页面性能的影响

今天同事小凡反馈,淘宝有个商品详情页,旺铺皮肤的 CSS 文件在 Firefox 下很奇怪的被加载了两次。最近对 detail 的渲染速度进行了优化,因此遇到 bug 第一反应是往优化方面找原因。然而调试了许久才发现,该 bug 居然是一个在淘宝深藏了很久的 bug, 在 IE 下会导致一些糟糕的情况产生。一身冷汗,立刻分析解决之。

这个 bug 并不新鲜。早在 2009 年,Nicholas C. Zakas 就发现了空 src 的危害性:Empty image src can destroy your site.

Nicholas 的发现可以概括为一句话:img, script, link 的 src/href 为空时,有可能会导致冗余请求。

今天这个 bug 的起因,可以补充 Nicholas 的发现:CSS 里,background url 为空时,也有可能会导致冗余请求。

除了空值,还有一个值也会出问题:#值。 比如 <img src=”#”>

具体测试结果请看:test.html

从测试结果中可以看出,#值比空值更糟糕。比如 background: url(#), 直接会触发一个新请求。这次旺铺皮肤的样式文件在 Firefox 下被加载两次,就是因为第三方设计师在 css 里写入了 url(#). css 外链时,考虑静态资源的缓存,重复请求引发的问题并不大。但当 css 内嵌时,在 IE 下会引发一个相对于当前页面的 index 请求,这就比较糟糕了。

解决方案:

等待浏览器自身的改进。Nicholas 在 2009 年就开始推动各浏览器厂商,现在看起来就 IE 修复得还可以,Firefox 依旧会从本地缓存中读取一次(重复读取有可能会导致 js/css 的再次 parse + execute,浪费呀)。对于#值,则目前所有浏览器都未考虑周全。
改变代码习惯。严禁代码中,url/href/src 值为空或 # . 这应该是目前最好的一种方式。
经验教训:对于开放 CSS 的系统,源码检查时,要加入对 background/background-image: url()/url(#) 的检查。
点滴经验,与君共勉。


文章三:【高性能前端1】高性能HTML

避免使用Iframe

Iframe也叫内联frame,可以把一个HTML文档嵌入到另一个文档中。使用iframe的好处是被嵌入的文档可以完全独立于其父文档,凭借此特点我们通常可以使浏览器模拟多线程,需要注意的是使用iframe并不会增加同域名下的并行下载数,浏览器对同域名的连接总是共享浏览器级别的连接池,即使是跨窗口或跨标签页,这在所有主流浏览器都是如此。也因为这样这让iframe带来的好处大打折扣。

在页面加载过程中iframe元素会阻塞父文档onload事件的触发,而开发者程序通常会在onload事件触发时初始化UI操作。例如,设置登录区域的焦点。因为用户习惯等待这一操作,所以尽可能的让onload事件触发从而使用户的等待时间变短是非常重要的。另外开发者会把一些重要的行为绑定在unload事件上,而不幸的是在一些浏览器中,只有当onload事件触发后unload事件才能触发,如果onload事件长时间未触发,而用户已经离开当前页面,那么unload事件也将永远得不到触发。
那是否有方案可以让onload事件不被iframe阻塞吗?有个简单的解决方案来避免onload事件被阻塞,使用JavaScript动态的加载iframe元素或动态设置iframe的src属性:

 <iframe id=iframe1 ></iframe>
 document.getElementById(‘iframe1’).setAttribute(‘src’, ‘url’);

但其仅在高级浏览器 中有效,对于Internet Explorer 8及以下的浏览器无效。除此之外我们必须知道iframe是文档内最消耗资源的元素之一,在Steve Souders 的测试中 ,在测试页面中分别加载100个A、DIV、SCRIPT、STYLE和 IFRAME元素,并且分别在Chrome、Firefox、Internet Explorer、Opera、Safari中运行了10次。结果显示创建iframe元素的开销比创建其他类型的DOM元素要高1~2个数量级。在测试中所有的DOM元素都是空的,如加载大的脚本或样式块可能比加载某些iframe元素耗时更长,但从基准测试结果来看,即使是空的iframe,其开销也是非常昂贵的,鉴于iframe的高开销,我们应尽量避免使用。尤其是对于移动设备,对于目前大部分还是只有有限的CPU与内存的情况下,更应避免使用iframe。

避免空链接属性

空的链接属性是指img、link、script、ifrrame元素的src或href属性被设置了,但是属性却为空。如<img src=””>,我们创建了一个图片,并且暂时设置图片的地址为空,希望在未来动态的去修改它。但是即使图片的地址为空,浏览器依旧会以默认的规则去请求空地址:

  1. Internet Explorer 8及以下版本浏览器只在img类型元素上出现问题,IE会把img的空地址解析为当前页面地址的目录地址。例如:如果当前页面地址为http://example.com/dir/page.html,IE会把空地址解析为http://example.com/dir/地址并请求。
  2. 早些版本的Webkit内核浏览器 与Firefox 会把空地址解析为当前页面的地址。如果页面内有多个空链接属性元素,当前页面的服务器则会被请求多次,增加服务器的负载。相较桌面浏览器对内核的更新升级较积极,这个问题在ios与android系统的移动浏览器上问题可能较严重。
  3. 幸运的是所有主流浏览器面对iframe的src属性为空时,会把空地址解析为about:blank地址,而不会向服务器发出额外的请求。

避免节点深层级嵌套

深层级嵌套的节点在初始化构建时往往需要更多的内存占用,并且在遍历节点时也会更慢些,这与浏览器构建DOM文档的机制有关。例如下面HTML代码:

 <html>
 <body>
 <p>
 Hello World
 </p>
 <div> <img src="example.png"/></div>
 </body>
 </html>

通过浏览器HTML解析器的解析,浏览器会把整个HTML文档的结构存储为DOM树结构。当文档节点的嵌套层次越深,构建的DOM树层次也会越深。

缩减HTML文档大小

提高下载速度最显而易见的方式就是减少文件的大小,特别是压缩内嵌在HTML文档中的JavaScript和CSS代码,这能使得页面体积大幅精简。除此之外减少HTML文档大小还可以采取下面几种方法:

  1. 删掉HTM文档对执行结果无影响的空格空行和注释
  2. 避免Table布局
  3. 使用HTML5

显式指定文档字符集

HTML页面开始时指定字符集,有助于浏览器可以立即开始解析HTML代码。HTML文档通常被解析为一序列的带字符集编码信息的字符串通过internet传送。字符集编码在HTTP响应头中,或者HTML标记中指定。浏览器根据获得的字符集,把编码解析为可以显示在屏幕上的字符。如果浏览器不能获知页面的编码字符集,一般都会在执行脚本和渲染页面前,把字节流缓存,然后再搜索可进行解析的字符集,或以默认的字符集来解析页面代码,这会导致消耗不必要的时间。为了避免浏览器把时间花费在搜寻合适的字符集来进行解码,所以最好在文档中总是显式的指定页面字符集。

显式设置图片的宽高

当浏览器加载页面的HTML代码时,有时候需要在图片下载完成前就对页面布局进行定位。如果HTML里的图片没有指定尺寸(宽和高),或者代码描述的尺寸与实际图片的尺寸不符时,浏览器则要在图片下载完成后再“回溯”该图片并重新显示,这会消耗额外时间。所以,最好为页面里的每一张图片都指定尺寸,不管是在页面HTML里的<img>标签,还是在CSS里。

<img src="hello.png" width="400" height="300">

避免脚本阻塞加载

当浏览器在解析常规的script标签时,它需要等待script下载完毕,再解析执行,而后续的HTML代码只能等待。为了避免阻塞加载,应把脚步放到文档的末尾,如把script标签插入在body结束标签之前:

 <script src="example.js" ></script>
 </body>


阅读本文后,您的心情是:
 
恶心
愤怒
强赞
感动
路过
无聊
雷囧
关注
知识共享许可协议
评论(0) 浏览(42130) 引用(0)
引用地址:http://blog.baiwand.com/tb.php?sc=30e125&id=216
Tags:
« 【分享】linux下vi命令大全 【经验】固定高度容器内的image垂直水平居中另一解法 »

Blogger

  • blogger
  • 天之骄子
  • 职位:研发工程师
    铭言:
    阳光与欢乐同在,
    与我同在
    主页:
    blog.baiwand.com

分类目录

日志归档

主题标签

数据统计

  • 日志:151篇
  • 评论:45条
  • 碎语:264条
  • 引用:0条

链接表

随机日志 »

最新日志 »

最新评论 »

标签云 »

订阅Rss
sitemap