性能黄金法则:
只有10%-20%的最终用户响应时间花在加载html文档,其余80%-90%时间花在加载页面所需的组件(脚本,图片,样式表,flasf..)
本文的内容就是来减少那80%-90%的时间.
减少HTTP请求
通过<\map>标签,把多个URL关联到一个图片上,来减少HTTP的开销.
原理就是通过你点击的图片区域来映射你对应该区域的URL.
缺点:
原理: 把多个碎图片合在一张图片上,在通过CSS的position来获取你需要的图片.
优点:
困惑点:
有人认为合并后的图片会大于分散图片之和,因为他们觉得合并的图片含有留白.
实际上是小于为合并的,因为合并后一张图片减少了图片本身的开销(颜色,格式等).
通过data:URL的格式在页面使用图片而无需HTTP请求.
缺点:
原理: 把一个页面依赖的样式合并为一个样式,把依赖的所有脚本合并为一个脚本.
(现在的打包工具可以很方便做到这个)
使用内容发布网络(CDN)
CDN: 一组分布在不同地理位置的服务器,来更高效的向用户发布数据.
优点:
缺点:
添加expires头
理解expires:
浏览器(代理)通过使用缓存来减少HTTP的请求数量,并减少响应大小.加速页面的加载.
服务器通过expires头告知客户端可以在指定的时间内使用某个组件的副本.(超过那个时间就是无效的),直接从客户端硬盘读取数据,响应时间少.
Expires : Thu, 15 Apr 2016 20:00:00 GMT
Expires会要求服务器端时间与客户端时间严格同步,并且一旦过期,服务器需要配制新的日期.
空缓存: 用户第一次访问你的网站,即使设置了Exppires头也不会减少HTTP请求数量,因为此时浏览器的缓存是空的.
完整缓存: 如果你的所有可以缓存的组件都在缓存状态.
所以使用长久的Expires头的场景对象应该是那些不经常变化的组件:
Cache-Control:max-age = 315000000
通过Cache-Control:max-age可以指定一个组件被缓存多久,单位s。
如果同时有max-age和Expires,那么会重写Expires.
压缩组件
原理: 通过减少HTTP响应包的大小,来减少响应时间。
客户端通过HTTP请求设置Accept-Encoding来标志对哪些压缩的支持.
Accept-Encoding : gzip
服务器看到上述报头,会使用客户端的压缩方式来压缩响应.并通过Content-Encoding告知客户端.
Content-Encoding : gzip
压缩的内容: 理想的是任何响应文本(除了图片,PDF)
压缩带来的成本:
代理缓存:
问题点:
demo1
浏览器A(不支持gzip) --> 通过代理发送一个请求 --> 服务器 --> 服务器返回的响应那么就是没压缩的 --> 该响应被代理缓存并且发给浏览器A
浏览器B(支持gzip) --> 通过同一个代理发送同一个URL --> 代理会使用之前缓存的未压缩内容进行响应.这就没达到压缩的用途了
demo2
浏览器A(支持gzip) --> 通过代理发生URL --> 服务器 --> 服务器返回压缩后的响应 --> 代理缓存该响应 --> 并把响应发给客户端
浏览器B(不支持gzip) --> 通过同一代理发送同一URL --> 代理会使用之前已经缓存的压缩的响应内容进行响应 --> 就尴尬了
解决办法:在服务器的响应添加Vary头.即
Vary : Accept-Encoding
原理:就是让代理可以缓存响应的多个版本.
把样式表放在顶部
目的: 改善整体的用户体验.让浏览器逐渐显示网页内容,与用户可以形成很好的视觉沟通.
白屏的概念:
你把样式表放在文档底部,有时候页面加载缓慢你会发现页面一片空白,直到突破内容又一下子填满页面.这就是白屏.
把样式表放在文档底部出现白屏的情况有以下几种:
把样式表放在顶部注意的情况:
把脚本放在页面底部
脚本会阻塞并行下载,也就是说如果你把脚本放在非底部的其他位置,位于脚本下面的代码要等到脚本加载解析完才轮到它,这就妨碍了页面的逐渐显示原则.
避免CSS表达式
因为每当页面发生变化(大小,事件交互等),CSS表达式都会重新求值计算,这就影响了页面的性能.
使用外嵌组件(外部JS和CSS)而不是内联
使用外部组件优点:
减少DNS查找.
为什么减少DNS查找可以提升性能?
因为你在浏览器输入一个URL,需要先经过DNS查找,找到你输入的URL对应的主机的IP地址,在未找到之前,你是不可以获取的到任何服务器资源的.所以减少DNS的开销是有必要的.
DNS的查找是可以被缓存来提供查找效率.也就是说你的DNS信息会缓存在浏览器里面和操作系统里面.
TTL值: 告知客户端对记录缓存多久.
浏览器对缓存的DNS数量是有限制的.
一个持久的TCP链接就无需要DNS查找.
精简JS
避免重定向
重定向的概念:就是把用户从一个URL路由到另外一个URL.常见的重定向有301.302
为什么要避免使用重定向?
你如果使用了重定向,那么在文档下载之前会有很多的一个空白期.这对用户体验相当不友好.所以重定向会延迟页面所有东西.
移除重复的脚本
重复的脚本带来的弊端:
配制ETag(实体标签)
什么是ETag(实体标签)?
ETag: 服务器和浏览器确定缓存组件有效性的一种机制
理解浏览器缓存的工作机制:
浏览器向服务器访问一个URL,服务器返回响应中一个Expires字段.浏览器检测该字段是否有效,有效就会使用浏览器缓存中的资源,再次请求时候不会发送HTTP,其实在重用缓存时候,需要发送一个GET请求,进行检测时候有效,如果有效服务器会返回一个304 Not Modified.
服务器检测组件与客户端缓存资源是否匹配常用的方式:
最新修改时间:指的是服务器在响应中会返回一个Last-Modified响应头,告诉我们组件最后修改时间
当你再一次请求同一资源时候,浏览器在请求中会带有If-Modified-Since字段,把最新修改的日期传回到服务器,服务器把这个最新修改日期与之前的Last-Modified时间进行比较,如果匹配一致,服务器返回304,使用缓存的.
ETag是唯一标志了组件版本的字符串,必须用引号引起来.
第一次请求资源时候,服务器会返回一个资源的ETag,
当浏览器再次请求该资源时候,浏览器会通过一个组件进行验证,通过If-None-Match把ETag传到原始服务器,服务器会进行比较刚刚传过来的与之前的是否有变化,一致的话,服务器返回304.
ETag的问题点:
ETag的解决办法:
配制ETag或者移除ETag.
通过Ajax缓存
Ajax本质就是提升用户体验的.
优化Ajax请求
压缩组件