《高性能网站建设指南》读书笔记

** 性能黄金法则 **

只有10%20%的最终用户响应时间花在了下载HTML文档上。其余的80%90%时间花在了下载页面中的所有组件上。

** 前端处理规则 **

  1. 减少HTTP请求
  1. 使用内容发布网络
  2. 添加Expires头
  3. 压缩组件
  4. 将样式表放在顶部
  5. 将脚本放在底部
  6. 避免CSS表达式
  7. 使用外部JavaScript和CSS
  8. 减少DNS查找
  9. 精简JavaScript
  10. 避免重定向
  11. 移除重复脚本
  12. 配置ETag
  13. 使Ajax可缓存

HTTP相关概念


  • HTTP请求类型:
    GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE
  • 压缩:
    浏览器使用Accept-Encoding头来声明支持压缩:Accept-Encoding:gzip,deflate
    服务器使用Content-Encoding头确认响应已被压缩:Content-Encoding:gzip
  • 条件GET请求:浏览器在缓存中保存了一个组件的副本,当If-Modified-Since头询问组件副本是否可用,服务器若返回304响应,浏览器得到一个更小更快的响应(没有响应体)。
  • Expires:Expires:Wed,05 Oct 2016 19:16:20 GMT
    Expires头明确指出浏览器是否可以使用组件副本。浏览器将过期时间和组件副本一同存入缓存,不再询问服务器组件副本是否可用。
  • Keep-Alive:浏览器和服务器均使用Connection:keep-alive头指出对Keep-Alive的支持。
    浏览器或服务器通过发出Connection:close关闭连接。
    注:在HTTP1.1中定义的管道技术普及之前,Keep-Alive依然是必要手段。对于HTTPS来说更重要,因为建立新的安全socket连接需要更多时间。

规则笔记


规则1.减少HTTP请求

技术:图片地图、CSS Sprites、内联图片和脚本、样式表的合并。

【图片地图】

图片地图(Image Map):将多个带有链接的图片合并为一张图片,通过图片地图,点击不同位置链接到不同位置。
分类:服务器端图片地图&客户端图片地图(常用)

示例代码(客户端):

<img usemap="#map1" src="/img/example.png">
<map name="map1">
    <area shape="rect" coords="0,0,31,31" href="location1" title="ToLocation1">
    <area shape="rect" coords="0,12,121,213" href="location2" title="ToLocation2">
    ……
    <area shape="rect" coords="141,0,171,31" href="locationN" title="ToLocationN">
</map>

缺点:

  1. 手工完成困难容易出错
  1. 除了矩形之外几乎无法定义其他形状
  2. 通过DHML创建的图片地图无法再IE中工作
【CSS Sprites】

即雪碧图。将多个图片合并成一张图片,通过background-position控制显示。

【内联图片】

使用data:URL模式可以在Web页面中包含图片但无需任何的HTTP请求。
常见的URl模式:http:、ftp:、file:、mailto:、smtp:、pop:、dns:、whois:、finger:、daytime:、news:、urn:。
data:URL模式格式:

data:[<mediatype>][;base64],<data>

data一般被用于内联图片,但它可以用在任何指定URL的地方。
注:不要内联公司logo。做法:CSS将内联图片作为背景,将CSS放在外部样式表中(达到浏览器缓存功能)。
经验:普通图片就不要采用内联图片了,数据量巨大,严重增大HTML文档的大小。

【合并脚本和样式表】

