《高性能网站建设指南》阅读摘抄

最近很久没有看前端相关书籍,有所生疏了。今天看到《高性能网站建设指南》,觉得还行,内容不多,不到200页,却将常见的前端提升网站性能的方法进行了罗列:

减少http请求

  1. 图片地图
    《高性能网站建设指南》阅读摘抄_第1张图片
  2. css spirits
    《高性能网站建设指南》阅读摘抄_第2张图片
  3. 内联图片:通过data:URL模式
    《高性能网站建设指南》阅读摘抄_第3张图片
  4. 合并脚本和样式表

使用内容发布网络

内容发布网络cdn: 分布于不同地理位置的服务器。

  • 优点:可缩短响应时间,备份、扩展存储能力、缓存,可缓和流量峰值压力
  • 缺点:响应时间受cdn服务提供商环境影响;无法直接控制组件服务器

cdn服务器一般用于静态内容,如图片、脚本、样式表、flash等。

添加expires头

  1. web服务器使用expires告诉web客户端可以使用当前副本,直到指定时间为止。要求服务器和客户端时间严格同步
  2. http1.1使用cache-control头来克服这一限制,使用max-age指定缓存时间。两者同时出现时,若浏览器均支持,则max-age指令会重写expires
  3. 为图片、样式表、脚本等不经常变化的组件使用expires
  4. 为了确保用户获取到最新版本,需要修改页面中的文件名

压缩组件

  1. 压缩有成本,服务器要花费额外的cpu周期完成压缩,客户端要对压缩文件进行解压缩
  2. 代理缓存压缩与未压缩版本:web服务器响应中添加vary:Accept-Encoding 区别

将样式表放在顶部

  1. ie中,将样式表放到文档底部,导致白屏的情形,其他情况承担fouc风险(firefox都是选择承担fouc风险)

    • 新窗口打开时
    • 重新加载
    • 作为主页
  2. 将css放在文档顶部,可避免白屏
  3. 一个style块可以有多个import,但是必须放在其他规则之前。
  4. import规则可能会导致白屏现象,即便把import放在文档head中也是如此。
  5. 使用import会导致下载的无序性,使用link标签将样式表放到文档的head中
  6. 无样式的内容闪烁 flash of unstyled content (fouc):已经加载的文档重会导致的
  7. 白屏与fouc: 将样式表放到文档末尾,浏览器延迟呈现,避免fouc,则会导致白屏;反之,若浏览器逐步呈现,则有fouc的风险。解决办法:遵循html规范,将css放在顶部,即文档head中
  8. 样式表在页面并不会影响下载时间,但是会影响页面呈现。

将脚本放在底部

  1. 好处:页面可以逐步呈现,也可以提高下载并行度
  2. 使用css,页面逐步呈现会被组织,直到所有样式表下载完成。(放在head中的原因)
  3. 使用脚本,对于所有位于脚本以下的内容,逐步呈现都被阻塞了。
  4. 浏览器会并行的执行http请求,但是同一主机下的数量有限,因此会发生等待。
  5. 脚本阻塞下载原因:

    -) 脚本可能使用document.write修改页面内容
    -) 无法保证按照正确的顺序执行,因此导致报错

  6. 无法将脚本移至底部的情形:使用document.write对页面进行了修改,作用域问题等。

  7. 延迟脚本defer: defer属性表明脚本不含document.write,浏览器可以继续呈现。如果一个脚本可以延迟,则可以移到页面顶部。在firefox中,即便是延迟脚本也会阻塞呈现和并行下载。

避免css表达式

ie支持expression,而其他浏览器不支持,如下:

   width:expression(document.body.clientWidth<600?"600px":"auto"); //js表达式,仅适用IE,后果CSS性能低下
   min-width:600px;//other

结论:避免适用CSS表达式

使用外部javascript和css

外部CSS/JS和内联CSS/JS的区别:

  • 外部CSS/JS可以缓存;
  • 内部CSS/JS可以减少HTTP开销,更快加载;
  • 经常访问,使用外部CSS/JS更佳;
  • 高完整缓存率,使用外部CSS/JS更佳;
  • 每个页面都使用相同的CSS/JS,则使用外部CSS/JS更佳;
  • 主页: 仅有一个页面查看,每次都是空缓存,组件重用率低 ==》内联更佳
  • 加载后下载 post-onload download: 文档onload事件1s延迟之后,确保页面呈现完毕后才会下载js/css文件
  • 动态加载技术 dynamic inlining: 利用cookie是否存在,判断是否有缓存,有cookie则存在缓存,使用外部CSS/JS,如果没有,则使用内联CSS/JS。

