speeding up your web site 前端性能优化规则(二)

 

接上一篇:speeding up your web site 前端性能优化规则(一)

---------------------------------------------------------------------------

 

优化加载顺序

我们上面的提到的不管是预加载或延迟加载,其实也是加载顺序的一部分。这们这里再次说到的就是页面onload之前的加载顺序。

其实这里一个主要原因是几乎所有的浏览器在处理js时的策略:因为js文件可能会改变页面内容和页面的布局,因此浏览器在碰到script标签时会推迟其后内容的呈现,直到这段js下载、解析和执行完成。

因此,我们尽可能的应该把js引用放到页面底部和内联script也放到底部去执行。

其实,有时我们会使用document.write来输出<script…>标签的引用外部js,首先这样做确实让外部js下载解析,不会再阻断后边的内容的解析,但是我们要知道document.write本身就是段js代码,它的执行同样会产生上面提到的问题。

另外,例如我们可以加defer和ansyc,让页面js下载、解析、执行不会阻断页面内容的解析,但是这和上面document.write一样,这些方式布局的js解析、执行的顺序是不会再是页面安排的顺序,如果js文件存在相互依赖时,将会出现问题。

因此,尽管我们可能许多其它的方法避免问题的发生,但把js引用和内联的js代码尽可能放到底部,明显是最优先推荐的。

js和css尽量放到单独文件进行引用而不是内联

这已经被广大开发者采用的方式了。内联可能减少http请求数啊,难道不是我们提倡的实践吗?没错,放到外部的优点,足你让你放弃这种想法。最重要的一点,外部引用的js和css文件可被浏览器缓存,也就是我们页面一次下载,之后所有页面请求到这些js和css文件都不会再去下载,节省的不仅仅是请求数了;再次,易于维护,同样的js只须修改一次,另外便于我们对js进行压缩和混淆;此外对于外联的js,我们可以省略内联js的<!--- <![CDATA[ ………………. ]]> -->,有更好的兼容性。

减少js/css文件的大小

用术语来说就是压缩,但这里讨论不是gzip这样的压缩, gzip是服务器的一种压缩算法,浏览器接收之后进行解压缩之后再去解析,这样减少传输数据大小,同时也引起压缩/解压缩的损耗的副作用。我们这里讨论的压缩,是去除文件里对于浏览器解析执行无用的:空格、换行、缩进注释等,这可能加大解决现网bug的难度,但是这些小不适,相对于更大的好处这比,根本不算什么。这样的压缩不仅减少传输数据大小,文件的减小甚至可以加快页面的解析速度,对页面加载速度有很大的帮助。当然压缩如果要手动去做也太惨无人道了,YUI Compressor 可以帮助我们很好完成压缩工作。

减少DOM操作次数

js操作DOM是一个相对来说比较慢的操作,因此我们应该注意:缓存要操作的DOM元素,而不是每次都getElementById;尽量在追加到页面DOM结构之前进行所有的处理,而不是追加到页面之后再处理;避免修改布局;追加包含多个结点的文档片段,而不是多次追加结点。

开发更灵活的事件处理

如果页面有太多的事件绑定到不同的元素,而这些事件又经常执行,页面有时会出现无响应的情况。这时使用“事件代理”是一个好的方法。例如你在一个DIV里有10个按钮,每个按钮都有事件绑定,而这时给DIV绑定事件处理程序,而不是10个按钮,通过事件冒泡机制,你依然捕获到事件并且区分出事件的来源。

有些时候,例如我们对事件树进行一些操作,没必要等到onload事件触发,这些操作只要DOM树构建完毕,而没必要等到所有的图片都下载完毕。这时DOMContentLoaded事件就是一个比onload更好的选择,但是这不是所有浏览器都支持。YUI的 onAvailable,jQuery的$(document).ready是我们可以采用的。

样式尽量放在head里,无论内联和引用的样式

我们都知道样式是控制是页面呈现的,而页面的解析呈现是从上到下执行的,解析一个样式,可能会影响之前解析过的内容。因此页面在遇到样式时会阻止页面解析直到样式下载完成并且完成对之前内容改变的显示,内联的样式也会造成对之前呈现的内容进行回查和改变显示,而对于一些浏览器包括IE,这种情况下会显示一个空白的页面,这对页面加载和用户体验都是不应该的。

使用有效的CSS选择符

我们都知道页面呈现时,元素显示不同的样式,会根据样式表、继承样式和默认样式等。对于浏览器,它为会元素查找匹配的样式然后应用。这个查找对于样式选择符是从右到左的顺序,直到找到合适或丢弃这个规则。因此,较少的规则和选择符是好的:移除无用的样式就是一个很好的优化实践,除此之外,对于有很多元素或样式规则的页面来说,优化样式规则也是一个很的实践,关键之处就是定义规则时尽量选择有效的选择符。

1,避免*和其它选择符组合使用,如#dd *{…}之类,允许继承或给不同的元素应用class。

2,规则尽量明确,优先使用ID、class。

3,移除多余的限定,例如ID选择器又被标签名限定div#myDiv、class被标签名限定(相同class区分不同标签除外)

4,避免使用后代/子/相邻选择符,我们知道浏览器会从右到左去应用样式,这类选择器会造成需要大量的元素去评估,因此避免使用,必要时使用class去替代这类选择符。特别那些多余的限定符,如body ul li a{…}这样的,body完全多余。

5,不要对链接之外的元素应用:hover。首先在IE7/IE8的严格模式里,会忽略链接这外的:hover应用;其次在IE7/IE8里会造成性能问题。

