web性能优化

Web性能优化,是前端优化的终身命题!
从用户角度,优化时候能够让页面加载更快,对用户的操作响应更及时,能够给用户提供更为友好的体验;从服务商角度,优化能够减少页面请求,或者减少请求所占宽带,能够节省可观的资源优化的方面可以分为页面级别和代码级别;相信很多人都听过优化网站性能的14条规则。更多的信息可见https://developer.yahoo.com ;下面我们就一起了解一些常见的方法:

第一条、尽可能的减少 HTTP 的请求数

1:性能准则:用户最终花相应的10%-20%的时间在接受请求的HTML文档,其他的时间都是花在HTML文档引用的所有组件(图片,css,script)进行HTTP请求上。

2:请求头的数据量(是小问题):每次请求的时候都会带上一些额外的信息进行传输,当请求资源很小时,可能request带的数据比实际的数据量还大,所以当请求越多时,在网路上传输的数据也就越多,传输速度自然就慢。

3:HTTP连接产生的花销:(用户输入url到下载内容,客户端经历的过程)域名解析-TCP连接-发送请求-等待(主要包含网络延迟和服务器处理时间)-下载资源-解析时间请求花费的时间大部分在其他阶段,而不是在下载资源阶段。

4:HTTP请求大多是并发,但是如果并发请求太多会对服务器造成压力,而且HTTP/1.1虽然引入管道机制允许客户端同时发送多个请求,但是服务器任然要先响应A再去响应B。合并请求理论上是要比不合并请求节省时间的。

第二条、使用CDN(内容分发网络): Use a Content Delivery Network

使用CDN内容分发网络服务器(在离你最近的地方,放置一台性能好连接顺畅的副本服务器,让你能够以最近的距离,最快的速度获取内容)

CDN内容分发网络服务器,其主要作用是可以保证网络内容更快,更稳定的传输,即加速网络访问的作用。

本质仍然是一个缓存,而且就近获取资源,当CDN中存在浏览器请求的资源时,从CDN直接返回给浏览器最短路径返回响应,加快用户访问速度,减少数据中心负载压力。

CDN缓存的一般是静态资源,如图片、文件、CSS、script脚本、静态网页等,但是这些文件访问频度很高,将其缓存在CDN可极大改善网页的打开速度。

使用CDN会极大的简化网络的系统维护工作量,网络维护人员只需将网站内容注入CDN系统,通过CDN部署在各个物理位置的服务器进行全网分发,就可以实现跨运营商,跨地域的用户覆盖。

在网站和用户之间加入CDN之后,用户不会有任何与原来不同的感觉。一个典型的CDN用户访问调度流程:
web性能优化_第1张图片

  1. 当用户点击网站页面上的内容url,经过本地DNS解析,DNS系统会最终将域名解析权交给CNAME(DNS的一种解析方式,即别名解析,比如一个域名 www.domain.com,设置一个CNAME指向它,由www.domain.com与一个IP进行绑定,如果设置多个CNAME指向它,以后修改CNAME指向的服务器时,只需要修改一个www.domain.com对应的IP即可)指向的CDN专用DNS服务器

  2. CDN的DNS服务器将CDN的全局负载均衡设备的IP地址返回给用户

  3. 用户向CDN的全局负载均衡设备发起内容url访问请求

  4. CDN全局负载均衡设备根据用户IP地址,以及用户请求的内容url,选择一台用户所属区域的区域负载均衡设备,告诉用户向这台设备发起请求

  5. 区域负载均衡设备会为用户选择一台合适的缓存服务器提供服务

    选择的依据:根据用户IP地址,判读那一台服务器据用户最近;根据用户所请求的url中携带的内容名称,判断那一台服务器上有用户所需的内容;查询各个服务器当前的负载情况,判断那一台服务器尚有服务能力。

    基于以上这些条件的综合分析之后,区域负载均衡会向全局负载均衡设备返回一台缓存服务器的IP地址

  6. 全局负载均衡设备把服务器的IP地址返回给用户

  7. 用户向缓存服务器发起请求,缓存服务器响应用户请求,将用户所需内容传达到用户终端。如果这台缓存服务器上并没有用户想要的内容,而区域均衡设备依然将它分配给用户,那这台服务器就要向它上一级缓存服务器请求内容,直至追溯到网站的源服务器将内容拉倒本地。

缺点:只能对静态资源加速;它是缓存文件,如果网站更新了内容部分电脑可能不会实时的更新过来,他需要将CDN那台计算机的内容也更新了,客户的显示器上内容才是最新的,这个时间可能需要几小时甚至半天,所以CDN加速不适合经常更新的网站;代价高

第三条、 添加Expire/Cache-Control 头:Add an Expires Header