结论:重用度很高,使用外部CSS/JS,否则使用内部

减少dns查找

  1. DNS开销 查找一个给定服务器的IP地址要花费20~120毫秒,DNS查找完成前,浏览器不能从主机那里下载任何东西
  2. DNS缓存:ISP/局域网的特殊缓存服务器,操作系统的DNS缓存、浏览器缓存。当浏览器丢失了记录时,才会请求操作系统询问地址;
  3. 存活时间TTL:返回的DNS请求包括这个值,告诉客户端可以缓存多久。但浏览器通常忽略该值,通过keep-Alive覆盖时间限制,同时DNS记录的数量也有限制,而不管缓存记录的时间。超过了限制,早期的访问记录会被删除。客户端收到的平均TTL值一般为最大TTL值的一半,由于DNS解析器自身也拥有与DNS记录相关的TTL.
  4. IE中记录和查看dns的: ipconfig /displaydnsipconfig /flushdns
  5. 减少DNS查找与增加并行下载的平衡: 至少两个主机,不超过4个
    结论:通过使用keep-alive和较少的域名,减少dns查找

精简javascript

  1. 精简: 从代码中移除不必要的字符以减少其大小,进而改善加载时间。如:空白符(空格、换行、制表符)
  2. 混淆: 与精简一样,会移除注释和空白,同时还会改写代码。改写:函数和变量名会变成更短的字符串,代码更加精炼,更难阅读,增加反向工程的难度。
  3. 混淆的缺点:缺陷 由于混淆更加复杂,混淆过程本身很有可能引入错误;维护 混淆会改变js符号,对于不能更改的需要进行标记 调试 代码难以阅读,增加调试难度
  4. gzip压缩产生影响最大,但精简能进一步减小文件大小
  5. 精简CSS带来的节省小于JS,因为通常css注释和空白,比js少。本质的优化在于合并相同的类,移除不使用的类

避免重定向

  1. 重定向原因:网站重新设计、跟踪流量、记录广告点击、建立易于记忆的URL。 重定向会使页面变慢
  2. 浏览器会自动将用户带到location字段的url,通常301和302响应不会被缓存,除非有附加头expires或cache-control要求这么做;
  3. meta重定向 0s后重定向
  4. js重定向,将document.location设置为期望的url即可。
  5. 为确保后退按钮正确工作,最好使用3XX HTTP状态码
  6. 缺少结尾的斜线http://www.baidu.com/,很多web服务器会发送重定向,包括apache。原因为:允许自动索引,自动转到默认的index.html上。
  7. 跟踪内部流量:若同一家网站之间的流量,通过建立Refer日志来避免重定向。
  8. 跟踪出站流量:http://www.baidu.com***http%3a//en.wikipedia.org 会返回302. 使用信标 beacon,信标响应通常是1px*1px的透明图片,并在图片的url中包含要跟踪的信息(实际只需使用xmlHttpRequest readyState=2时确认已发送即可响应请求,或者使用新打开标签页或者弹出页target='_blank'即可。)
    《高性能网站建设指南》阅读摘抄_第4张图片

移除重复脚本

  • 导致脚本重复的原因: 团队大小和脚本数量
  • 重复执行,重复下载(可通过缓存解决)

配置ETag

  1. ETag: Entity Tag 实体标签,是web服务器和浏览器用于确认缓存组件的有效性的一种机制。浏览器通过返回的expires判断缓存是否新鲜;如果过期了,浏览器在重用它之前首先得检查它是否仍然有效,这称作 条件get请求。如果浏览器缓存的组件是有效的,则服务器不会返回整个组件,只会返回304。
  2. 服务器在检测缓存组件是否和原服务器组件一致时,有两种方式:比较最新修改日期(服务器响应last-modified,浏览器使用if-modified-since回传服务器进行比较,若比较一致,则返回304)、比较实体标签(http1.1中引入,唯一标识一个组件的一个版本的字符串,需要以引号引起来,服务器响应ETag, 浏览器if-none-match回传到服务器进行比较,若匹配,返回304)。
  3. etag的意义:提供了一个比最新修改时间更灵活的机制。
  4. etag的问题:对服务器集群、代理来说,etag会不匹配,降低缓存效率
  5. if-none-match比if-modified-since有更高的优先级。
  6. 即便配置了很长的expires头,当用户reload或者refresh时,仍会产生条件get请求。如果需要通过除最新修改日期之外的一些东西来验证,则etag是一种强大的方法,否则最好简单的移除(etag性能问题)。
    结论:需要配置或者直接移除etag.

使ajax可缓存

参考资料:

  1. 《高性能网站建设指南》 Steve Souders 2008年

你可能感兴趣的:(web开发)