前端加速网站的方法

   已经证实有许多可以加速页面访问的速度,下面就分7类包括35个实例:

   最小化http请求

   终端用户响应时间的80%是在前端,而这恰好是花费在下载页面组件上:图片,级联样式表,脚步,flash等。减少加载组件的数量也就是减少展现页面的http请求的数量。这是加快页面访问速度的关键。

   减少页面组件加载的方法之一就是简化页面的设计。但有没有一种方法加载丰富的页面内容而且响应速度很快呢?这里有些技巧减少http请求数,并且支持富页面设计。

   合并文件是减少http请求的一种方法。通过合并所有的script文件成单一的文件,合并所有的css文件成单一的文件。合并文件是最富有挑战性的(因为js和css都是跨页面的),但这会降低页面的响应时间。

  css spirate是减少图片加载时间的好方法。合并您的背景图片成单一的图片,使用css的background-image和background-position属性 得到所要的图片段。

  image map ,合并多个图片成单一的图片。图片整体大小差不多,但是这减少了http请求数,加快了页面的加载速度。image map 只是在页面上相近的图片生效,例如导航栏。使image map 协调起来工作可能很繁琐或者容易犯错。使用image map取图片是很费劲的,所以这里并不推荐使用。

  inline image使用url scheme嵌入图像数据到实际的页面中。这可能增加了html文档大小,合并inline image 到级联样式表是减少了http请求,加大了页面的大小。inline image仍然不支持所有的主浏览器。

  减少页面的http请求数是优化的开始。这也是第一次访问页面改善性能的最有效的方法。让用户第一次能够快速访问您的网页是最后的用户体验。

   

  使用CDN  内容分发网络

  用户主要根据您的网站的响应时间来做出反应。配置您的网页内容的多个地方的镜像 可能会超出用户的期望,您的网站快速响应非常快,但你应该从哪里开始呢?

  第一步就是要完成内容的分发位置。不要试图用分布式架构重新设计你的网站。改变架构可能包括像跨服务器同步sesision状态和复制数据库事务的可怕任务,这取决于您的程序了。试图减少用户和存取内容的距离可能效果并不理想。

   记住终端用户的80-90%的页面响应时间花费在加载页面组件上面。这也是优化性能的黄金法则,不是立马去重构您的程序,首先更好的是分发您的静态内容。这不仅减少响应时间,而且cdn让这变得更加容易。

   CDN是选取靠近用户的服务器的内容呈现给用户,所以具有更好的效率,服务器选择分发内容到一个指定的用户基于网络的优先法则。例如都是选择 最少跳转节点的服务器或这响应时间最短的服务器。

    一些大的网络公司都有自己的CDN网络。但是找家CDN服务提供商还是合算的。对于创业型企业或者私有网络公司,CDN可能不在考虑范围。但是当您的终端用户越来越庞大的时候,CDN可能就是减少响应时间的最好方法了。比如yahoo,就从服务器上把静态内容转移到cdn上(但就和上面谈到的,雅虎或者第三方都有自己的CDN)提高了至少20%的响应速度。切换到CDN是相对容易的,但是给你的网站速度的提升那是巨大的。

    

     给页面头部添加expire或 cache-control

     这个规则有两个方面:

     1:对应静态内容页,设置头部expires 在未来的某个时间,以致页面永不过期。

     2:对应动态内容页,使用一个合适的头部cache-control  帮组浏览器 响应请求的变化。

    web页面设计变得越来越丰富了,那也意味这页面包括了更多的js,css,image,flash等。用户第一次访问您的页面可能有几次http请求,但是通过使用expire头部策略,你就缓存了这些内容。这就避免了持续的不必要的页面请求。expires头部通常用在图像上,但是可以用在所有的组件上,比如js,css,flash。

      浏览器使用缓存减少http请求数的大小和容量,使页面加载速度更快,使用expires 头部的就是告诉一个客户端一个内容能够被缓存多久,下面是一个未来的expires header,也就是告诉浏览器这个知道2012 年 12月 5日才过期:

      

    Expires: Thu, 5 Dec 2012 20:00:00 GMT
  

  如果你的服务器是apache的,那么就使用expiredefault指令设置一个相对当前日期的过期日期,下面这个例子就是从请求时间开始的10年后才过期。

   

     ExpiresDefault "access plus 10 years"
 
 

      记住,当您使用未来过期的时候,无论组件什么时候改变您都必须更改组件的文件名称。比如yahoo,我们的过程中经常有这一步:版本号嵌入在文件中,比如:yahoo_2.6.0.js。

      使用未来过期的expires头部只有在用户访问您的站点之后才生效,当用户第一次访问站点到浏览器缓存清空的这段时间内 无论 http的请求数多少都没关系。因此,用户缓存来性能优化取决于用户访问页面的频率。我们用yahoo来进行衡量下,用缓存的页面占到了75-85%。通过使用未来过期的头部,你增加了浏览器缓存的组件数,并在没有进行页面网络传输的情况下重新刷新了页面。

      

   使用GIZP

   网络传输http请求到响应的时间很大程度上取决于前端工程师做的优化。用户的带宽和ISP提供商以及临近交换机的节点都不在开发工程师的控制下。但也有其他因素影响响应时间。压缩t通过减少http请求的大小就减少了响应的时间。

   从http1.1开始,web客服端都声明支持在http请求的header加入accept-encoding进行压缩:

        Accept-Encoding :gzip,deflate

   如果web服务器发现包含了这样的header,它就会采取客服端的一种方法进行压缩,web服务器就会通知web客服端通过accept-encoding头进行响应:      content-encoding :gzip

   gzip可能是最有效最受欢迎的压缩方式。它由GUN开发并基于RFC1952标准。其他的压缩格式你可能看到的是缩小,但这不被大众接收和也不是有效的。

    gzip可能减少了70%的响应大小,可能都达到了90%。如果你使用apache,配置gzip的模块取决于版本,apache1.3使用mod_zip,而apache2.x使用mod_deflate。

     浏览器和代理有可能会在 压缩过后 接收和发送的内容不一致。幸运的是,这些情况都被删除了。apache模块自动增加了响应头部解决了这种问题。

    服务器gzip压缩取决于文件类型。但是通常局限于压缩的内容,大部分网站gzip压缩html文档,其实也可以压缩js和css,可是大部分网站并不这么做,实际上,可以压缩任何响应的txt文本,包括xml和json数据,图像和pdf已经压缩过了,所以不包括在内,如果你试图压缩pdf和image,这不仅会消耗cpu而且可能会增加文件大小。

    gzip与许多文件类型一样,是尽量减少页面容量和提升用户体验的一种简易的方法。

    

   放置css在页面顶端

    当我们在yahoo进行重新搜索时,我们发现文档头部的级联样式加载的很快,这是因为把级联样式放在页面头部可以更加快的呈现页面。

    前端工程师关心的页面性能是快速加载,也就是要使得客服端的浏览器快速的显示出页面内容,这对于大内容的网页和带宽很低的用户来说显得尤为重要。给用户一个可视化的回应是重要的,例如导航条,能很好地搜索和存档。现在html页面就是导航条,当浏览器加载页面头部文件,导航栏,顶部logo等等,页面内容的所有这些都是可视化的响应。这改善了整个用户体验。

   放置css在页面低端是静止的,包括IE。如果页面风格发生了变化,浏览器呈现网页就必须重新加载页面元素,用户的页面就一片空白。

   所以CSS必须包含在页面的头部。白屏和无内容的flash都是致命的错误,可以解决的方法就是在页面头部包括css样式。

   放置js脚本在页面底端

    由脚本引起的问题就是阻碍了并行加载页面。http1.1规格就是建议不要在同一个域名下不要让浏览器同时处理两个以上的页面组件。如果你从的图片从多个域名存取,你就可能同时加载两个以上的组件,然而当一个script脚本在执行的时候,浏览器不会去做其他的事情,即使是在统一主机下。

   有些情况就是把脚本放在页面底端可能有麻烦,例如,使用document.write插入页面内容,就不能移动到页面的下面,这可能是作用域的问题,但多数情况下,还是有方法解决这些问题的。

    一个好的建议就是使用延迟加载,延迟属性表明不使用document.write,但关键的是还是能够让浏览器展现内容,不幸的是,firefox不支持延迟属性,在IE上,可以延迟加载,但不是期望的那么好,如果一个脚步可以被延迟加载,那么也就可以放到页面的底部,这也就使得你的页面加载的更快速。

      避免css表达式

      css表达式是动态设置css属性的一种强大或危险的方法。从IE5开始就支持了,但是在IE8已经被删除了。例如,背景图可以使用css表达式每隔1小时变化一次:

       

    background-color: expression( (new Date()).getHours()%2 ? "#B8D4FF" : "#F08A00" );
 
 

      就像这里显示的一样,表达式包含了一个JS运算,CSS属性通过js的表达式计算出来,其他浏览器并不接受这种表达方法,只有在IE上它可以用来实现,所以为了兼容其他浏览器还是要一个一致的效果。

     表达式的问题是他们可能比人们期望的计算还要多,不仅在页面加载或页面尺寸大小变化的时候要重新计算,而且当页面滚动或者用户移动鼠标的时候也要计算,增加一个计算器用来跟踪一个css表达式被计算的频率。在页面上移动鼠标一圈,可能产生10000个 计算。

      减少css表达式计算的次数方法之一就是使用一次表达式,表达式第一次计算设置css样式属性的时候有个显式的值用来替代css表达式,如果风格属性必须动态的存在页面的整个生命周期中,那么建议使用事件触发机制而不是使用css表达式,如果你使用css表达式,他们会计算成千上万次,而影响您的页面性能。

     

    让js和css文件在外部

     性能规则的许多都是处理外部组件如何被有效的管理。然而在这之前,你有个最基本的问题:js和css应该包含在页面内部还是外部?

     使用外部文件可能使页面能够快速的展现,因为jss和css被浏览器缓存了,如果css和js直接写在html页面内,那么页面每次请求的时候都要加载,这虽然减少了http请求的数,但是增加了html容积的大小,另一方面,js和css写在页面的外面可以被浏览器缓存,没有增加http请求数的情况下减少了html文档的大小。

     关键的是js和css被浏览器缓存的频率相对于html文档请求数。这虽然难于量化,但还是能够用不同的实际效果来衡量。如果访问你的站点的用户每个对话中有许多可以重新利用的css和js,那么把css和js放在页面的外部就是最好的选择。

    许多站点面对这些不知如何处理。对于这样的情况,最好的办法就是把css和js文件放在页面的外部。唯一例外的可能就是主页了,例如雅虎的首页,首页几乎没有多少展现的内容,所以把js和css直接写在首页里使用户的响应时间更快。

    对于前端页面的第一次展现的时候,技术上可以实现在http请求和浏览器缓存css,js做出平衡折中的方法,也就是在首页直接嵌入css和js,但是在页面下载的时候动态加载。之后的页面加载都会在浏览器的缓存中进行存取。

   减少DNS查询

    DNS把域名定位到IP地址,正如电话簿的姓名找到对应的电话号码,当你敲入www.yahoo.com在浏览器的地址栏的时候,DNS解析就把浏览器的地址转换成IP地址,DNS有个消耗,大概花费20-120微秒的时间查询对应IP地址的域名,浏览器直到域名被解析之后才能下载东西。

   DNS查询被缓存会有更好的性能。这个缓存可以指定在一台特殊的服务器上进行,由ISP或者本地网络中心主管,但也有缓存放在私有服务器上的,DNS信息保留在操作系统的DNS缓存上。许多浏览器有自己的缓存,和操作系统的缓存区分开来,只要浏览器保存了DNS的记录在缓存中,它就不需要向操作系统的缓存发出请求。

    IE默认缓存DNS查询30分钟,也可以指定注册表的设置DnsCacheTimeout,FF默认缓存DNS查询1分钟,默认由network.dnsCacheExpiration配置。

  当客服端的DNS缓存是空的时候,页面上的DNS查询数量是等于主机域名的数量的,这也包括了主机名使用的URL,image,js,css,flash等等,减少DNS的域名数也就是减少DNS查询。

   减少主机域名的数量也就有可能减少页面并行下载的数量,避免DNS查询消耗响应时间,但是减少并行下载时间可能增加了响应时间,我的方法就是把这些页面内容分成在至少两个主机域名上,但不要超过4个,对于 减少DNS轮询 并且 使用并行下载的 这是一个好的折中方案。

   

  压缩CSS和JS大小


  减少代码中不必要的字符,也会降低页面加载的时间,删除代码中所有的注释以及不必要的空格。js文件大小和页面加载时间是成正比的,两个广受欢迎的压缩工具是:YUI和JSmin,当然YUI也可以用来压缩CSS.

   用于源代码的优化还是不确定。不只是压缩页面容量大小那么简单,压缩很可能产生一个BUG。在美国头10名排名的网站中,压缩取得了21%的效果但是也有25%的负面影响。相对于减少源码文件的减少,js压缩显得更可靠。

   除了修改外部js和css文件,内嵌的<script>,<style>也应该修改,即使你压缩了你的js和css文件,减少他们的容积也可能带来5%的效果。随着css和js的大小不断增加和使用,也就有必要减少文件的大小。

   

  避免重定向

  重定向终止于301,302错误代码。这是HTTP头部使用301响应的例子:

       

      HTTP/1.1 301 Moved Permanently
      Location: http://example.com/newuri
      Content-Type: text/html

     浏览器自动让用户跳转到指定的Location域。在页面头部重定向的信息必须有的,响应的内容是没有的。301,302实际上没有被缓存,除非头部指定,例如使用expires或者cache-control。meta刷新标签或者js是另外重定向的方法,但是如果你非要重定向,那么使用标准的http状态代码,确保后退按钮可以使用。

     要牢记的是重定向降低了用户体验,在用户和html直接插入一个重定向延迟了页面展现的内容,只有当html文档接收到后 页面组件内容才能开始加载。

     重定向作为最浪费带宽资源的一个经常发送,但开发者却没有注意到这点,这发生在一个/斜杠在url丢掉后, 例如打开页面 http://astrology.yahoo.com/astrology 要花费30s的时间 定向到 http://astrology.yahoo.com/astrology/ (注意增加的斜杠)。这个在apache的mod_rewrite或者the DirectorySlash指令已经修正了。

    老站点转到新站点对用户来说也是个重定向。使用重定向链接到一个站点是简单的,要求更少的代码,虽然在某些时候使用重定向减少了开发的复杂度,但是它降低了用户体验,如果代码路径是在同一台服务器上,可选的解决办法就是使用alias或者mod_rewrite,如果域名变更了,那么可行的就是创建CNAME(DNS记录用来创建一个别名从一个域名指向另一个),连同使用Alias 或 mod_rewrite。


   删除重复的代码

    

   在一个页面同时包含同样的js是性能降低了. 这不是像你平常想象的那样. 美国头10个知名站点的两个都犯了这种错误. 在同一个简单的页面代码重复有两个因素增加了这种怪事的发生: 团队大小和代码数量. 当它确实发生的时候, 重复代码创建不必要的http请求和执行js降低了性能.

