浏览器F5 和CRTL+F5的区别
这个两个的区别主要体现在浏览器发往服务端的http的报头的区别:
场景:在第一次成功浏览一个静态资源后,即http status 为200
F5后的报头如下:
GET /qbuilder/STATIC_SERVER/c2c/face0/images/logo.png HTTP/
1.1
Host: eshop.alibaba.com
Connection: keep-alive
Cache-Control: max-age=
0
User-Agent: Mozilla/
5.0
(Windows NT
5.1
) AppleWebKit/
535.1
(KHTML, like Gecko) Chrome/
13.0
.
782.41
Safari/
535.1
Accept: text/html,application/xhtml+xml,application/xml;q=
0.9
,*/*;q=
0.8
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=
0.8
Accept-Charset: ISO-
8859
-
1
,utf-
8
;q=
0.7
,*;q=
0.3
Cookie: ali_apache_id=
121.0
.
29.198
.
05685139288455.1
; ali_beacon_id=
121.0
.
29.198
.
1308643958740.1
; cna=naeFBgnmqQECAcYdAHmYY0RP; _cn_slid_=RHDgCLa5uc; __last_loginid__=yiqunshitou; ali_apache_track=
"c_ms=1|c_mt=2|c_mid=yiqunshitou|c_lid=yiqunshitou"
; ad_prefer=
"2011/06/29 14:47:05"
; h_keys=%u4e91%u51b2; ali_apache_sid=
121.0
.
29.198
.
11811912040075.8
|
1309513855
If-None-Match:
"66831f-1478-2d41dd00"
If-Modified-Since: Tue,
28
Jun
2011
09
:
20
:
20
GMT
|
CTRL+F5后的报头如下:
GET /qbuilder/STATIC_SERVER/c2c/face0/images/logo.png HTTP/
1.1
Host: eshop.alibaba.com
Connection: keep-alive
Cache-Control: no-cache
Pragma: no-cache
User-Agent: Mozilla/
5.0
(Windows NT
5.1
) AppleWebKit/
535.1
(KHTML, like Gecko) Chrome/
13.0
.
782.41
Safari/
535.1
Accept: text/html,application/xhtml+xml,application/xml;q=
0.9
,*/*;q=
0.8
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=
0.8
Accept-Charset: ISO-
8859
-
1
,utf-
8
;q=
0.7
,*;q=
0.3
Cookie: ali_apache_id=
121.0
.
29.198
.
05685139288455.1
; ali_beacon_id=
121.0
.
29.198
.
1308643958740.1
; cna=naeFBgnmqQECAcYdAHmYY0RP; _cn_slid_=RHDgCLa5uc; __last_loginid__=yiqunshitou; ali_apache_track=
"c_ms=1|c_mt=2|c_mid=yiqunshitou|c_lid=yiqunshitou"
; ad_prefer=
"2011/06/29 14:47:05"
; h_keys=%u4e91%u51b2
|
可以看出区别的地方是:
Cache-Control: no-cache
|
表示服务器不能使用缓存的信息作为返回,no-cache 和max-age=0的区别在于no-cache 是must的规范,而且不支持HTTP1.0,需要和Pragma:no-cache联合使用。
If-None-Match:
"66831f-1478-2d41dd00"
If-Modified-Since: Tue,
28
Jun
2011
09
:
20
:
20
GMT
|
校验客户端的缓存和服务端是否一致,这是chrome自带的,根据http1.1的协议是不应该有这种东西的
实验
目的
- 加快页面响应速度
- 减少静态资源维护版本维护成本
- 服务器压力持平或降低,内存使用,cpu使用,i/o等指标,吞吐量保持一致
方案
方案1:线上方案
HTTP/
1.1
200
OK
Date: Mon,
04
Jul
2011
11
:
33
:
37
GMT
Server: Apache/
2.0
.
63
(Unix) mod_ssl/
2.0
.
63
OpenSSL/
0.9
.7a mod_AliCookie(
for
apache2.x)/
1.1
aliBeacon/
1.0
Set-Cookie: ali_apache_sid=
121.0
.
29.198
.
35232279189147.7
|
1309781017
; path=/; domain=.alibaba.com
Last-Modified: Tue,
28
Jun
2011
09
:
20
:
20
GMT
ETag:
"66831f-1478-2d41dd00"
Accept-Ranges: bytes
Content-Length:
5240
Cache-Control: max-age=
86400
Expires: Tue,
05
Jul
2011
11
:
33
:
37
GMT
Keep-Alive: timeout=
25
, max=
486
Connection: Keep-Alive
Content-Type: image/png
|
关键点:
- etag使用INode MTime Size三者生成
- 多余header:Last-Modified,Server
- 缺少压缩
方案2:YY
- 使用Last-Modified时间
- 采用gzip压缩非图片的静态资源,gzip图片可能导致压缩后的东西比原来还大,甚至浪费CPU时间
- Header server 减少内容
- 去除ETag
- no-cache
测试结果
- 页面完全下载完的时间,快
- 服务器cpu使用,低
- 服务器内存使用,低
- 服务器I/O吞吐,低
符合以上要求的为最佳方案
记录
测试环境:
OS:xp SP3
浏览器: FF5
服务器:开发机10.20.147.166
访问网页地址: http://eshop.alibaba.com/po/201105/recommend/index.html
方案1:线上方案
apache 配置:
NameVirtualHost *
<VirtualHost * >
ServerAdmin sa
@alibaba
-inc.com
ServerName eshop.alibaba.com
DocumentRoot
"/home/admin/eshop"
RewriteEngine on
RewriteRule ^/qbuilder/STATIC_SERVER/(.*)$ /home/admin/eshop/eshop/STATIC_SERVER/$
1
RewriteRule ^/po/(.*)$ /home/admin/eshop/postatic/po/$
1
RewriteRule ^/c2c/(.*)$ /home/admin/eshop/postatic/c2c/$
1
KeepAlive On
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault
"access plus 1 days"
ExpiresByType image/gif A86400
ExpiresByType image/jpeg A86400
ExpiresByType image/png A86400
</IfModule>
|
清空缓存后,
在地址栏输入网址 5次,记录每次onload时间如下:
1.
2.
3.
4.
5.
5次平均的时间为115.2ms,从途中可以看出,只有index。html进行校验,其他都是读缓存的
在上述5次访问的基础上,按F5 5次刷新页面记录如下:
1.
2.
3.
4.
5.
平均5次的访问时间为 136.6ms,从图中也可以看出,每次都是发送4个请求,去服务端校验
综合得出,平均每次的请求是 125.9ms
方案2:YY
apache 配置
FileETag None
ServerTokens Prod
<IfModule mod_deflate.c>
# Insert filter
SetOutputFilter DEFLATE
# Netscape
4
.x has some problems...
BrowserMatch ^Mozilla/
4
gzip-only-text/html
# Netscape
4.06
-
4.08
have some more problems
BrowserMatch ^Mozilla/
4
\.
0
[
678
] no-gzip
# MSIE masquerades as Netscape, but it is fine
# BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
# NOTE: Due to a bug in mod_setenvif up to Apache
2.0
.
48
# the above regex won't work. You can use the following
# workaround to get the desired effect:
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
# Don't compress images
SetEnvIfNoCase Request_URI \
\.(?:gif|jpe?g|png|bmp)$ no-gzip dont-vary
</IfModule>
<IfModule mod_headers.c>
Header set
"Cache-Control"
"max-age=0"
# Make sure proxies don't deliver the wrong content
Header append Vary User-Agent env=!dont-vary
</IfModule>
|
清空缓存后,
在地址栏输入网址 5次,记录每次onload时间如下:
1.
2.
3.
4.
5.
平均为153.4ms,从途中也可以看出,每次都是4个请求,只是http status是304。
在上述5次访问的基础上,按F5 5次刷新页面记录如下:
1.
2.
3.
4.
5.
5次平均为130.6ms
综上所述10次平均的访问时间是:142.5ms
基于以上得到的数据,我们能不能在延时和版本管理做一个权衡,也就说缓存一定的时间,这个时间短的可以接受发布的错误。
IE6重复上述测试
IE6在虚拟机上,延迟会比较严重,只对比两种方案
方案1:线上
清空缓存后,
在地址栏输入网址 5次,记录每次onload时间如下
3542
1163
1052
1128
1080
平均时间为 1593ms
在上述5次访问的基础上,按F5 5次刷新页面记录如下:
1229
1174
1161
1341
1191
平均时间1219.2ms
综上所的平均为 1406.1ms
方案2:YY
清空缓存后,
在地址栏输入网址 5次,记录每次onload时间如下
3685
1263
1215
1307
1262
平均时间为 1746.4ms
在上述5次访问的基础上,按F5 5次刷新页面记录如下:
1285
1327
1169
1270
1263
平均时间1262.8ms
综上所的平均为 1504.6ms
衍生的方案
- 使用gzip压缩所有text/*,css,js
- 减少server头
- 去除E-TAG
- 使用last-modified
- expire设置为1年
apache配置如下:
ServerTokens Prod
FileETag None<IfModule mod_deflate.c>
# Insert filter
SetOutputFilter DEFLATE
# Netscape
4
.x has some problems...
BrowserMatch ^Mozilla/
4
gzip-only-text/html
# Netscape
4.06
-
4.08
have some more problems
BrowserMatch ^Mozilla/
4
\.
0
[
678
] no-gzip
# NOTE: Due to a bug in mod_setenvif up to Apache
2.0
.
48
# the above regex won't work. You can use the following
# workaround to get the desired effect:
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
# Don't compress images
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|bmp)$ no-gzip dont-vary
</IfModule>
<IfModule mod_headers.c>
# Make sure proxies don't deliver the wrong content
Header append Vary User-Agent env=!dont-vary
</IfModule> <IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault
"access plus 1 year"
</IfModule>
|
清空缓存后,
在地址栏输入网址 5次,记录每次onload时间如下
258ms
101ms
94ms
92ms
95ms
平均时间为 128ms
在上述5次访问的基础上,按F5 5次刷新页面记录如下:
151ms
159ms
145ms
150ms
155ms
平均时间152ms
综上所的平均为 140ms
服务器压力
由于增加了压缩的环节,所以服务器压力会上升。
测试方案:
先用以下命令清空系统内存缓存
sync && echo
3
> /proc/sys/vm/drop_caches
|
然后用http_load并发1000个用户访问120s
由于我是每个1秒统计的,所以取非100的记录120条进行统计和分析
r | b | swpd | free | buff | cache | si | so | bi | bo | in | cs | us | sy | id | wa | st | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
对非图片进行压缩 | 5.075 | 0.1 | 22 | 1745.208333 | 0.991666667 | 166.5333333 | 0 | 0 | 10.93333333 | 2158.766667 | 30746.81667 | 57896.3 | 9.066666667 | 9.391666667 | 78.68333333 | 0.883333333 | 1.883333333 |
对非图片不进行压缩 | 4.975 | 0.191666667 | 22 | 1736.883333 | 0.941666667 | 169.1 | 0 | 0 | 24.1 | 2127.4 | 31372.51667 | 58729.5 | 8.775 | 9.391666667 | 78.225 | 1.741666667 | 1.808333333 |
(row1-row2)/row2 | 2.01% | -47.83% | 0 | 0.48% | 5.31% | -1.52% | 0 | 0 | -54.63% | 1.47% | -1.99% | -1.42% | 3.32% | 0 | 0.59% | -49.28% | 4.15% |
从上述对比数据可以看出,只有r(等待run的进程数),free(空闲的内存),buff(用作缓冲区的内存),cache(用作缓存的内存),us(用户级别的进程cpu占用率),bo(发送到I/O设备的block),id(cpu idle),st(被虚拟机抢夺的时间)等指标上升外,其他指标均有所下降。
其中BO的上升是因为处理的请求更多了。
这也说明gzip压缩虽然给cpu带来的了负担,大约在3%左右,但是却带来了很大的流量节省。
总结
所以第二种方案比第一种方案延时 16.6 ms ,但是第二种方案的好处在于开发不用记录版本号。
从index.html看出,文件大小从2.4KB减少到1018B,减少了59%的单个文件传输量,所以对静态资源的压缩势在必行
由于静态资源分web的静态资源和portal的静态资源,而两种业务场景不一致,所以需要分开对待。
为什么不使用ETAG
apache的ETAG只支持INODE,MTime和Size组合生成。
由于inode会暴露文件在机器上的存储节点,容易造成安全隐患
而且集群的服务器,inode势必会不一样。
web静态资源
需要修改的点:
- 对javascript,text/*和css进行gzip压缩
- 去除ETAG,减少server内容
- 增加expired值到一年期
开发的时候如修改静态资源则需要增加版本号
portal静态资源
因此静态资源需要优化的地方:
- 对text/*,javascript 和 css类型的请求进行gzip压缩
- 增加last-modified
- 去除ETAG,减少server
- cache-control设为no-cache
不过193上不能加载deflate这个模块,可能是编译问题,线上还没测试过。