本篇是对《高性能网站建设指南》一书的后7种规则进行梳理。
八、使用外部Jacascript和css
1.如果需要呈现给用户的页面可以实现完整缓存,那么使用外部Jacascript和css会提高网站性能。
2.在使用使用外部Jacascript和css时,可以设置页面加载完成后下载,这样可保证页面也首屏效果。
九、减少DNS查询
1.Internet是通过IP地址来查找服务器的。由于IP地址很难记忆,通常使用包含主机名的URL来取代它,但是浏览器发送请求时,IP地址仍然是必需的。这就是Domain Name System(DNS)所处的角色,DNS将主机名映射到IP地址上。当你输入一个网址时,链接到服务器的DNS解析器会返回服务器的IP地址。
2.DNS开销:通常浏览器查找的一个给定的主机名的IP地址要花费20-120毫秒,在完成查找之前,浏览器不能从主机那里下载任何的东西。
3.使用Keep-Alive和较少的域名来减少DNS查询
十、精简JavaScript
精简是从代码中移除不必要的字符,比如空白符(空格、换行、制表符)等以减少文件大小,进而改善加载时间。
十一、避免重定向
1.重定向用于将用户从一个url重新路由到另一个url。重定向有很多种:301和302是常见的两种
2.当Web服务器向浏览器返回一个重定向时,响应中就会拥有一个范围在3xx的状态码(注意:”304 Not Modeified”并不是真的重定向-他是用来响应GET请求,避免下载已经存在于浏览器缓存中的数据。)。
3.重定向的损伤:在重定向完毕并且HTML文档下载完成之前,没有任何东西显示给用户。
十二、移除重复脚本
重复性脚本损伤性能的方式有两种:不必要的HTTP请求和执行JavsScript所浪费的时间。
十三、配置或移除ETag
1.Etag是什么?
实体标签(Entity Tag ETag)是Web服务器和浏览器用于确认缓存组件的有效性的一种机制。
2.浏览器的缓存与确认?
步骤一:Expires头:浏览器在下载组件时,会将它存储到缓存中。再次请求改组件时,会确认改组件是否过期来决定是否重新请求改组件,而这个过期时间是由Expires头的值来决定。当请求一个组件时,服务器会根据其选项在响应中返回一个Expires头。
步骤二:条件GET请求:如果缓存的组件过期了(或者用户明确地重新记载了页面),浏览器在重用它之前必须首先检查它是否仍然有效,这称作条件GET请求。如果组件有效,原始服务器会返回一个”304 Not Modified”状态码。
服务器在检测缓存的组件是否有效时有两种方式:
1.比较最新修改日期
2.比较实体标签
2.1 最新修改时间:
原始服务器通过Last-Modified响应头来返回组件的最新修改时间,它要求服务器端和客户端时间完全统一的情况下才有意思。
2.1 实体标签:
ETag提供了另一种方式,用于检测浏览器缓存中的组件与原始服务器上的组件是否匹配。ETag在HTTP1.1中引用。ETag是唯一标识了一个组件的一个特定版本的字符串。唯一的格式约束是该字符串必须用引号引起来。原始服务器使用ETag来响应指定组件的Etag。
Etag为验证实体提供了比修改最新日期更为灵活的机制,例如,如果实体依据User-Agent或者Accept-Language头而改变,实体的状态可以反映在ETag中。此后,如果浏览器必须验证一个组件,它会使用If-None-Match头将ETag传回原始服务器。如果ETag是匹配的,就会返回304状态吗。
3.ETag带来的问题
ETag的问题在于,通常使用的组件的某些属性来构造它,这些属性对于特定的,寄宿了网站的服务器来说是唯一的。当浏览器从一台服务器获取了原始组件,之后,又向另外一台不同的服务器发起条件GET请求时,ETag是不会匹配的——对于使用服务器集群来处理请求的网站来说,这是很常见的一种情况。默认情况下,对于拥有多台的服务器网站,APache和IIS中嵌入的数据都会大大地降低有效性验证的成功率。
3.1 Apache1.3和2.X的ETag格式是inode-size-timestamp,即使文件系统的所有信息都是一致的,但是不同服务器上的inode仍然是不同的。
3.2 IIS5.0和6.0在ETag上有着类似的问题。IIS上ETag的格式是Fletimestamp:ChangNumber。ChangNumber适用于跟踪IIS配置变化的计数器。对于网站背后的服务器来说,ChangNumber不大相同。
3.3 最后结果,对于完全相同的组件,从一台服务器到另一台Apache和 IIS产生的ETag是不同的,如果你使用了服务器集群,使用ETag会造成组件不必要的重复加载并影响服务器的性能、增加宽带的开销。
4.ETag用还是不用?
如果你使用的是服务器集群,且使用默认的ETag配置,你的用户将面对缓慢的页面,你的服务器会有很高的负载,你会消耗大量的带宽,而且代理也不能有效地缓存你的内容。
为了使用ETag的灵活性的验证能力而又要消除其所带来的问题,有一种选择是对ETag进行自定的配置。比如可以使用一段根据浏览器是否为Internet Explorer而变化的脚本。如果使用PHP来生成脚本,你可以通过设置ETag头来反映浏览器的状态。
如果你的组件必须通过最新修改日期之外的一些东西来进行验证,则自定义ETag是一种强大的方法。如果你不能自定义ETag,建议你移除ETag。
十四、使用Ajax可缓存
公所周知,主动的Ajax请求时异步的,用户可能仍然需要等待响应。不过用户不必忍受整个页面的重新加载了,而且用户在等待时,UI仍然可以响应。
由于Ajax毕竟是一个请求,所有为更好的用户体验,我们仍需结合上面其他的性能优化条例来使用,比如缓存等。