摘自书《HTTP/2基础教程》
DNS查询优化
解析域名越快越好
- 限制域名的数量
- 保证低限度的解析延迟
- 主体HTML页面或响应中利用DBS预取指令。在下载并处理主体页面HTML的同时,预取指令能开始解析页面上指定的域名
<link rel="dns-prefetch" href="//ajax.googleapis.com">
优化TCP连接
开启连接是个耗时的过程
- 利用preconnect指令
<link rel="preconnect" href="/fonts.example.com" crossorigin>
- 尽早中止并响应。借助CDN
- 实施最新的TLS最佳实践来优化HTTPS
避免重定向
额外重定向增加延迟,影响用户体验
- 利用CDN代替客户端在云端实现重定向
- 同一域名使用web服务器上的rewrite规则避免重定向
- 注:通常重定向和SEO一起用于帮助短期内优化搜索结果
客户端缓存
本地缓存不需要建立网络连接,生存时间TTL指令告诉浏览器应该缓存某个资源多久
- 静态内容(如图片或带版本的数据)可以在客户端永久缓存。
- CSS/JS和个性化资源缓存时间大约是交互时间的两倍
- 其他类型资源TTL值可能有所不同,取决于你对特定资源能容忍的旧数据的极限。
可以通过HTTP首部指定cache-control及max-age,或者expires首部
网络边缘缓存
网络边缘缓存提供更快的访问速度,为网站服务基础设施分担很大一部分流量。
需要缓存的资源满足两个条件:
- 在多用户之间可共享
- 能够接受一定程度的旧数据
个人信息等不可在网络边缘缓存,重大新闻等可利用CDN提供的缓存清理purging机制处理。(一直保留,直到被通知,即永久缓存资源,收到通知才删除)
条件缓存
HTTP提供条件请求机制,节省带宽和性能。客户端以有效方式询问服务器:如果内容变了,请返回内容本身;否则请直接告诉我内容没变。
- 在请求中包含HTTP首部If-Modified-Since。仅当最新内容在指定日期指挥被更新过才返回完整内容,否则返回304并在响应首部附带新的时间戳。
- 在请求体中包含实体校验码,ETag(唯一标识所请求的资源,有服务器提供,内嵌于资源的响应首部中)
一般来说web服务器会对图片和css、js使用这些技术,但你要检查一下是否对其他可缓存资源起作用。
压缩和代码极简化
针对所有文本内容,更少字节数对应更少的请求-应答和更短的请求时间。
极简化指从哪个文本资源中剥离所有非核心内容的过程(如html页面去掉注释、空格)。
常见压缩算法包括gzip、deflate、Brotli
避免阻塞CSS/JS
绘制像素之前css已经下载完整,如果在html中定位了js,就会被请求、解析、执行。浏览器处理完此js之前会阻止其后任何资源的下载渲染。大多数时候这种阻塞导致不必要的延迟,策略如下:
- 定期校验这些资源的使用情况,不再使用的js直接去掉
- 如果js执行顺序无关紧要且必须在onload之前运行,设置async
<script async src="/js/main.js">
下载js和解析HTML并行能极大提升用户体验。慎用document.write指令
- 如果js执行顺序很重要且能承受脚本在DOM加载完之后运行,使用defer属性
<script defer src="/js/myjs.js">
- 对不影响页面初次展示的js脚本,在onload事件触发之后请求它
- 如果不想延迟主页面的onload事件,可以考虑iframe获取js,但iframe下载的js访问不了主页面上的元素。
图片优化
图片主导了多数网站
- 图片元信息(地理位置时间戳等)应该在发给客户端之前去掉,保留版权和色彩描述
- 图片过载,裁剪图片等
反模式
不适用于h2站点的做法
生成精灵(spiriting)图和资源合并/内联
HTTP/2针对特定资源的请求不是阻塞式的,很多请求可以并行处理,针对性能而言这种做法没有必要
域名拆分
h2领域比较好的办法是继续保持当前的域名拆分,但是确保这些域名共享同一张证书,并保持服务器IP和端口相同,以便从浏览器网络归并中收益,这样可以节省为单个域名连接建立的时间。
禁用Cookie的域名
h2中首部被压缩,客户端和服务器都保存首部历史避免重复传输已知信息,所以重构站点不必考虑唧哝cookie的域名