规则2.使用内容发布网络

  • 在多个地理位置不同的服务器上部署内容
  • 实现地理位置分离的第一步,不要尝试使用分布式架构重新设计你的应用程序
  • 使用CDN(缺点:CDN服务挂掉将直接影响应用,不可控因素;解决方法:使用多家CDN服务)
  • 测试CDN服务的效果和测试所在地理位置有关
  • 有助于完成测试的两个网站:Keynote System(www.keynote.com)和Gomez(www.gomez.com

规则3.添加Expires头

在这一日期/时间之后,响应将被认为是无效的。

  • HTTP1.1引入Cache-Control头克服Expires头限制(要求服务器客户端的始终严格同步,还需要配置维护)
Cache-Control:max-age:315360000

注:时间单位为秒

  • mod_expires Apache模块使你在使用Expires头时能够像max-age那样以相对的方式设置时间。
    注:此部分示例代码由于和MarkDown冲突会显示错误,详细内容请自行查询资料
【空缓存VS完整缓存】

使用长久的Expires头

【修订文件名】

为使用户获取更新,将组件的文件名加上版本号。更新文件时修改文件版本号将会使用户重新从服务器上获取组件。

规则4.压缩组件

减小页面大小的方法:

  1. 压缩HTTP响应包(效果最显著)
  2. 删除注释
  3. 缩短URL
  • Web客户端通过HTTP请求中的Accept-Encoding头来标识对压缩的支持
Accept-Encoding:gzip,default
  • Web服务器通过客户端列出方法中的一种来压缩响应。
  • gzip是最理想的压缩方式。
  • 需要压缩的内容:HTML文档、脚本、样式表、XML和JSON在内的任何文本响应。
  • 不应该压缩的内容:图片和PDF(浪费CPU,增加大小)
  • 压缩成本:服务器CPU开销和客户端解压缩耗费的资源
  • 检测收益是否大于开销需要考虑的因素:响应的大小,连接的带宽,客户端与服务端Internet距离
  • 根据经验,通常对大于1KB或2KB的文件进行压缩
  • mod_gzip_mininum_file_size控制着希望压缩文件的最小值,默认为500B
【代理缓存】

存在两种方式上的问题:

问题1:

不支持gzip的浏览器先访问了代理服务器,代理服务器转发请求,服务器返回未经压缩的响应包给代理服务器,代理服务器将未经压缩的响应包缓存后转发给该浏览器;
支持gzip的浏览器请求代理服务器,代理服务器发现缓存,直接将缓存的未经压缩的响应包返回给该支持gzip的浏览器。

结果:虽然支持gzip的浏览器收到的是未经压缩的响应包,未提高效率,但最终还能完成基本的请求。

问题2:

支持gizp的浏览器先访问了代理服务器,代理服务器转发请求,服务器返回经过压缩的响应包给代理服务器,代理服务器将经过压缩的响应包缓存后转发给该浏览器;
不支持gzip的浏览器请求代理服务器,代理服务器发现缓存,直接将缓存的经过压缩的响应包返回给该不支持gzip的浏览器。
结果:第二个不支持gzip的浏览器收到的是经过压缩的响应包,无法正常解析。

解决方法:在Web服务器中添加Vary头

Vary:Accept-Encoding

规则5.将样式表放在顶部

违反规则将样式表放在顶部或HEAD标签外,虽然不影响加载组件的时间,但会影响文档呈现效果,这有不同的浏览器决定(白屏或无样式内容闪烁)。

规则6.将脚本放在底部

规则7.避免CSS表达式

规则8.使用外部的JavaScript和CSS

如果要实现主页快速访问且后续网页也能较快使用组件,可以这样:

1.在主页加载完成后下载后续网页所需组件(加载后下载)
2.动态内联(利用Cookie作指示器,如果有缓存,则生成一个使用外链组件的主页,并在主页加载完成后下载后续组件;如果没有缓存,则生成一个使用内联组件的主页,同样在加载完成后下载后续组件)

规则9.减少DNS查找

当客户端的DNS缓存为空(浏览器和操作系统都是)时,DNS查找的数量与Web页面中唯一主机名的数量相等。
建议:将组件分别放到2~4个主机名下(减少主机名潜在减少了组件并行下载的数量)。

规则10.精简JavaScript

从代码中移除不必要的字符,包含注释、不必要的空白字符(空格、换行和制表符)

【混淆】

精简 + 改写函数和变量名
通常目标:增加反向工程难度
缺点:

  • 缺陷:由于混淆更加复杂,混淆过程本身很可能引入错误。
  • 维护:由于混淆会改变JavaScript符号,因此需要对任何不能改变的符号(例如API函数)进行标记,防止混淆修改它们。
  • 经过混淆的代码很难阅读。这使得在产品环境调试问题更加困难。

精简JavaScript的工具:JSMin和DojoCompressor(ShrinkSafe)

【精简CSS】

收益通常小于精简JavaScript

优化CSS:

  • 合并相同的类、移除不使用的类
  • 移除注释和空白
  • 直观优化(如缩写#606代替#660066)
  • 移除不必要字符(例如0代替0px)

规则11.避免重定向

规则12.移除重复脚本

规则13.配置ETag

ETag是唯一标识了一个组件的一个特定的字符串。

  • 唯一的格式约束是该字符串必须用引号引起来。
  • 如果你无需自定义ETag,最好简单地将其移除。

规则14.使Ajax可缓存

应具有长久的Expires头


此篇笔记是我阅读《高性能网站建设指南》这篇文章记录的笔记,写出来与大家共享。
如果需要阅读原文,请下载PDF文档:《高性能网站建设指南》

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容