Iframe也叫内联frame,能够把一个HTML文档嵌入到另外一个文档中。使用iframe的好处是被嵌入的文档能够彻底独立于其父文档,凭借此特色咱们一般可使浏览器模拟多线程,须要注意的是使用iframe并不会增长同域名下的并行下载数,浏览器对同域名的链接老是共享浏览器级别的链接池,即便是跨窗口或跨标签页,这在全部主流浏览器都是如此。也由于这样这让iframe带来的好处大打折扣。javascript
在页面加载过程当中iframe元素会阻塞父文档onload事件的触发,而开发者程序一般会在onload事件触发时初始化UI操做。例如,设置登陆区域的焦点。由于用户习惯等待这一操做,因此尽量的让onload事件触发从而使用户的等待时间变短是很是重要的。另外开发者会把一些重要的行为绑定在unload事件上,而不幸的是在一些浏览器中,只有当onload事件触发后unload事件才能触发,若是onload事件长时间未触发,而用户已经离开当前页面,那么unload事件也将永远得不到触发。
那是否有方案可让onload事件不被iframe阻塞吗?有个简单的解决方案来避免onload事件被阻塞,使用JavaScript动态的加载iframe元素或动态设置iframe的src属性:php
<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。css
空的连接属性是指img、link、script、ifrrame元素的src或href属性被设置了,可是属性却为空。如<img src=””>,咱们建立了一个图片,而且暂时设置图片的地址为空,但愿在将来动态的去修改它。可是即便图片的地址为空,浏览器依旧会以默认的规则去请求空地址:html
深层级嵌套的节点在初始化构建时每每须要更多的内存占用,而且在遍历节点时也会更慢些,这与浏览器构建DOM文档的机制有关。例以下面HTML代码:java
<html> <body> <p> Hello World </p> <div> <img src="example.png"/></div> </body> </html>
经过浏览器HTML解析器的解析,浏览器会把整个HTML文档的结构存储为DOM树结构。当文档节点的嵌套层次越深,构建的DOM树层次也会越深。android
提升下载速度最显而易见的方式就是减小文件的大小,特别是压缩内嵌在HTML文档中的JavaScript和CSS代码,这能使得页面体积大幅精简。除此以外减小HTML文档大小还能够采起下面几种方法:ios
HTML页面开始时指定字符集,有助于浏览器能够当即开始解析HTML代码。HTML文档一般被解析为一序列的带字符集编码信息的字符串经过internet传送。字符集编码在HTTP响应头中,或者HTML标记中指定。浏览器根据得到的字符集,把编码解析为能够显示在屏幕上的字符。若是浏览器不能获知页面的编码字符集,通常都会在执行脚本和渲染页面前,把字节流缓存,而后再搜索可进行解析的字符集,或以默认的字符集来解析页面代码,这会致使消耗没必要要的时间。为了不浏览器把时间花费在搜寻合适的字符集来进行解码,因此最好在文档中老是显式的指定页面字符集。正则表达式
当浏览器加载页面的HTML代码时,有时候须要在图片下载完成前就对页面布局进行定位。若是HTML里的图片没有指定尺寸(宽和高),或者代码描述的尺寸与实际图片的尺寸不符时,浏览器则要在图片下载完成后再“回溯”该图片并从新显示,这会消耗额外时间。因此,最好为页面里的每一张图片都指定尺寸,无论是在页面HTML里的<img>标签,仍是在CSS里。express
<img src="hello.png" width="400" height="300">
当浏览器在解析常规的script标签时,它须要等待script下载完毕,再解析执行,然后续的HTML代码只能等待。为了不阻塞加载,应把脚步放到文档的末尾,如把script标签插入在body结束标签以前:浏览器
<script src="example.js" ></script> </body>
有两种方式加载样式文件,一种是link元素,另外一种是CSS 2.1加入@import。而在外部的CSS文件中使用@import会使得页面在加载时增长额外的延迟。虽然规则容许在样式中调用@import来导入其它的CSS,但浏览器不能并行下载样式,就会致使页面增添了额外的往返耗时。好比,第一个CSS文件first.css包含了如下内容:@import url(“second.css”)。那么浏览器就必须先把first.css下载、解析和执行后,才发现及处理第二个文件second.css。简单的解决方法是使用<link>标记来替代@import,好比下面的写法就可以并行下载CSS文件,从而加快页面加载速度:
<link rel="stylesheet" href=""first.css"" /> <link rel="stylesheet" href="second.css" />
须要注意的是一个页面中的CSS文件不宜过多,不然应该简化及合并外部的CSS文件以节省往返请求时间(RTT)提高页面加载速度。
IE独有属性AlphaImageLoader用于修正7.0如下版本中显示PNG图片的半透明效果。这个滤镜的问题在于浏览器加载图片时它会终止内容的呈现而且冻结浏览器。在每个元素(不只仅是图片)它都会运算一次,增长了内存开支,所以它的问题是多方面的。彻底避免使用AlphaImageLoader的最好方法就是使用PNG8格式来代替,这种格式能在IE中很好地工做。若是你确实须要使用AlphaImageLoader,请使用下划线_filter又使之对IE7以上版本的用户无效。
CSS表达式是动态设置CSS属性的强大(但危险)方法。Internet Explorer从第5个版本开始支持CSS表达式。下面的例子中,使用CSS表达式能够实现隔一个小时切换一次背景颜色:
background-color: expression((new Date()).getHours()%2?"#FFFFFF": "#000000" );
如上所示,expression中使用了JavaScript表达式。CSS属性根据JavaScript表达式的计算结果来设置。expression方法在其它浏览器中不起做用,所以在跨浏览器的设计中单独针对Internet Explorer设置时会比较有用。
表达式的问题就在于它的计算频率要比咱们想象的多。不只仅是在页面显示和缩放时,就是在页面滚动、乃至移动鼠标时都会要从新计算一次。给CSS表达式增长一个计数器能够跟踪表达式的计算频率。在页面中随便移动鼠标均可以轻松达到10000次以上的计算量。一个减小CSS表达式计算次数的方法就是使用一次性的表达式,它在第一次运行时将结果赋给指定的样式属性,并用这个属性来代替CSS表达式。若是样式属性必须在页面周期内动态地改变,使用事件句柄来代替CSS表达式是一个可行办法。若是必须使用CSS表达式,必定要记住它们要计算成千上万次而且可能会对你页面的性能产生影响。
CSS选择器对性能的影响源于浏览器匹配选择器和文档元素时所消耗的时间,因此优化选择器的原则是应尽可能避免须要消耗更多匹配时间的选择器。而在这以前咱们须要了解CSS选择器匹配的机制,如例子的子选择器规则:
#header > a {font-weight:blod;}
咱们中的大多数人都是从左到右的阅读习惯,可能也会习惯性的设定浏览器也是从左到右的方式进行匹配规则,由于会推测这条规则的开销并不高。咱们这样假象浏览器会像这样的方式工做:找到惟一的id为header为的元素,而后把这个样式规则应用到直系子元素中的a元素上。咱们知道文档中只有一个id为header的元素,而且它只有几个a类型的子节点,因此这个CSS选择器应该至关高效。
事实上,却刚好相反,CSS选择器是从右到左进行规则匹配。了解这个机制后,例子中看似高效的选择器在实际中的匹配开销是很高的,浏览器必须遍历页面中全部的a元素而且肯定其父元素的id是否为header。
若是把例子的子选择器改成后代选择器则会开销更多,在遍历页面中全部a元素后还需向其上级遍历直到根节点。
#header a {font-weight:blod;}
理解了CSS选择器从右到左匹配的机制后,能够理解选择器中最右边的规则每每决定了浏览器继续左移匹配的工做量,咱们把最右边选择规则称之为关键选择器。
通配选择器使用 * 符合表示,可匹配文档中的每个元素。以下例规则将全部元素的字体大小设置为20px:
* { font-size:20px;}
通配选择器做用于全部的元素,如规则最右边为通配符:
.selected * {color: red;}
浏览器匹配文档中全部的元素后分别向上逐级匹配class为selected的元素,直到文档的根节点,所以其匹配开销是很是大的,一般比开销最小的ID选择器高出1~3个数量级,因此应避免使用关键选择器是通配选择器的规则。
属性选择器根据元素的属性是否存在或其属性值进行匹配,以下例规则会把herf属性值等于”#index”的连接元素设置为红色:
.selected [href=”#index”] {color: red;}
但其匹配开销是很是大的,浏览器先匹配全部的元素,检查其是否有href属性而且herf属性值等于”#index”, 而后分别向上逐级匹配class为selected的元素,直到文档的根节点。因此应避免使用关键选择器是单规则属性选择器的规则。
CSS3添加了复杂的属性选择器,能够经过类正则表达式的方式对元素的属性值进行匹配。固然这些类型的选择器定是会影响性能的,正则表达式匹配会比基于类别的匹配会慢不少。大部分状况下咱们应尽可能避免使用 *=, |=, ^=, $=, 和 ~=语法的属性选择器。
移除无匹配的样式,有两个好处:
第一,删除无用的样式后能够缩减样式文件的体积,加快资源下载速度;
第二,对于浏览器而言,全部的样式规则的都会被解析后索引发来,即便是当前页面无匹配的规则。移除无匹配的规则,减小索引项,加快浏览器查找速度;
有时候咱们会感受到页面反应迟钝,这是由于DOM树元素中附加了过多的事件句柄而且些事件句病被频繁地触发。这就是为何说使用事件代理是一种好方法了。若是你在一个div中有10个按钮,你只须要在div上附加一次事件句柄就能够了,而不用去为每个按钮增长一个句柄。事件冒泡时你能够捕捉到事件并判断出是哪一个事件发出的。
选择器查询是开销很大的方法。因此,使用选择器的次数应该越少越好,而且尽量缓存选中的结果,便于之后反复使用。好比,下面这样的写法就是糟糕的写法:
jQuery('#top').find('p.classA'); jQuery('#top').find('p.classB');
更好的写法是:
var cached = jQuery('#top'); cached.find('p.classA'); cached.find('p.classB');
对 cookie 与 localstorage 操做的API是同步的,且cookie与localstorage是多个tab页面间共享的,多页面同时操做时会存在同步加锁机制,建议应尽可能少的对cookie或localStorage进行操做。
使用JavaScript访问DOM元素是比较慢的,所以为了提高性能,应该作到:
一般开发者都会使用JavaScript类库,如jQuery、Mootools、YUI、Dojo等,可是开发者每每只是使用JavaScript类库中的部分功能。为了更大的提高性能,应尽可能避免使用这类大而全的类库,而是按需使用微类库来辅助开发。