HTTP网络通信及优化
一、产品性能优化方案
- HTTP网络层优化
- 代码编译层优化 webpack
- 代码运行层优化 html/css+ javascript+ue+ react
- 安全优化xss+csrf
- 数据埋点及性能监控
CRP( Critical Rendering Path)关键渲染路径
二、页面访问过程
从输入URL带看到页面,中间经历的环节
- URL解析:把地址的域名转成IP;
- 缓存检测:
- DNS解析:通过DNS domain name system,通过IP查找对应的服务器
- TCP三次握手:建立客户端和服务器之间的网络连接
- 数据传输,基于传输协议
- TCP四次挥手
客户端:所有可以向服务器发送请求的一端都是客户端
服务器端:所有可以接受客户端的请求,并且给其响应一些内容的都是服务器
1、URL解析
1.1 区分
URI 统一资源标识符,URL和URN是URI的子集
URL 统一资源定位符,根据这个地址能找到对应的资源
URN 统一资源命名符,一般指国际上通用的一些名字
1.2 URI组成
URI包括URL和URN
URL组成部分:协议 域名 端口 路径 问号传参 或者哈希值
以username:password@www.baidu.com:443/index.html?…为例
协议
协议包括http、https、ftp... 它是客户端和服务器端用来传输信息的方式“快递小哥”
HTTP:最常用的超文本传输协议 HTTP1.0/1.1/2,0
Https:HTTP+SSL(TSL)比HTTP更加的安全 因为要经过ssl加密「支付类网站都需要使用https」
FTP:文件上的上传下载(我们把本地内容部署到服务器,或者从服务器拉去内容FTP工具)
域名
购买服务器后,一般都有一个外网IP地址,基于这个IP地址可以找到服务器;但是没有人可以记得住这个IP,所以我们要设置一个让别人好记忆的名字,这个名字就是“域名”
外网IP:供外部访问
内网IP:局域网访问
移动端测试:手机端和电脑端连接到同一个局域网下,首先保证PC端使用本机的局域网IP可以正常访问项目, 这样在手机端浏览器中输入相同的地址,也可以访问到这个项目...{可能需要关闭电脑的防火墙}
- 顶级域名:qq.com「需要买的」
- 一级域名:www.qq.com
- 二级域名:sports.qq.com
- 三级域名:kbs.sports.qq.com
- ...
- com/cn/org/edu/gov/net/vip...
端口号
端口号:区分同一台服务器上的不同项目的
取值范围:0~65535
默认端口号:浏览器会根据输入的协议,给与默认端口号「前提是自己没有指定
Http->80 Https->443 FTP->21
哈希值
哈希值:HASH
作用:锚点定位 hash路由
URL重写
item.jd.com/detail.jsp?… 是动态网址,页面中的内容是无法被搜索引擎收录的(不利于SEO优化)
动态网址 静态化[item.jd.com/10001222332…> URL重写
前后端开发不分离,页面基于服务器渲染,并且想做SEO的优化
2、浏览器缓存
缓存一般指的都是静态资源文件的缓存,这个一般是客户端和服务器端根据一些协商的规则,自动去完成的缓存策略「不用我们自己编写啥代码去处理」。缓存信息存在响应头中
2.1 缓存位置
Memory Cache:内存缓存「一般用于,页面没有关闭,只是刷新」
Disk cache:硬盘缓存「页面关闭后重新打开」
打开网页:查找 disk cache中是否有匹配,如有则使用,如没有则发送网络请求
普通刷新(F5):因TAB没关闭,因此 memory cache是可用的,会被优先使用,其次才是 disk cache
强制刷新(ctr+F5):浏览器不使用缓存,因此发送的请求头部均带有 Cache-contro: no-cache,服务器直接返回200和最新内容
2.2 缓存检查
- 先检查是否存在强缓存,如果存在则使用强缓存信息;如果不存在则再检测协商缓存,如果协商缓存生效,则使用协商缓存信息,如果不生效,则从服务器重新拉取资源信息...
- 但是两种缓存针对的都是资源文件「html、css、js、image...」,而基于ajax等获取数据,不存在这些所谓的强缓存和协商缓存!
2.3 缓存类型
强缓存 Expires http1.0 / Cache-Control HTTP1.1
如果获取的是强缓存中的信息,HTTP状态码也是200
如果是从服务器成功从新获取,HTTP状态码也是200
强缓存不适合于静态页面的缓存
原因:如果页面都缓存以后服务器更新了产品,我们访问也是走的缓存数据,这样看不到最新的内容了
协商缓存 Last-Modified「HTTP1.0」/ ETag「HTTP1.1」
检测缓存->先看是否存在强缓存「强缓存存在走强缓存」>强缓存不存在,再看是否有协商缓存「协商存在,还是走缓存」->协商也不存在,则直接从服务器获取最新的内容->缓存起来
3、DNS解析
-
递归查询
-
迭代查询
每一次DNS解析时间预计在20~120毫秒
-
减少DNS解析次数(一个网站中访问的资源尽可能在一个服务器上)
-
大型项目中,我们往往是分开服务器部署
-
web服务器:处理资源文件「例如:htmU/css/js」的请求
-
图片服务器:处理图片等富媒体资源
-
数据服务器:处理API接口请求
-
第三方服务器:获取第三方的一些数据
-
-
===》充分利用服务器的资源,提高资源服务器的处理和并发
提高http的并发数(同一个服务器最多允许5~7个并发数)
-
加大DNS解析的次数「不好的」
-
DNS预获取(dns-perfetch)
利用页面渲染的异步性,在渲染页面的过程中,同时去做DNS解析「解析的结果缓存下来」,后期渲染过程中,再次遇到对应域名的资源请求,直接获取缓存的解析记录即可
4、TCP
- TCP网络通信:更加稳定可靠「三次握手&四次挥手」,但是也会慢
- UDP网络通信:虽然建立通道比较快,但是不稳定,信息传输过程中可能会丢失信息
5、数据传输
http事物:一个完整的请求和响应
http报文:客户端和服务器端所有通信的信息统称为HTTP报文「谷歌浏览器控制台->NetWork中都可以看到」
起始行:请求起始行、响应起始行
首部(头):请求头、响应头「含:自定义的请求/响应头」
主体:请求主体、响应主体
5.1 HTML页面基本上是不做强缓存的,为啥?
-
一个页面的渲染都是从HTML开始的,在渲染HTML代码的时候,再去发送其它资源(例如:CSS/JS/图片...)的请求
-
一但HTML都做了强缓存,完了,接下来有效期内,除了CTRL+F5刷新处理,只要访问这个页面,用的都是本地缓存的内容,即使人家服务器端已经把内容更新了,你也拿不到...
5.2 如何保证其他资源在服务器更新后,即使本地有对应的强缓存信息,我们也能及时更新呢?
- 请求文件后面设置时间戳
第一次请求:index.html
<link href='css/index.css?20210526181400'> 时间戳一般放文件最后一次“修改”的时间
...
缓存了:index.css?20210526181400
没有任何文件更改
第二次请求:index.html
<link href='css/index.css?20210526181400'>
...
获取缓存信息
程序员,更新了index.css中的代码,同时需要在index.html中把请求资源的时间戳改了
第三次请求:index.html
<link href='css/index.css?20210528180000'>
...
因为时间戳和上述的不同的,所以不走本地缓存,而是重新从服务器获取
- 文件的名字根据内容更改后,设置不同的HASH名
第一次请求:index.html
<link href='css/adasds433fhghj3w.css'>
缓存:adasds433fhghj3w.css
后期程序猿修改了CSS,会生成一个新的文件名 klklkewacz5565ssds.css
第二次请求:index.html
<link href='css/klklkewacz5565ssds.css'>
三、数据缓存
本地存储: cookie/ localstorage/ sessionstorage
- cookie:存储内容很少4KB、 cookie信息自己会默认在客户端和服务器端传来传去「内容信息多会影响前后端通信的 速度」、不稳定「基于安全卫士等可以把其清除掉」、用户可以禁用 cookie
- localstorage:存储5MB、持久保存、稳定、和服务器也没关系
- sessionstorage:页面关闭则消失
- vuex+ redux:类似于全局变量,页面刷新就没有了
四、前后端分离与不分离开发的优缺点
五、编码问题
处理:中文、特殊符号....
- encodeURL/decodeURL:对整个URL编码,编码的是空格和中文
- encodeURIComponent/ decodeURI Component:只编码问号传递的参数值{它的编码规则比较多,类似于://这样的特殊字符也会编码}
- escape/ unesecape:也可以实现编码解码,但是只能客户端不同页面之间自己用,因为很多后台都不支持这个API「一般只用于客户端信息传输,例如: cookie」
六、哈希值
#
开头- 不会引起页面的刷新
- location.hash()
- window.onhashchange=function(){}监听哈希值变化
//用哈希值实现选项卡
window.onhashchange=function(){
let str=location.hash;
switch(str){
}
}
七、TCP三握四挥
应答模式 前端问,后端答
- 前端问 后端能否听到我说话?
- 后端答应, 后端问你能听到我不
- 前端:能
数据传递
- 前端要求断开,前端要的内容已经说完
- 后端告诉前端好的,内容接着传
- 后端告诉前端传完了 可以关闭
- 前端说关闭了
-
seq序号,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记
-
ack确认序号,只有ACK标志位为1时,确认序号字段才有效,ack=seq+1
-
标志位
- ACK:确认序号有效
- RST:重置连接
- SYN:发起一个新连接
- FIN:释放一个连接
- ……
转载自:https://juejin.cn/post/7179151597597884477