高性能网站建设之前端优化规则

一个网站体验好不好,其实首当其冲的是网页的加载速度,其次是网站的样式和用户体验。网页的加载速度除了与后台业务逻辑的计算量相关之外,很多优化规则跟前端知识息息相关。那么前端有哪些优化规则可以提高网站的加载速度呢? -- 参阅《高性能网站建设》

实例参见:http://stevesouders.com/hpws/rules.php

雅虎团队也给出了35个优化建议:https://developer.yahoo.com/performance/rules.html 同时给出了相应的测试工具Yslow http://developer.yahoo.com/yslow/

 

规则一:减少HTTP请求

1,CSS Sprites合并样式图片。

在开发过程中很多html标签的修饰用到很小的图片,如果每个很小的一个图片都是单独的,那么它将产生一次http请求比较浪费资源,可以将这些很小的图片合并到一张大的图片上,这样能够有效的加快渲染速度,当然是不是所有图片都合并到一张图上呢?当图片太大时,下载这个图片也会很耗时,就会丧失优化的效果,应该根据网页的显示区块进行相应的合并,一般小图片整合到一张图片时,图片大小不要超过300K-500K(个人喜好)。

2,合并样式和脚本文件

很多人喜欢将网页分区后用不同的css文件去渲染样式,这样文件分开比较清晰,提升阅读性,不过在线上环境时,是可以利用css工具将这些样式文件合并为一个样式文件的,但也不是所有的样式文件都要合成一个文件,比如第三方类库的css,或者特殊自定义等功能的css文件,应该根据项目情况进行合并,js文件也是同样的做法。

 

规则二:使用CDN (内容分发网络 Content Delivery Network)

网站在加载的过程中,html文档加载只占了5%-20%的时间,其他时间都用于加载网站组件上(样式、脚本、图片)。根据二八规律,我们最应该优化的就是组件的加载时间,这也是为什么稍大型的网站都会使用CDN的原因,而且很多电商网站图片显示比较丰富的都有专门的图片服务器。那CDN为什么能提高组件的加载速度?CDN的基本思路就是避开影响网络传输和网络稳定性的因素,根据用户网络流量、各节点的连接状况、和用户之间的距离,确定将连接转到离用户最近的服务节点上。所以用户分布很广的情况下,优化效果非常明显。CDN的主要优势有以下几点:

1,CDN就近访问服务节点,提高了资源响应速度和下载速度。

2,CDN的服务稳定性和负载有保证,减轻了源网站的负载,同时解决了跨运营商访问的问题。

3,有效应对DDOS攻击,能有效保障源网站的安全。

 

规则三:添加Expires头

 当访问网站时,网站响应请求头中都会有cache-control:max-age=300、expires:Fri, 02 Jun 2017 08:42:03 GMT、last-modified:Mon, 15 May 2017 02:30:51 GMT这几个信息,expires指令是服务端告诉客户端次资源什么时间过期,在过期时间之内客户端直接加载缓存的资源,但是expires指令有个问题,如果客户端时间不正确或者服务端时间不正确,则有可能产生不了缓存效果,比如:如果服务器时间为2017-06-01,但实际时间为2017-06-03,expires默认缓存时间为1天,返回给客户端的有效时间则为2017-06-02,与客户端实际时间对比发现失效了,就会再次请求服务端。客户端时间不正确也类似。

但是这个问题可以通过cache-control指令中max-age来解决,max-age是指这次响应后多少秒内缓存有效。优先级高于expires,所以当expires不正常时,max-age可以替代,所以常见的网站这两个指令都同时在用。规则九中详细讲述缓存优先级。

Apache配置Expires的命令为:

ExpiresDefault "access plus 30 days"     默认所有30天以后失效

ExpiresDefault "access plus 4 weeks"    默认所有4周后失效

ExpiresByType text/html "access plus 1 month 15 days 2 hours"   html类型的 1个月15天2个小时候失效

ExpiresByType image/gif "modification plus 5 hours 3 minutes"    gif类型的5个小时 3分钟失效

 

规则四:压缩组件