现在越来越多的图片,脚本,css,flash被嵌入到页面中,当我们访问他们的时候势必会做许多次的http请求。其实我们可以通过设置Expires header 来缓存这些文件。Expire其实就是通过header报文来指定特定类型的文件在览器中的缓存时间。大多数的图片,flash在发布后都是不需要经常修 改的,做了缓存以后这样浏览器以后就不需要再从服务器下载这些文件而是而直接从缓存中读取,这样再次访问页面的速度会大大加快。一个典型的HTTP 1.1协议返回的头信息:
HTTP/1.1 200 OK
Date: Fri, 30 Oct 1998 13:19:41 GMT
Server: Apache/1.3.3 (Unix)
Cache-Control: max-age=3600, must-revalidate
Expires: Fri, 30 Oct 1998 14:19:41 GMT
Last-Modified: Mon, 29 Jun 1998 02:28:12 GMT
ETag: “3e86-410-3596fbbc”
Content-Length: 1040
Content-Type: text/html

其中通过服务器端脚本设置Cache-Control和Expires可以完成。
如,在php中设置30天后过期:

<!--pHeader("Cache-Control: must-revalidate"); $offset = 60 * 60 * 24 * 30; $ExpStr = "Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT"; Header($ExpStr);--> 

也可以通过配置服务器本身完成,这些偶就不是很清楚了。想了解跟多的朋友可以参考http://www.web-caching.com/

据我了解,目前阿里巴巴中文站的Expires过期时间是30天。不过期间也有过问题,特别是对于脚本过期时间的设置还是应该仔细考虑下,不然相应的脚本功能更新后客户端可能要过很长一段时间才能“感知”到这样的变化。所以,哪些应该缓存,哪些不该缓存还是应该仔细斟酌一番。

第四条、启用Gzip压缩:Gzip Components

  1. web服务器开启Gzip压缩

    在http协议中允许客户端可以选择从服务器上下载压缩的内容,服务器配置人员可以查看对应的配置文件,开启Gzip压缩,服务器启用Gzip压缩后,会在响应头中增加Content-Encoding:gzip,可以通过检查此header项来判断服务器是否开启Gzip压缩。

  2. js代码压缩

    js压缩原理一般是去掉多余的空格,替换长变量名,简化一些代码写法等。Js代码压缩工具很多,其中用的最多的是UglifyJS,它不仅是压缩工具,同时具有js语法分析和代码优化功能。

  3. css代码压缩

    Css代码压缩原理和js代码压缩原理类似,去掉多余的空格注释等,同时优化合并一些css规则定义,css代码压缩工具比较有名的是CSS
    Compressor

  4. 图片压缩:可以使用图片压缩工具

    何时压缩代码也很重要,因为压缩后的代码会影响代码的调试,使得开发者不容易确定代码出错的位置,所以推荐在开发后期,甚至在网站的发布阶段做代码和资源的压缩。如果放在代码发布阶段压缩,则开发者开发过程不需要考虑代码压缩问题,方便开发者的开发与调试。

第五条、将css放在页面最上面 ( Put Stylesheets at the Top)

将css放在页面最上面,这是为什么?因为 ie,firefox等浏览器在css全部传输完全之前不会去渲染任何的东西。理由诚如小马哥说得那样很简单。css,全称Cascading Style Sheets (层叠样式表单)。层叠即意味这后面的css可以覆盖前面的css,级别高的css可以覆盖级别低的css。如:!important覆盖其他的,浏览器在他完全加载完毕之后再去渲染无疑也是合情合理的很多浏览器下,如IE,把样式表放在页面的底部的问题在于它禁止了网页内容的顺序显示。浏览器阻止显示以免重画页面元素,那用户只能看到空白页了。Firefox不会阻止显示,但这意味着当样式表下载后,有些页面元素可能需要重画,这导致闪烁问题。所以我们应该尽快让css加载完毕顺着这层意思,如果我们再细究的话,其实还有可以优化的地方。比如本站上面包含的两个css文件,

“http://www.space007.com/themes/google/style/google.css” type=“text/css” media=“screen”/> 和“http://www.space007.com/css/print.css”type=“text/css” media=“print” />。

从media就可以看出第一个css是针对浏览器的,第二个css文件是针对打印样式的。从用户的行为习惯上来将,要打印页面的动作一定是发生在页面页面 显示出来之后的。所以比较好的方法应该是在页面加载完毕之后再动态地为这张页面加上针对打印设备的css,这样又可以提高一点速度。

第六条、将script放在页面最下面 (Put Scripts at the Bottom )

将脚本放在页面最下面的目的有那么两点:

  1. 因为防止script脚本的执行阻塞页面的下载。在页面loading的过程中,当浏览器读到js执行语句的时候一定会把它全部解释完毕后在会接下来读下面的内容。不信你可以写一个js死循环看看页面下面的东西还会不会出来。(setTimeout 和setInterval的执行有点类似于多线程,在相应的响应时间之前也会继续下面的内容渲染。)浏览器这么做的逻辑是因为js随时可能执 行 location.href或是其他可能完全中断此页面过程的函数,即如此,当然得等他执行完毕之后再加载咯。所以放在页面最后,可以有效减少页面可视元素的加载时间。

  2. 脚本引起的第二个问题是它阻塞并行下载数量。HTTP/1.1规范建议浏览器每个主机的并行下载数不超过2个(IE只能为2个,其他浏览器如ff等都是默认设置为2个,不过新出的ie8可以达6个)。因此如果您把图像文件分布到多台机器的话,您可以达到超过2个的并行下载。但是当脚本文件下载时,浏览器不会启动其他的并行下载。当然对各个网站来说,把脚本都放到页面底部加载的可行性还是值得商榷的。就比如阿里巴巴中文站的页面。很多地方有内联的js,页面的显示严重依赖于此,我承认这和无侵入脚本的理念相差甚远,但是很多“历史遗留问题”却不是那么容易解决的。

