构建高性能WEB之HTTP首部优化

2024-09-08 14:38

本文主要是介绍构建高性能WEB之HTTP首部优化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

0x00 前言

在讨论浏览器优化之前,首先我们先分析下从客户端发起一个HTTP请求到用户接收到响应之间,都发生了什么?知己知彼,才能百战不殆。这也是作为一个WEB开发者,为什么一定要深入学习TCP/IP等网络知识。

0x01 到底发生什么了?

当用户发起一个HTTP请求时,首先客户端将与服务端之间建立TCP连接,成功建立连接后,服务端将对请求进行处理,并对客户端做出响应,响应内容一般包括响应主体。
(此处我们仅简单说明,但真实的一次请求其中发生的事情是相当复杂的,这里贴条连接,讲得比较详细)。
从输入 URL 到页面加载完成的过程中都发生了什么事情?

建立TCP连接

为了进行可靠的数据传输,TCP在进行发送数据之前,会进行TCP三次握手,以此确定接收方能够成功收取传输的数据,而建立连接的过程,必然是要耗费系统资源,以及时间资源的。

服务端处理并响应

当服务端接收到客户端发送来的请求之后,如果请求内容是静态资源,服务端会从硬盘中取出静态资源,然后将静态资源放在响应主体中,发送给客户端。如果是动态资源,服务端首先取出资源,并通过业务逻辑操作,动态生成最终的响应主体,然后发送给客户端。

客户端渲染

客户端接受到服务端传输过来的网络资源,然后进行渲染,绘制等,最终展示给用户。

0x02 优化点在哪里?

通过简单的了解,我们了解到TCP建立连接是有资源消耗,时间消耗的,那么如果我们无需每次简历TCP连接,那是否可以提高网站的性能呢?答案是肯定的。

  • 优化点1:减少TCP连接

我们知道,在获取资源的时候,以获取速度从慢到快是:网络资源->本地硬盘资源->本地内存资源。而网络资源也分硬盘资源以及内存资源。并且网络资源的传输,也是有相当大的时延的。

  • 优化点2:对数据进行缓存
  • 优化点3:减少数据传输量

0x03 如何进行优化?

本篇文章主要说的优化点是与HTTP首部有关的优化,或者说是与浏览器端有关的优化,其它优化这里暂不赘述。

持久连接:Keep-Alive

HTTP连接设计之初是请求-响应-关闭,也就是每建立一次HTTP连接,只能进行一次资源请求,当需要在同一目标服务器上获取多个资源的时候,就需要多次建立HTTP连接,而这个多次建立连接的过程,便降低了网站的性能。

于是,出现了Connection:Keep-Alive,人称持久连接。Keep-Alive避免了建立或者说重新建立连接的过程,减少了HTTP连接。

而与此配套的有Keep-Alive:timeout=120,max=5

其中,timeout=120 是指这个TCP通道保持120S,max=5 指这个TCP通道最多接收5个HTTP请求,之后便自动关闭该连接。

修改时间:Last-ModifiedIf-Modified-Since

Last-Modified首部是服务端对客户端的HTTP响应所加的一个与缓存有关的HTTP首部,该首部标记了所请求资源在服务端的最后修改时间。类似:

Last-Modified : Fri , 12 May 2015 13:10:33 GMT

当客户端发现HTTP响应头中有Last-Modified,会对资源进行缓存,在下次请求资源时,在HTTP请求头中添加If-Modified-Since首部,首部中将会添加上次成功请求资源时响应头部的Last-Modified属性值,即:

If-Modified-Since : Fri , 12 May 2015 13:10:33 GMT

当服务端接收到的HTTP请求中,发现有If-Modified-Since头部时,会将该属性值与请求资源的最后修改时间进行比对,如果最后修改时间与该属性值一致时,服务端会返回一个304 Not Modified响应,该响应中不包括响应实体。浏览器收到304的响应后,会进行重定向,获取本地缓存资源。如果最后修改时间与该属性值不一致,则会从服务端重新获取资源,做出200响应。

版本标记:ETagIf-None-Match

ETag其实与Last-Modified是差不多的方式,但是ETag并没有选择以时间作为标记,而是对所请求文件进行某些算法来生成一串唯一的字符串,作为对某一文件的标记。当收到客户端对某一资源的请求时,服务端在响应时,添加ETag首部,如下:

ETag:W/"a627ff1c9e65d2dede2efe0dd25efb8c"

当客户端发现ETag头部时,同样会对资源进行缓存,并在下次请求时,在请求头部添加If-None-Match,如:

If-None-Match:W/"a627ff1c9e65d2dede2efe0dd25efb8c"

当服务端收到请求中含有该头部时,会使用同样的ETag生成算法对文件ETag进行计算,并与If-None-Match属性值进行比对,如果一致,则返回一个304 Not Modified响应,基本与上一种方式是一致的。

缓存时间:ExpiresCache-Control

上述两种方式中,每次请求资源时,虽然在有缓存的情况下,选择缓存进行渲染绘制,但是在这之前还是发起了一次HTTP请求,虽然并没有真实的响应实体,但是依然会造成一些资源消耗。而Expires与上述两种方式使用了不同的思路。

当服务端希望客户端浏览器对某一资源进行缓存时,为了免去客户端每次都要询问自己:我上次的缓存现在还能用吗?所以,服务端选择了放权。只去告诉浏览器,我这次给你的资源你可以用多长时间,在这个时间段内,你可以一直使用它,无需每次咨询我。而服务端就是通过Expires属性来告诉客户端浏览器可以多长时间内不需要询问服务端。如下:

Expires:Thu, 19 Nov 2015 15:00:00 GMT

当客户端在响应首部中发现该属性值时,便会将该资源缓存起来,而缓存的过期时间即是Expires中的时间。在这个时间段内,浏览器完全自主。

但是,Expires有一个不足的地方是,如果服务端时间与客户端本地时间不统一时,可能服务端让客户端可以对该资源缓存一个小时,而客户端本地时间比服务端时间快了两个小时,那就意味着,所有缓存都将不会生效。

于是有了弥补该不足的一个属性,即:Cache-Control。如果服务端在响应首部添加该属性时,客户端将直接使用该属性值来生成本地时间的缓存过期时间,这样便解决了这个问题,如下:

Cache-Control:max-age=3600

如果客户端在2015年10月01日13时00分00秒收到该响应时,便会加上3600秒也就是2015年10月01日14时00分00秒作为缓存过期时间。如果响应头部既有ExpiresCache-Control,浏览器会首选Cache-Control

0x04 结束

这里,基本上说的都是与HTTP首部有关的网站性能优化。本文主要是在对《构建高性能WEB站点. 郭欣著》中第六章浏览器缓存的学习总结笔记。这本书对于WEB站点的优化,从各个层面都做了很详尽的讲解,确实是一本很棒的书,也在这里感谢HQBOSS的推荐。

原文作者:我才是二亮
原文链接:http://www.2liang.me/archives/264

这篇关于构建高性能WEB之HTTP首部优化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1148388

相关文章

Python实现批量CSV转Excel的高性能处理方案

《Python实现批量CSV转Excel的高性能处理方案》在日常办公中,我们经常需要将CSV格式的数据转换为Excel文件,本文将介绍一个基于Python的高性能解决方案,感兴趣的小伙伴可以跟随小编一... 目录一、场景需求二、技术方案三、核心代码四、批量处理方案五、性能优化六、使用示例完整代码七、小结一、

Three.js构建一个 3D 商品展示空间完整实战项目

《Three.js构建一个3D商品展示空间完整实战项目》Three.js是一个强大的JavaScript库,专用于在Web浏览器中创建3D图形,:本文主要介绍Three.js构建一个3D商品展... 目录引言项目核心技术1. 项目架构与资源组织2. 多模型切换、交互热点绑定3. 移动端适配与帧率优化4. 可

HTTP 与 SpringBoot 参数提交与接收协议方式

《HTTP与SpringBoot参数提交与接收协议方式》HTTP参数提交方式包括URL查询、表单、JSON/XML、路径变量、头部、Cookie、GraphQL、WebSocket和SSE,依据... 目录HTTP 协议支持多种参数提交方式,主要取决于请求方法(Method)和内容类型(Content-Ty

Web服务器-Nginx-高并发问题

《Web服务器-Nginx-高并发问题》Nginx通过事件驱动、I/O多路复用和异步非阻塞技术高效处理高并发,结合动静分离和限流策略,提升性能与稳定性... 目录前言一、架构1. 原生多进程架构2. 事件驱动模型3. IO多路复用4. 异步非阻塞 I/O5. Nginx高并发配置实战二、动静分离1. 职责2

从原理到实战解析Java Stream 的并行流性能优化

《从原理到实战解析JavaStream的并行流性能优化》本文给大家介绍JavaStream的并行流性能优化:从原理到实战的全攻略,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的... 目录一、并行流的核心原理与适用场景二、性能优化的核心策略1. 合理设置并行度:打破默认阈值2. 避免装箱

C# LiteDB处理时间序列数据的高性能解决方案

《C#LiteDB处理时间序列数据的高性能解决方案》LiteDB作为.NET生态下的轻量级嵌入式NoSQL数据库,一直是时间序列处理的优选方案,本文将为大家大家简单介绍一下LiteDB处理时间序列数... 目录为什么选择LiteDB处理时间序列数据第一章:LiteDB时间序列数据模型设计1.1 核心设计原则

Python 基于http.server模块实现简单http服务的代码举例

《Python基于http.server模块实现简单http服务的代码举例》Pythonhttp.server模块通过继承BaseHTTPRequestHandler处理HTTP请求,使用Threa... 目录测试环境代码实现相关介绍模块简介类及相关函数简介参考链接测试环境win11专业版python

Python实战之SEO优化自动化工具开发指南

《Python实战之SEO优化自动化工具开发指南》在数字化营销时代,搜索引擎优化(SEO)已成为网站获取流量的重要手段,本文将带您使用Python开发一套完整的SEO自动化工具,需要的可以了解下... 目录前言项目概述技术栈选择核心模块实现1. 关键词研究模块2. 网站技术seo检测模块3. 内容优化分析模

Java实现复杂查询优化的7个技巧小结

《Java实现复杂查询优化的7个技巧小结》在Java项目中,复杂查询是开发者面临的“硬骨头”,本文将通过7个实战技巧,结合代码示例和性能对比,手把手教你如何让复杂查询变得优雅,大家可以根据需求进行选择... 目录一、复杂查询的痛点:为何你的代码“又臭又长”1.1冗余变量与中间状态1.2重复查询与性能陷阱1.

Python内存优化的实战技巧分享

《Python内存优化的实战技巧分享》Python作为一门解释型语言,虽然在开发效率上有着显著优势,但在执行效率方面往往被诟病,然而,通过合理的内存优化策略,我们可以让Python程序的运行速度提升3... 目录前言python内存管理机制引用计数机制垃圾回收机制内存泄漏的常见原因1. 循环引用2. 全局变