浏览器发送请求时一般会带Accept-Encoding:gzip, deflate, sdch, br的头信息,它表示的意思是此浏览器支持gzip、deflate、sdch、br的压缩方式,请求到服务器后,服务器会根据客户端支持的压缩方式以及服务器端自己支持的压缩组件对请求的资源进行压缩后再返回给客户端,通过Content-Encoding:gzip头信息告诉客户端服务端是采用了那种压缩方式。目前最流行的方式是gzip。压缩组件就是指压缩资源的大小,文件越小越容易传输并能加快传输速度。压缩组件主要是压缩样式和脚本文件、html文档。在开发过程中我们很多时候都会合并css或js文件并压缩,通常生成.min.js等文件,这个也是能有效减小资源体积,但服务器还会对.min.js文件再次用gzip进行压缩使得资源更小,传输更快。ps:Apache2.x版本是用mod_deflate模块对资源进行压缩,压缩方式是gzip,配置一般为AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript ,详细参见 http://httpd.apache.org/docs/2.4/mod/mod_deflate.html

 

规则五:样式表放首部、脚本放尾部

样式放在底部有些浏览器逐步呈现,会出现白屏问题。

脚本放在尾部是防止脚本文件中有阻塞的逻辑如:document.write,会阻塞组件的并行下载。

 

规则六:避免CSS表达式、精简JS

尽量避免CSS表达式,不好的CSS表达式非常耗性能,对用户体验非常不好,不建议使用,例如:p{width:expression(setCntr(),document.body.clientWidth<600 ? "600px" : "auto");min-width:600px}这里主要是设置p的最小宽度,有的浏览器不支持采用css表达式,但是表达式求值频率没有考虑好会异常的高,非常耗性能,一般采用合理的js去修复这类问题。

精简js是指就是利用js压缩工具对js源码进行压缩,css文件也有类似工具,减小资源大小,利于网络传输、加快加载速度。

 

规则七:使用外部JS和CSS文件、移除重复脚本

使用外部js和css文件与使用内联js和css文件各有利弊,使用内联文件会减少http请求,加载速度会快一点,但是外部的js和css文件利于缓存,利于组件重用,将公用的模块封装后,不同的页面都可以使用,利于开发维护。目前大型网站上两种方式都在用,部门js和css文件都用内联方式,一些js和css采用外部调用,普通网站一般建议使用外部js和css文件。

同时注意不要重复引入相同的资源文件,浪费资源,而且可能会产生意想不到的问题,所以引入文件时因仔细检查。

 

规则八:减少DNS查找、避免重定向

典型的一次DNS解析耗费20-120 毫秒,假如网站加载的组件分布在不同的域名下,或者采用了CDN服务,那么域名很多的情况下DNS解析花费的时间就比较多,减少DNS查找的方法,首先增加DNS缓存,但是DNS缓存在操作系统和浏览器上都有实现自己的DNS缓存,不太需要服务的关心,而服务的关心的是DNS记录TTL值的设置,过长不利于容灾切换,过短不利于缓存,其次最常用的一种方法是在淘宝、京东 经常会看到类似的标签<link rel="dns-prefetch" href="http://hm.baidu.com" />  dns-prefetch的作用就是DNS预解析,DNS Prefetching是具有此属性的域名不需要用户点击链接就在后台解析,而域名解析和内容载入是串行的网络操作,所以这个方式能减少用户的等待时间,提升用户体验。注:dns-prefetch需慎用,多页面重复DNS预解析会增加重复DNS查询次数。

 

规则九:配置ETag

 Etag指entity tag实体标签,是服务器确认缓存组件有效性的一种机制。如果浏览器支持ETag,对于相应资源会返回etag头信息,浏览器下次发送请求时发送If-None-Match头信息值为上次返回的ETag信息,如果此时服务器上对应的资源已经改变那么资源对应的Etag信息就改变了,此时会将If-None-Match的值和Etag的值对比,不同则重新返回Etag值信息,如果相同直接返回304状态信息。

缓存的几种方式:

1,Etag 

2,Last-Modified  、 If-Modified-Since   响应时返回last-modified信息,下次发送请求时用if-modified-since携带上次last-modified的数据,服务端则比较对应资源文件跟这个修改时间是否一致,不一致返回新的资源,一致则返回304状态。

3,cache-control:max-age=300 ,下次请求时检查是否在这个缓存时间内,不在则请求新的资源,在则使用缓存数据。

4,Expires 和客户端的时间进行对比判断有效期

服务器优先级响应:Etag>Last-Modified>max-age>Expires   (max-age和expires是无需请求服务器的)

注意:Etag有个问题在一台服务器上时,生成的Etag能够保证标识的唯一有效性,如果服务是集群时有效性得不到保障,所以大多数网站不使用Etag指令。

 

规则十:使Ajax可缓存

 Ajax请求分为POST和GET两种类型,POST请求是不能进行缓存的,而GET请求在URL相同的情况下是可以缓存的。

posted @ 2017-06-01 19:51  easma  阅读(116)  评论(0编辑  收藏  举报