不要使用Css表达式

css表达式可以说是很强大的,能动态的设置CSS的值,它其实在样式值时接受一个js的表达式来实现的。表达式是被其它浏览器忽略的除了IE,IE5开始加入表达式,但是在IE8里已经不推荐使用了。除此之外,还有一个很大的性能问题,那就是这个表达式不仅会在页面加载时计算,还会在页面大小变化、滚动、甚至用户鼠标事件发生时,都会重新计算。必要时可使用js取代。

避免使用滤镜

可能我们最多就是使用滤镜在IE6里,为了支持背景图片的透明,但是仍要指出存在的一些问题:这样就不能使用背景拼接,增加组件请求数,另外它会在该图片下载过程中,阻止页面呈现并冻结浏览器,并且会增加内存消耗。但是我们不得不使用时,请使用css hack _filter让只在IE6中有效,而对其它浏览器应用更好的方案。

避免@import

在外部css文件时使用@import可以引用其它的外部Css,但是请不要这样做:因为并不会减少http请求,并且只有在解析了css之后,才会发现这个样式,在IE中这相当于用在页面底部引用样式文件,因此避免使用@import。

图片优化

一个页面从大小来说占大头的肯定是图片,一张图片少则几KB甚至上百,甚至几M也有可能,图片的优化大可以说是非常重要的。此外,我们从类似fireworks等软件保存的图片会包含对于做图软件有用的而对于显示无用的多余的注释、并且使用过多的色彩值、包含无用的空白的图片等又提供了优化的空间。不过让这些简单的是,可以通过google推荐的 GIMP 或yui 推荐的imagemagick 来进行这些优化。以下提供图片的优化的建议:

1,如果图片使用256色、可以试着调低以优化图片。

2,优先选择png格式,试着转化gif到png格式,选择较小的。

3,如果图片较小(小于10px*10px )或色彩较少(调色板色彩小于3种)或图片包含动画时采用gif。

4,相册的图片选 用jpg.

5,任何时候不要使用bmp或tiff。

6,图片压缩:png图片用pngcrushOptiPNGPNGOUT工具,jpg要以用jpegtran进行一定的压缩。

7,保证favicon.ico存在,并且足够小并且可缓存。

8,避免src为空的图片的存在,因为这导致某些浏览器发起一个对当前页面的请求。

另外,我们还应该注意

1:图片合并的优化:图标水平排列比垂直排列的图片体积会小点、安排色彩值相似的合并、不要在图片之间留空隙。

2:关于图片缩放:当然对于需要一个小尺寸的图片,不能提供一个大图,然后通过设置width来实现;对于如果一个图片在一个页面内使用两次,只下载一个较大的,然后通过缩放来适应较小的需求也是合适的。

3,显示指定图片的尺寸:通过width和height显示指定图片的尺寸,就可以消除图片呈现时的计算并且保证图片下载失败时,页面不会变形,要注意不能用于图片缩放,并且只能加到图片自身或父元素上。

总是指定文档类型和字符集并且保证是正确的

服务器输出的数据都是包含编码信息的比特流传递的,因此我们应该通过response header中或html文档中的http-equiv指定文档类型和字符集。如果浏览器没有得到这样的信息,它们在执行js或呈现页面前缓冲得到的信息,直到它们搜索到字符集信息或采取默认值,因此请显示指定字符集。如果之后有输出的数据不符合当前使用字符集,它们不得不重新解析和绘制页面,如果引用文件出现不匹配就会再次请求该文件,因此确保指定正确的字符集。

启用gzip压缩

不用太多解释了,注意一点:不要对图片或其它二进制形式的文件启用gzip压缩,这通常不会有作用并且有可能导致文件变大,并白白浪费cpu。

减少请求的数据

一般情况下,我们尽量减少无用的get或post数据,并且尽量精简格式。此外,最具操作空间就是cookie了,不要在cookie中存储太多的数据,并且移除无用多余的字段、设置合理的过期时间。

另外,限制cookie使用的域,确保图片、css等页面组件使用无cookie的域。

ajax请求使用get方式

在使用XMLHttpRequest采用post请求时,实际上会分两次执行:第一次发送headers,第二次发送post的数据。因此尽量使用get方式,因为它只发送一个tcp包(有大量的cookie除外),另外IE中url长度限制2KB。另外 有意思的是,如果采用post方式,不发送任何数据时和get方式表现是一样的。

尽早输出缓冲

当我们请求一个页面,浏览器会200-500毫秒时间去等待服务器发来后面的html页面,而在这断时间里,浏览器是空闲的,因此,php中通过flush()可以输出你已经准备好的html,然后再去组织下面的html,这样浏览器可以解析html片断,然后开始下载需要的其它组件。php中最好在html的head标签之后执行一次flush(),因为head一般情况下都是比较好组织并且会包含一些css或js文件,这样就可以实现获取页面内容和其它组件并行下载。

使用CDN

关于CDN的讨论好像已经超出前端考虑的范围了,可以想象,组件分发到不同的网络节点,当用户请求时,总会从一个离自己最近的、最空闲的网络节点获取数据,是多么的惬意。但是对于大多数网站来说,这几乎是无法的。

针对移动设备的优化

组件gzip解压后保持在25K以下,因为iphone不会缓存大于25K的文件。

 

--------------------------------------------------------------------

posted @ 2013-01-11 10:14  for certain  阅读(549)  评论(0编辑  收藏  举报