不必要的http请求发生在IE中, 而不是在ff中. IE, 如果外部脚本包含了两次那就不会被缓存, 在页面加载的时候产生两个http请求. 即使代码被缓存了, 当用户加载页面的时候额外的http请求还是有的.

除了产生多余的http请求外, 时间也浪费了,因为js代码执行了多次. 多余的js在ie和ff都有,尽管脚本被缓存了.

在您的模板中建立一个js管理模块是解决js重复加载的好方法. 典型的html页面包含js的方法是使用script标签.

      <script type="text/javascript" src="menu_1.0.17.js"></script>


另外一个可选的方法就是在php脚本中创建一个insertScript的函数.

      <?php insertScript("menu.js") ?>

另外防止一个脚本被重复使用多次的方法, 这种方法能用脚步来处理, 比如依赖性检测 和增加版本号到js(修改js文件的版本号)用来支持将来过期的头部 。


 

  配置Etags

     视图标签 (ETags)是一种网络服务器和客服端用来判定客服端缓存的组件是否匹配原始任一服务器的机制。  (实体即组件: images, scripts, stylesheets, 等.) ETags 用来验证比上次最后修日期更具有灵活性的实体。Etags 是一个唯一标识组件的字符串。唯一的格式约束也就是被引用的字符串。原始服务器使用Etag响应头部指定组件的Etags  :

      HTTP/1.1 200 OK
      Last-Modified: Tue, 12 Dec 2006 03:03:59 GMT
      ETag: "10c24bc-4ab-457e1c1f"
      Content-Length: 12195

