From bbf31256fb3236ee0d4c44ae7151ab3903c5a87a Mon Sep 17 00:00:00 2001 From: Omooo <869759698@qq.com> Date: Fri, 7 Jun 2019 15:14:57 +0800 Subject: [PATCH] =?UTF-8?q?finsh=20Web=20=E6=80=A7=E8=83=BD=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E6=9C=80=E4=BD=B3=E5=AE=9E=E8=B7=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 10 +- .../computer_network/Web 性能优化最佳实践.md | 130 ++++++++++++++++++ 2 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 blogs/computer_network/Web 性能优化最佳实践.md diff --git a/README.md b/README.md index c5933a9..fdbb52e 100644 --- a/README.md +++ b/README.md @@ -174,9 +174,15 @@ Android Notes [HTTP 的前世今生](https://github.com/Omooo/Android-Notes/blob/master/blogs/computer_network/HTTP%20%E7%9A%84%E5%89%8D%E4%B8%96%E4%BB%8A%E7%94%9F.md) -[HTTP/1.1](https://github.com/Omooo/Android-Notes/blob/master/blogs/computer_network/HTTP 1.1.md) +[HTTP/1.1](https://github.com/Omooo/Android-Notes/blob/master/blogs/computer_network/HTTP%201.1.md) -[HTTP/2.0](https://github.com/Omooo/Android-Notes/blob/master/blogs/computer_network/HTTP 2.0.md) +[HTTP/2.0](https://github.com/Omooo/Android-Notes/blob/master/blogs/computer_network/HTTP%202.0.md) + +[针对浏览器的优化建议](https://github.com/Omooo/Android-Notes/blob/master/blogs/computer_network/%E9%92%88%E5%AF%B9%E6%B5%8F%E8%A7%88%E5%99%A8%E7%9A%84%E4%BC%98%E5%8C%96%E5%BB%BA%E8%AE%AE.md) + +[TCP 与 UDP](https://github.com/Omooo/Android-Notes/blob/master/blogs/computer_network/TCP%20%E4%B8%8E%20UDP.md) + +[Web 性能优化最佳实践](https://github.com/Omooo/Android-Notes/blob/master/blogs/computer_network/Web%20%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5.md) #### 笔试 diff --git a/blogs/computer_network/Web 性能优化最佳实践.md b/blogs/computer_network/Web 性能优化最佳实践.md new file mode 100644 index 0000000..d35d966 --- /dev/null +++ b/blogs/computer_network/Web 性能优化最佳实践.md @@ -0,0 +1,130 @@ +--- +Web 性能优化最佳实践 +--- + +#### 目录 + +1. 前言 +2. 在客户端缓存资源 + +#### 前言 + +无论什么网络,也不管所用网络协议是什么版本,所有应用都应该致力于消除或减少不必要的网络延迟,将需要传输的数据压缩至最少。这两条标准是经典性能优化最佳实践,是其他数十条性能准则的出发点: + +1. 减少 DNS 查找 + + 每一次主机名解析都需要一次网络往返,从而增加请求的延迟时间,同时还会阻塞后续请求。 + +2. 重用 TCP 连接 + + 尽可能使用持久连接,以消除 TCP 握手和慢启动延迟。 + +3. 减少 HTTP 重定向 + + HTTP 重定向极费时间,特别是不同域名之间的重定向,更加费时;这里面既有额外的 DNS 查询、TCP 握手,还有其他延迟。最佳的重定向次数为零。 + +4. 使用 CDN(内容分发网络) + + 把数据放到离用户地理位置更近的地方,可以显著减少每次 TCP 连接的网络延迟,增大吞吐量。 + +5. 去掉不必要的资源 + +6. 在客户端缓存资源 + + 应该缓存应用资源,从而避免每次请求都发送相同的内容。 + +7. 传输压缩过的内容 + + 传输前应该压缩应用资源,把要传输的字节减至最少。 + +8. 消除不必要的请求开销 + + 减少请求的 HTTP 首部数据(比如 HTTP Cookie),节省的时间相当于几次往返的延迟时间。 + +9. 并行处理请求和响应 + + 请求和响应的排队都会导致延迟,无论是客户端还是服务端。 + +10. 针对协议版本采取优化措施 + + HTTP/1.x 支持有限的并行机制,要求打包资源、跨域分散资源,等等。相对而言,HTTP/2.0 只要建立一个连接就能实现最优性能,同时无需针对 HTTP/1.x 的那些优化方法。 + +#### 在客户端缓存资源 + +要说最快的网络请求,那就是不用发送请求就能获取资源。将之前下载过的数据缓存并维护好,就可以做到这一点。对于通过 HTTP 传输的资源,要保证首部包含适当的缓存字段: + +- Cache-Control 首部用于制定缓存时间 +- Last-Modified 和 ETag 首部提供验证机制 + +只要可能,就给每种资源都指定一个明确的缓存时间。这样客户端就可以直接使用本地副本,而不必每次都请求相同的内容。类似的,指定验证机制可以让客户端检查过期的资源是否有更新,没有更新,就没必要重新发送。 + +最后,还要注意应同时指定缓存时间和验证方法。 + +#### 压缩传输的数据 + +利用本地缓存可以让客户端避免每次请求都重复取得数据。不过,还是有一些资源是必须取得的,比如原来的资源过期了,或者有新资源,再或者资源不能缓存。对于这些资源,应该保证传输的字节数最少。因此要保证对它们进行最有效的压缩。 + +HTTP、CSS 和 JavaScript 等文本资源的大小经过 gzip 压缩平均可以减少 60~80%。而图片则需要仔细考量,比如选择最优的图片格式。 + +这里说一下 WebP 格式,它是 Google 开发的一种新的图片格式,这种格式的无损压缩和有损压缩效能都有所提升: + +- WebP 的无损压缩图片比 PNG 的小 26% +- WebP 的有损压缩图片比 JPG 的小 25%~34% +- WebP 支持无损透明压缩,但因此仅增加了 22% 的字节 + +但是,这种格式需要客户端 CPU 多花点时间解码(大约相当于处理 JPG 的 1.4 倍),但字节的节省完全可以补偿处理时间的增长。 + +#### 消除不必要的请求字节 + +HTTP 是一种无状态协议,也就是说服务器不必保存每次请求的客户端的信息。然而,很多应用又依赖于状态信息以实现会话管理、个性化、分析等功能。为了实现这些功能,HTTP 做了扩展,允许任何网站针对自身来源关联和更新 Cookie 元数据:浏览器保存数据,而在随后发送给来源的每一个请求的 Cookie 首部中自动附加这些信息。 + +上述标准并未规定 Cookie 最大不能超过多大,但实践中大多数浏览器都将其限制为 4KB。与此同时,该标准还规定每个站点针对其来源可以有多个关联的 Cookie。于是,一个来源的 Cookie 就有可能多达几十 KB。不用说,这么多元数据随请求传递,必然会给应用带来明显的性能损失: + +- 浏览器会在每个请求中自动附加关联的 Cookie 数据 +- 在 HTTP/1.x 中,包括 Cookie 在内的所有 HTTP 首部都会在不压缩的状态下传输 +- 在 HTTP/2.0 中,这些元数据经过压缩了,但开销依然不小 +- 最坏的情况下,过大的 HTTP Cookie 会超过初始的 TCP 拥塞窗口,从而导致多余的网络往返 + +应该认真对待和监控 Cookie 的大小,确保只传输最低数量的元数据,比如安全会话令牌。同时,还应该利用服务器上共享的会话缓存,从中查询缓存的元数据。更好的结果,则是完全不用 Cookie,比如在请求图片、脚本和样式表等静态资源时,浏览器绝大多数情况下不必传输特定于客户端的元数据。 + +#### 并行处理请求和响应 + +为了让应用响应速度达到最快,应该尽可能第一时间就分派所有资源请求。可是,还有一点也要考虑,那就是所有这些请求以及它们对应的响应,将会被服务器如何处理。如果我们的请求在服务器上按先来后到的顺序依次排队,那就又会导致不必要的延迟。要想实现最佳性能,就要记住以下几点: + +- 使用持久连接,从 HTTP/1.0 升级到 HTTP/1.1 +- 利用多个 HTTP/1.1 连接实现并行下载 +- 可能的情况下利用 HTTP/1.1 管道 +- 考虑升级到 HTTP/2.0 以提升性能 +- 确保服务器有足够的资源并行处理请求 + +如果不使用持久连接,则每个 HTTP 请求都要建立一个 TCP 连接。由于 TCP 握手和慢启动,多个 TCP 会造成明显的延迟。在使用 HTTP/1.1 的情况下,最好尽可能重用已有连接。如果碰上能使用 HTTP 管道的机会,不要放过。更好的选择,则是升级到 HTTP/2.0,从而获得最佳性能。 + +#### 针对 HTTP/1.1 的优化建议 + +针对 HTTP/1.x 的优化次序很重要:首先要配置服务器以最大限度的保证 TCP 和 TLS 的性能最优,然后在谨慎的选择和采用经典的应用最佳实践,之后在度量、迭代。 + +1. 利用 HTTP 管道 + + 如果你的应用可以控制客户端和服务器这两端,那么使用管道可以显著减少网络延迟。 + +2. 采用域名分区 + + 如果你的应用性能受限于默认的每来源 6 个连接,可以考虑将资源分散到多了来源。 + +3. 打包资源以减少 HTTP 请求 + + 拼接和精灵图等技巧有助于降低协议开销,又能达成类似管道的性能提升。 + +4. 嵌入小资源 + + 考虑直接在父文档中嵌入小资源,从而减少请求数量。 + +管道缺乏支持,而其他优化手段又各有各的利弊。事实上,这些优化措施如果使用不当,反倒会伤害性能。总之,要有务实的态度,通过度量来评估各种措施对性能的影响。 + +#### 针对 HTTP/2.0 的优化建议 + +HTTP 2.0 的主要目标就是提升传输性能,实现客户端与服务器间较低的延迟和较高的吞吐量。显然,在 TCP 和 TLS 之上实现最佳性能,同时消除不必要的网络延迟,从来没有如此重要过。 + +接下来,或许有点意外,那就是采用移动及其他经典的最佳做法:少发数据、削减请求,根据无线网络情况调整资源供给。不管是用什么版本的协议,减少传输的数据量和消除不必要的网络延迟,对任何应用都是最有效的优化手段。 + +最后,杜绝和忘记域名分区、文件拼接、图片精灵等不良的习惯,这些做法在 HTTP/2.0 之上完全没有必要。事实上,继续使用这些手段反而有害,可以利用 HTTP/2.0 内置的多路分发以及服务器推送等新功能。 \ No newline at end of file