摘 要:随着全球信息网络化的不断扩展,网站的应用越来越重要。速度成为了一个网站使用体验和市场成败的最重要指标之一,快速便成为一个网站高性能的体现。
关键词:性能; 优化; JavaScript
随着全球信息网络化的不断扩展,网站的应用越来越重要。速度成为了一个网站使用体验和市场成败的最重要指标之一,快速便成为一个网站高性能的体现,网站的建设包括“前端”和“后端”两部分。“后端”的时间是指从服务器返回第一个字节到客户端所花费的时间,它包含大部分的后端处理:数据库查询、远程web服务调用、拼接HTML等等。其余的是“前端”的时间,如执行JavaScript代码以及渲染页面等,也包含了下载页面上所有相关资源的时间。据统计80%-90%的性能由前端决定,所以笔者将以前端优化设计为主,讲解一些提高网站性能的方法。
1 服务器端优化设计
1.1 使用内容发布网络
内容发布网络(cdn)是一组分布在多个不同地理位置的web服务器,用于更加有效地向用户发布内容。Cdn选择网络跳跃最小的服务器或者最短响应时间的服务器,从而节约成本提高速度,Cdn还提供备分服务、扩展存储、缓存。Cdn技术在国内还未普及,还有一些缺点需要改进。
1.2 添加 Expires头
静态文件我们可以设置为永久不过期。对于动态文件Web服务器使用Expires头来告诉web客户端它可以使用部分内容,直到指定时间为止。长久的Expires头常用于图片,时间较长的Expires会带来额外的开发。
1.3 压缩内容
大部分网站都使用了gzip技术,可以减轻网络流量压力,通常能将相应的数据量减少70%。常用的Nginx和Apache都能配置,Apache使用mod_gzip 和mod_deflate。经过测试大约10%-15%的访问没声明支持gzip,结果是这部分用户加载的资源总量增大一倍,打开页面的速度大大增加。经过研究发现是这些用户使用的代理工具和安全软件删除了浏览器的accept-encoding头的内容,导致页面加载变慢。
2 内容优化设计
2.1 减少 HTTP 请求
(1)图像地图:在一个图片上关联多个url,url选择取决于点击图片的哪个位置。即减少了图片数量,又美观。(2)内联图像:使用 data: URL scheme 在实际的页面嵌入图像数据,可以在页面中包含图像,但不会增加额外的http请求,Ie不支持。(3)合并文件:把多个js或者css文件合并为一个。
2.2 减少 DNS 查找
浏览器解析url,返回服务器IP地址。Dns也有开销,所以我们要减少页面加载花费在Dns查找上的时间。通常使用缓存Dns keep-alive和较少的域名来减少Dns查找。结合减少 HTTP 请求数来综合考虑。(1)减少iframe数量:使用iframe实现脚本异步加载能提高性能,但是我们常常以损害性能的方式使用iframe。创建iframe的开销能比创建dom元素高出1-2个数量级之多,Iframe会阻塞onload事件,导致页面加载时间延长,影响用户体验。(2)避免重定向:301、302等重定向会增加加载速度。(3)其他:减少dom元素数量,利用并行、延迟、预加载, 杜绝404错误。
2.3 Css优化设计
(1)css放到 HTML 代码页顶部:使页面加载更快,把样式更早的呈现出来。(2)避免 CSS 表达式:CSS 表达式在Ie浏览器中可能会被执行成千上万次,导致页面打开慢。(3)使用外部css:能够有针对性的对其进行单独的处理,如压缩或者缓存。(4)使用 <link> 而不是@importChoose <link> over @import。(5)简化选择符:因为Css选择符是从右到左匹配,所以用最高效的id选择符是最好的选择。避免使用通配符,不限定id选择符,不限定类选择符,规则越具体越好,避免使用后代选择符,避免使用子选择符,继承等几种方法也能提高性能。
2.4 图片优化设计
(1)优化图片:可以使用一些工具实现比如photoshop的另存为web格式,通常优化到60%-70%的质量,然后再用工具进行一些无损压缩。常用的图像格式有:jpeg、png、gif,最好的是png格式。Png格式将图像保存在“块”中,对于web来说大部分“块”是非必要的,我可以用工具将非必要的“块”删除,从而达到优化效果。Jpeg中包含注释、应用程序定义的信息、相机型号、日期,位置等信息,这些信息可以通过工具安全的删除。Gif转化为png8,再对png优化。(2)使用CSS Sprite:将多个背景图片合并到一个大的图片中,通过修改背景的位置,在元素上显示背景图片的一部分。我们还可以继续优化,比如将颜色相近的图标组合在一起、避免不必要的空白、元素水平排颜色在256种之内、不使用对角线渐变等。当然如果透明区过多占用过多内存,可能会引起性能问题,需要权衡。(3)不要在 HTML 中使用缩放图片: 如果一张200*200的图像在通过<img height="100" width="100" src="image.jpg" >加载的时候就会带来额外开销,浏览器会将图像缩小,但是下载的图像仍是原图。(4)用更小的并且可缓存的 favicon.ico或apple touch icon
3 JavaScript优化设计
如今JavaScript被越来越多的应用于网页当中。但是随着JavaScript代码行数不断增长,加上执行JavaScript的引擎几乎没有变化,JavaScript带来的性能问题越来越多。虽然chrome,firefox,safari都开发了新的JavaScript引擎,但是这些编译器方面的优化还无法完全解决代码带来的性能问题。
3.1 页面渲染和脚本加载
JavaScript引擎是单线程执行的,所以所有事件都要排队等待处理。页面渲染和JavaScript处理是互斥的。所以脚本会阻止并行下载而浏览器的加载是从上往下,如果脚本的页面顶部,不加载完脚本,页面便不会显示,这样影响了用户体验,我们应该先将整个页面呈现给用户。所以脚本最好放到页面底部。当然如果有特殊要求,需要脚本效果,早呈现出来,可以把脚本放在需要的位置即:按需加载。虽然defer可以解决这个问题,但是有些浏览器不支持defer属性。也可以用xmlHttpRequest动态创建script元素。或者利用JavaScript异步属性async。Web Workers是HTML5的一个JavaScript多线程解决方案,今后可能会更好的解决加载问题。
3.2 使用外部JavaScript
能够有针对性的对其进行单独的处理,如压缩或者缓存。当然把脚本写在页面里能减少HTTP 请求数,所以需要按页面的性质设计方法。
3.3 压缩精简
删除无用代码和重复代码,然后进行压缩。常用的压缩工具是JSMin 和 YUI Compressor。
3.4 Dom操作优化
文档模型对象Dom是用于操作html的一种程序接口。Dom和JavaScript是分开实现的。例如Chrome使用WebCore库渲染页面
,用V8引擎来实现JavaScript。所以Dom和JavaScript的交互只能通过接口,JavaScript每次访问Dom都要有消耗,所以Dom操作慢。
(1)减少交互次数。如例子:
function testOne (){for (var a=0; a<100;a++){
document.getElementById(‘b’).innerHTML +=’c’} }
这段代码每次循环元素被访问两次:一次取innerHTML属性,一次重写。以减少访问次数为目的经过优化代码可以写为:
function testTwo (){var d=’’;for (var a=0; a<100;a++){d +=’c’} document.getElementById(‘b’).innerHTML +=’a’}循坏全部结束一次性写入,经测试速度快百倍以上。
3.5 循环优化
循环处理是所有编程语言最常用的一种方式,循环执行过长会严重影响体验。循环类型有四种:for循环、while循环、do-while循环、for-in循环。四种里面最慢的是for-in循环,其他三种可以以减少迭代为目标情况来选择最合适的方法。for-in循环遍历对象属性的时候会全部遍历,消耗大、效率低,没什么好优化的地方。如果知道明确的对象属性,可以用循环数组来代替。
3.6 条件语句优化
常见的用法有switch和if-else。因浏览器不同,没有哪种最好,但是我们可以在条件较多的时候使用switch。而用if-else的时候,我们可以把最可能出现的条件放在首位。
3.7 Ajax请求使用 get 方法
因为post要对服务器请求两次,而get只请求一次,所以在URL 长度不超过2K的情况下,使用get方法。
3.8 浏览器内存泄露
随着Ajax技术的流行,内存泄漏就成为了越来越严重的问题。造成泄漏的主要模式有闭包和循环。如果发现泄漏问题,我们可从这两方面入手,更快的找的问题源头,及早解决。
3.9 利用框架开发
用源生的JavaScript代码编程,理想状态下性能应该是最好的。但是因为每个人的水平不同,写出的代码可能即繁琐庞大性能又不好。所以现在流行用各种JavaScript框架进行开发。利用框架的优势是代码量少、学习起来也相对简单、开发速度快、对于各种浏览器兼容性也好。现在JavaScript框架很多,常用的有jQuery、YUI、MooTools、prototype、dojo、extjs等。通过以上几方面概述了如何优化设计一个高性能网站的基本方案,希望对读者有所帮助。