不考虑带宽大小,不考虑服务器性能如何,如何保证网站从服务器到用户浏览器这个过程是最快的,打开一个网站之前的用户体验是最好的呢。Steve Souders的高性能网站建设指南这本书当中给我们建议了以下几种方法:
1.减少HTTP请求
2.使用内容分发网络(传说中的CDN服务)
3.添加Expires头
4.压缩组件
5.将样式表文件放在顶部
6.将脚本文件放在底部
7.避免CSS表达式
8.CSS样式表文件和JS脚本文件使用外链的方式引入
9.减少DNS查找
10.精简Javascript
11.避免重定向
12.移除重复脚本
13.配置ETag
14.是AJAX可缓存
作者的意图是上面的14条建议都是经过各大网站测试的数据当中所总结的,我们暂且不论这些建议是否真正的有效,先来表表这14条建议都是什么含义,如何做到这14条建议。说白了就是如果我们想用这14条建议到我们的项目当中,我们需要遵守些什么,什么要做,什么不要做,怎么做的问题。
第一条:减少HTTP请求
网站性能优化,就是优化网站打开的速度了。把这一条放在第一的位置,肯定因为这家伙非常的耗用资源。你说啥?啥是HTTP?如果不明白啥是HTTP,尊驾请异步这里。HTTP_超文本传送协议定义了浏览器(即万维网客户进程)怎样向万维网服务器请求万维网文档,以及服务器怎样把文档传送给浏览器。要明白为什么说HTTP请求耗用资源,就得稍微了解下HTTP请求。
一次完整的HTTP请求主要包括如下步骤:1、建立TCP连接2、浏览器向WEB服务器发送请求命令3、WEB浏览器发送请求头信息4、WEB服务器应答5、WEB服务器发送应答头信息6、WEB服务器向浏览器发送数据7、WEB服务器关闭TCP连接。每一个步骤都需要耗费时间来完成,比如步骤3,就相当于平常我们上传东西,步骤6,相当于我们从网上下载,这些步骤虽然很快,但还是会耗费时间去干这些事,而且每次HTTP请求都会重复做上面的1~7这写步骤,如果页面当中HTTP请求的数量过多,就会耗用大量的时间,导致网站加载速度过慢。网页当中的图片,样式文件,脚本文件和视频媒介文件都会有HTTP请求的发生,当你的网站当中图片的数量越多,你的网站打开的速度就会越慢。像百度图片这种只好选用其它的方式来优化网站的速度,例如图片延迟加载。总的来说,尽量减少我们网页当中的HTTP请求就对了。那怎么做呢?上面也说了,页面当中的图片,样式、脚本和视频文件会进行HTTP请求,我们主要就是针对图片、样式、脚本、Flash视频这几个内容进行优化。
第一步:使用图片地图,HTML当中的标签<map><area ....></map>
第二步:尽量把网站中使用的图片,作为标签的背景写到CSS样式文件当中。当作为背景的图片数量越来越 多的时候,就使用CSS Sprites技术,把多个图片合并成一张图片。
第三步:通过使用data:url在页面当中包含图片但无需额外的HTTP请求(低版本的IE不支持),比如我门见到过的Base64位图片
第四步:就是尽可能的合并CSS和JS文件
第二条:使用内容发布网络
什么是内容发布网络?其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。如果用户A身在中国,网站B的服务器在美国,网站C的服务器在中国,那么理论上用户A访问网站C的速度要比访问B的速度快。因为A用户和C网站在距离上更近,网络数据传输的距离近,时间上就会短。内容发布网络就是分布在多个不同地理位置的WEB服务器,用于更加有效的向用户发布内容。
例如M用户请求了G网站,G网站上的一个文件F存放在内容分发网络的某一个服务器上面。当你的网站W引用文件F的时候,也是使用改内容发布网络,当M用户访问你的网站W的时候,它因为已经在访问G网站的时候下载过F文件了,所以在访问你的网站W的时候,就不用重新下载该文件了,直接从用户本地的缓存中读取。如果该文件F之前没有被缓存过,就会从靠近用户M距离最近的那个内容发布网络节点下载该文件。
第三条:添加Expires头
添加一个时间足够久的Expires头,用来缓存从服务器上请求的文件。
假如你定义了如下:
Expires: Thu, 15 Apr 2017 20:00:00 GMT
这是一个有效期非常长的Expires头,它告诉浏览器在2017年4月15日之前,都是用这个请求过的缓存文件。这样做就将HTTP请求的数量减少一个。
Expires头使用一个特定的时间,它要求服务器端和客户端的时钟严格同步。
换另外一种方式,Cache-Control使用max-age指令制定组件被缓存多久。让人值得庆幸的是有些浏览器默认都设置了这些内容,例如IIS服务器上。
添加Expires头的真正意义其实还是为了减少HTTP请求。
第四条:压缩组件
前端:
通过对CSS样式文件和JS脚本文件的内容压缩,图片压缩,如果是PNG格式的图片压缩,推荐使用TinyPNG。
服务端:
启用GZIP编码来压缩HTTP响应包的大小。通过HTTP请求中的Accept-Encoding头来标识对压缩的支持。
Accept-Encoding:gzip,deflate
IIS服务器默认情况是开启文件压缩的。
内容压缩的主要意义是减少HTTP请求响应的大小来减少响应时间。
第五条:将样式表放在顶部
HTML当中的内容是至上而下加载的,样式文件放在顶部,在加载HTML文档的时候,同时也在加载样式文件,这样页面会一边加载一边让浏览器渲染已经加载好的内容,也就是“逐步呈现”我们的网页内容。
将样式表文件放在文档底部会导致在浏览器中阻止内容逐步呈现。把样式文件放在顶部对整个页面的加载时间并没有减少,它影响的是浏览器对我们页面上内容加载的反映。
一点一点的加载让用户看到我们的页面,比加载完所有内容之后再把页面展示给我们的用户,两种方式在时间上并没有什么差别,但去能给用户不一样的感觉。
第六条:将脚本放在底部
加载脚本会阻止页面逐步呈现。当浏览器加载到一段JS脚本的时候,它会等待这一段脚本解析完成之后,再继续加载下面的内容。如果解析脚本花费的时间为1s种,那么用户就要等待1s之后才能看到页面一点一点的加载。阻止逐步呈现就意味着等待,就会影响用户的体验。
第七条:避免CSS表达式
使用CSS表达式就是使用expression来设置页面的某些样式。这种方法现在使用的人应该不多了,但我们了解下总没有什么不好的。
为什么使用表达式不好?因为表达式计算的频率太高,浪费浏览的资源。
加入有个下面的CSS规则:
<code>
p{
width:expression(setCntr(),document.body.clientWidth<600?"600px":"auto");
}
</code>
setCntr()函数增加一个全局变量的值并将这个值应用到一个页面元素上面。如果页面中有个10个段落(p)。加载整个页面会执行CSS表达式10次。如果用户改变了页面窗口的大小,滚动鼠标,该CSS表达式都会被执行10次。这样毫无意义的计算,浪费浏览器的资源是很可怕的。如果你在一个页面当中应用过多的CSS表达式,就会照成浏览器崩溃。
第八条:引用外部的JS和CSS
首先我们思考如下一个问题:
情况一:HTML页面大小有50K,CSS样式文件大小有20K,脚本JS文件有30K。
情况二:页面B包含样式CSS和脚本JS,大小是90K
分布测试两种情况,我们会发现情况二要比情况一快30%~50%,因为情况一需要承担多个HTTP请求带来的开销。
的确内联所需要的开销时间会短些;但是,如果放入外部文件中,有下面的好处:
1.样式文件和JS文件就有机会被浏览器缓存起来。
2.能够被项目当中的其它页面重用。
这样同一个HTML文件,不增加HTTP请求数量的基础上,肯定体积大所需要的开销会大些。
维护性上,如果把样式文件CSS和脚本文件JS统统放在页面HTML当中,我们能够想想是怎么一种混乱的情况吗?
第九条:减少DNS查找
当浏览器与Web服务器建立连接时,它需要进行DNS解析,将域名解析为IP地址。然而,一旦客户端需要执行DNS lookup时,等待时间将会取决于域名服务器的有效响应的速度。
第十条:精简Javascript
这里比较不好把握,牵扯到编写JS脚本的一些内容。例如:避免使用过多的全局遍历,避免过多的DOM操作,缓存查找到的DOM元素。然后就是使用Grunt这种工具对文件进行压缩。
第十一条:避免重定向
这个地方主要说的是后台代码的重定向,我这里不多说
第十二条:移除重复脚本
重复脚本对网站性能照成的损伤有两个方面:
1、增加不必要的HTTP请求
2、执行javascript所浪费的时间
第十三条:配置ETag
这一条是为了防止缓存不起作用进行的配置,属于后台方面的内容。
最终目的:缓存内容减少HTTP请求。
第十四条:使Ajax可缓存
使Ajax可缓存的前提是保证你的数据是不经常变化的,如果发生变化就重新从服务器请求新的数据,我们使用一个长久的Expires头来缓存Ajax请求的内容。
关于Ajax,我建议通过Ajax请求的内容仅包含必须从服务端返回的数据信息,HTML结构部分则缓存到HTML页面当中,然后通过模版解析,把所通过ajax请求的内容展示出来,因为目前浏览器端的运算速度越来越快了,所以现在完全可以这样做。
结束语
网站性能优化,我的理解就是优化一个网站打开的速度,也就是怎么样让用户体验到飞一般的感觉。
网站优化包括前端优化和后台优化,这本书并没有按照前后端这样来分别讲解网站优化。
下面再针对前端方面说几个性能优化的方面:
1.了解Repaint和Reflow,减少页面reflow,像document.write,document.getElementById("xx").style.xx=''这些,都会reflow页面。
2.减少DOM操作,还有上面说到的,把查找到的DOM进行缓存。
3.使用json数据交换格式
4.语义化HTML
总的来说优化的最终目的就是:减少HTTP请求,压缩HTTP请求响应的文件大小,尽量缩短用户访问网站所花费的时间。