第六条、避免css表达式

避免在CSS中使用Expressions

避免使用@import(等页面加载完后才去加载,用link标签替换它)

避免通配选择符,单规则的属性选择器

css选择符是从右到左匹配的

比如:#hrader>a{font-weight:blod;}

浏览器遍历页面中所有的a元素->其父元素的id是否为header

#hrader a{font-weight:blod;}

要比上一个消耗更多的事件

属性选择器是:.selected[href="#index"]{background:red;}

浏览器匹配所有元素->检查是否有href属性并且href属性值等于“#index”->分别向上级逐级匹配class为selected的元素,直到文档的根元素。

第八条、把javascript和css都放到外部文件中 (Make JavaScript and CSS External )

不仅从性能优化上会这么做,用代码易于维护的角度看也应该这么做。把css和js写在页面内容可以减少2次请求,但也增 大了页面的大小。如果已经对css和js做了缓存,那也就没有2次多余的http请求了。当然,有些特殊的页面开发人员还是会选择内联 的css和js文件。

第九条、减少DNS查询 (Reduce DNS Lookups)

在 Internet上域名与IP地址之间是一一对应的,域名(kuqin.com)很好记,但计算机不认识,计算机之间的“相认”还要转成ip地址。在网络 上每台计算机都对应有一个独立的ip地址。在域名和ip地址之间的转换工作称为域名解析,也称DNS查询。一次DNS的解析过程会消耗20-120毫秒的 时间,在dns查询结束之前,浏览器不会下载该域名下的任何东西。所以减少dns查询的时间可以加快页面的加载速度。yahoo的建议一个页面所包含的域 名数尽量控制在2-4个。这就需要对页面整体有一个很好的规划。目前我们这点做的不好,很多打点的广告投放系统拖累了我们。

第十条、压缩 JavaScript 和 CSS (Minify JavaScript )

在前面的压缩中已经列举。
当然,压缩带来的一个弊端就是代码的可读性没了。相信很多做前端的朋友都遇到过这个问题:看Google的效果很酷,可是去看他的源代码却是一大堆 挤在一起的字符,连函数名都是替换过的!自己的代码也这样岂不是对维护非常不方便。所有阿里巴巴中文站目前采用的做法是在js和css发布的时候在 服务器端进行压缩。这样在我们很方便地维护自己的代码。

第十一条、避免重定向 (Avoid Redirects )

  • 原因:
    重定向损伤性能,他会延迟整个HTML文档的传输,在HTML文档到达之前,页面不会呈现任何东西,也没有任何组件会被下载。
    比如当你输入http://www.kuqin.com/的时候服务器会自动产生一个301服务器转向 http://www.kuqin.com/ ,你看浏览器的地址栏就能看出来。这种重定向自然也是需要消耗时间的。当然这只是一个例子,发生重定向的原因还有很多,但是不变的是每增加一次重定向就会增加一次web请求,所以因该尽量减少。
  • 重定向:
    就是当用户浏览器或搜素引擎访问某个旧的网址地址时,服务器告诉浏览器或搜素引擎,改网址已经搬家,新家的地址是…,请使用新地址来访问该网页。
  • 避免重定向的方法:
  1. 在定义连接地址的href属性的时候,尽量使用最完整的,最直接的地址
  2. 后台可以去设置,Response.Redirect第二个参数设置为false
  3. 如果涉及到从测试环境到生产环境的迁移,建议通过DNS中的CNAME的机制来定义别名,而不是强制地重定向

第十二条、移除重复的脚本 (Remove Duplicate Scripts )

从性能上考虑,代码规范上看也是这样。但是不得不承认,很多时候我们会因为图一时之快而加上一些或许是重复的代码。或许一个统一的css框架和js框架可以比较好的解决我们的问题。不仅是要做到不重复,更是要做到可重用。

第十三条、配置实体标签(ETags) (Configure ETags )

不是很懂 ,参考网址贴上,上面有详解:参考网址

第十四条、使 AJAX 缓存 (Make Ajax Cacheable )

ajax还要去缓存?做ajax请求的时候往往还要增加一个时间戳去避免他缓存。It’s important to remember that “asynchronous” does not imply “instantaneous”.(记住“异步”不是“瞬间”这一点很重要)。记住,即使AJAX是动态产生的而且只对一个用户起作用,他们依然可以被缓 存。

你可能感兴趣的:(基础总结,web性能优化,前端)