网站性能提升最佳实践二

https://developer.yahoo.com/performance/rules.html?guccounter=1#csslink

  • Content
  • Server
  • Cookie
  • CSS
  • JavaScript
  • Images
  • Mobile

原文从七个方面总结网站性能提升。

本篇总结Server方面。

Use a Content Delivery Network (CDN)使用内容分发网络

用户到服务器的距离会影响响应时间,比如当我们访问美国的服务器和中国的服务器
用户80%-90%的响应时间用来下载页面上的内容
为了加速这个:

  • 不要轻易尝试将web应用改为分布式架构

  • 可以尝试使用CDN,将静态内容分散(切换到CDN是个相对简单的代码变化,将极大地提高网站速度

一个内容分发网络是分布在多地的服务器集合,可以更有效地向用户提供内容

Add Expires or Cache-Control Header添加Expires或Cache-Control头

  1. 对于静态组件,设置一个长期的Expires头,表示该请求“永不过期”
  2. 对于动态组件,使用适当的Cache-Control头,来帮助浏览器有条件的进行请求

网页被首次访问时需要大量的HTTP请求,通过使用Expires头,可以使请求过的组件可缓存,避免后续访问时的重复请求。也就是说,这个操作是对后续的请求有影响

对于性能的提升,取决你对这个网站的访问频率

Web服务器在HTTP响应中添加的Expires头告诉客户端可以将组件缓存多长时间

如果使用了长期的Expires头,当组件发生改变时,组件名应该改变(构建阶段处理:将组件版本号加到组件名中

Gzip Components压缩组件

通过压缩HTTP响应来减少响应时间

HTTP请求头中要添加

1
Accept-Encoding: gzip, deflate

服务器根据上面列出的方法之一压缩响应,并在响应头中添加下面的字段提醒客户端

1
Content-Encoding: gzip

服务器根据文件类型选择要压缩的内容,但通常非常有限

任何文本类型的响应都值得压缩

图片和PDF不应该压缩(因为已经压缩过了

压缩尽可能多的文件类型是减少页面重量page weight,加速用户体验的简单方法

Configure ETags配置实体标签

当要确定缓存的内容和服务器中的内容是否一致时,实体标签是比最后修改时间(last-modified date)更完备的机制

实体标签是唯一标识特定版本组件的字符串,唯一格式限制是要使用引号引起来

一个例子:

服务器发回响应如下

1
2
3
4
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中就是要验证的实体标签

1
2
3
4
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"

如果标签得到匹配,服务器会返回一个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. By default, both Apache and IIS embed data in the ETag that dramatically reduces the odds of the validity test succeeding on web sites with multiple servers.

Apache服务器删除ETag的方法:

  • 在配置文件添加一行

    1
    FileETag none

Flush Buffer Early尽早刷新输出缓存

flush() 函数允许将部分就绪的HTML响应发送回浏览器,以便浏览器可以在服务器忙于处理其它HTML时就开始获取组件

flushing的最佳位置是head标签之后,如下

1
2
3
4
5
  ... <!-- css, js -->
</head>
<?php flush(); ?>
<body>
... <!-- content -->

Use GET for Ajax Requests 使用GET处理Ajax请求

在使用XMLHttpRequest时,POST在浏览器中的实现分为两步:先发送头文件,再发送数据。

因此最好使用GET请求,它只使用一个TCP包就可以发送(除非有很多cookie

POST without posting any data behaves like GET.

Avoid Empty Image src 避免空src属性

两种形式的空src属性

  1. html

    1
    <img src="">
  2. js

    1
    2
    let img = new Image();
    img.src = "";

都会导致:浏览器再次向服务器发送一次请求

造成这个行为的根本原因是:在浏览器中执行URI解析的方式,浏览器会将空字符串视为一条相对URI,然后进行解析

HTML5增加了约束,src属性必须非空