然后, 如果浏览器验证了一个组件, 就用If-None-Match 头部 把etag传到原始服务器. 如果Etag匹配, 304代码返回12195 字节 减少响应  ,如下所示:

      GET /i/yahoo.gif HTTP/1.1
      Host: us.yimg.com
      If-Modified-Since: Tue, 12 Dec 2006 03:03:59 GMT
      If-None-Match: "10c24bc-4ab-457e1c1f"
      HTTP/1.1 304 Not Modified


The problem with ETags is that they typically are constructed using attributes that make them unique to a specific server hosting a site. ETags won't match when a browser gets the original component from one server and later tries to validate that component on a different server, a situation that is all too common on Web sites that use a cluster of servers to handle requests.一般来说, Apache和IIS内嵌在etag的数据 都极大的降低了 多个服务器站点有效测试成功的奇怪现象。

 Apache 1.3 and 2.x Etag格式 就是  内节点-大小-时间戳. 虽然一个文件可能 存在多个服务器的统一目录下,同样的大小,访问权限,时间等。 但是对每个服务器来说 它的内节点是不一样的 .

IIS 5.0 and 6.0 Etags有个相似的问题. IIS etags的格式是 Filetimestamp:改变数。改变数是个计数器用来跟踪IIS配置变化. It's unlikely that the ChangeNumber is the same across all IIS servers behind a web site.

The end result is ETags generated by Apache and IIS for the exact same component won't match from one server to another. If the ETags don't match, the user doesn't receive the small, fast 304 response that ETags were designed for; instead, they'll get a normal 200 response along with all the data for the component. If you host your web site on just one server, this isn't a problem. But if you have multiple servers hosting your web site, and you're using Apache or IIS with the default ETag configuration, your users are getting slower pages, your servers have a higher load, you're consuming greater bandwidth, and proxies aren't caching your content efficiently. Even if your components have a far future Expires header, a conditional GET request is still made whenever the user hits Reload or Refresh.

如果你没有利用etags提供的灵活验证模式,那去掉etag标签更好。Last-Modified  头部验证基于组件的时间戳。移除etags减少了http头部请求和响应的大小。微软的技术文章描述了怎样移除etags。 . 对 Apache, 只要简单的添加下面的代码 到apache的配置文件即可:

     FileETag none
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值