请求数据
URL解析 - DNS解析 - TCP三次握手建立连接通道 - 发送http请求 - 服务端处理请求 - 服务端向客户端发送http响应 - TCP四次挥手切断连接通道-页面渲染
购买服务器,得到域名
买好服务器,并上传项目后,购买域名(与服务器的ip地址映射关系),在DNS上定义域名和IP地址的对应关系,这时就可以通过url来访问了,备案
解释
当你在浏览器的地址栏中输入url按下enter的那一刻神奇的事情发生了==>浏览器对url进行解析,知道它通信协议,域名,端口号,请求路径,hash==>得到的域名通过DNS解析得到ip地址找到对应的服务器==>通过tcp的三次握手与服务器建立连接==>发送http请求,服务端处理请求,服务端给客户端发出响应==>tcp四次挥手切断tcp通道(tcp通道一般允许6~7个并发http请求)==>把请求体中的内容渲染到浏览器中
URL的解析
URL➡️通信协议,域名,端口号访问路径和hash 通信协议:
- http:超文本传输协议
- https:加密的http协议(SSL加密)
- FTP :文件传输协议(开发好的文件上传到服务器上) 域名 : 一个域名对应一个IP地址,DNS域名解析就是找到域名对应的IP,找到相应的服务器 端口号: 一个服务器中会有很多的项目,为了区分不同的项目为每个项目指定不同的端口号
- http默认端口号:80
- https默认端口号:443
- query:一般用在客户端向服务端传递参数(get请求)/前端路由组建间的数据传递
- hash:前端页面的路由/锚点定位
DNS解析
浏览器解析好了URL之后,会先在本地缓存中查找该资源是否有强缓存,如果没有强缓存 并且当前域名对应的IP地址在本地没有缓存就会查找网络DNS,找到对应的服务器 DNS查找过程: 本地查找: 浏览器中是否有该域名对应的IP地址 - hosts文件中是否存在 - 本地DNS是否存在 网络DNS查找

TCP三次握手:
客户端向服务端请求连接,服务端告知客户端可以连接,客户端告诉服务端好的,然后建立了Tcp连接通道

http请求&&响应:
客户端向服务端发送http请求,服务端处理请求后,向客户端发送响应
TCP四次挥手:
客户端发送请求后告诉服务端:发送请求了准备关闭吧 服务端回应客户端:接收到了准备关闭吧 服务端向客户端发送处理好的数据,告诉客户端:数据发过去了准备关闭吧 客户端告诉服务端:接收到了关闭吧。 最后TCP通道关闭

渲染大致的过程
浏览器拿到响应体中的内容,一开始是一个16进制编码 16进制编码==>便签字符串==>词法解析得到tokens==>生成节点==>生成Dom树

解析
每一个tab标签页都是一个进程,每个页面都会有一个GUI线程来实现页面的渲染,当从服务端得到html代码之后GUI就会解析把页面结构渲染成一个Dom树,把css渲染成 CSSOM树结合后生成render树经过布局和绘制完成页面的渲染
CSSOM的生成
当遇到link标签时浏览器就会派发一个http线程,去服务端请求,等到所有的样式都请求回来之后,会按照顺序渲染CSSOM树,遇到style标签不用发送http请求但是也要等待它前面的link回来之后,依次渲染


布局/回流&&绘制/重绘
第一次计算render tree元素的大小位置叫布局,把布局后的绘制到页面叫绘制 之后因为改变dom的结构产生的叫回流(重排),因结构或样式改变重新绘制页面的操作叫重绘
script的请求
当遇到写在script标签中的js代码时直接执行并且GUI线程不在运行,直到js代码执行完毕,遇到要发送http请求时,GUI要等待请求回来并且代码执行后再开始执行
defer
在script标签设置defer之后,http请求时不会影响GUI线程的渲染,请求回来之后不会立即执行,而是等到GUI渲染完之后执行
async
在script标签设置async之后,http请求时不会影响GUI线程的渲染,但是请求回来之后立即执行,执行时GUI停止渲染
浏览器预解析
在GUI主线程之心之前,会把页面上的src等需要http请求的先发送一波请求,并发量在6~7次,之后GUI渲染
渲染性能优化
- 使用语义化标签,尽量减少嵌套的层级(利于seo优化,提高渲染效率)
- link标签请求css在头部,css回来的早,提高页面渲染的效率,script标签放底部防止阻塞GUI渲染
- 使用position:absolute/fixed使元素脱离文档流
- 用平滑换取速度
- 抛弃传统的操作Dom,选择使用Vue/React这种数据影响视图模式
避免频繁向容器中添加Dom元素
因为回流时很消耗性能的减少dom的操作,在循环创建dom元素并放入某个容器时,不可以每次循环得到的dom都加入到容器,而是采用字符串拼接,或者把每个dom元素放入 let frg=document.createDocumentFragment()中之后一起放入容器中
let box=document.querySelector(".box")
let frg=document.createDocumentFragment()
for(let i=0;i<10;i++){
let a=document.createElement("a")
frg.appenChild(a)
}
box.appendChild(frg)
渲染队列&&读写分离
当每修改元素的属性就会把这一操作放到渲染队列中,直到代码中出现获取样式的操作或者没有代码,统一执行只回流一次,这种操作就叫读写分离
前端骨架屏
前端请求到的结果只有结构样式,服务端没有直接操作数据库把数据和页面结合返回,这样使用ajax请求就要消耗时间,所以拿到的html页面要把数据的位置使用灰框或者 loading占位
服务端骨架屏
首屏的内容是服务端渲染,把数据和页面一起返回给客户端
http优化
http1.0和http1.1
http1.0是每当有一个请求时就会通过tcp三次挥手建立一个连接通道,响应结束后就会有一个tcp四次挥手切断这个通道,这样每访问一次就建立一个通道,是很浪费性能的
http1.1是当第一次请求时会建立tcp连接通道,但是不会在请求一次后立即关闭而是在一定时间,或者请求一定数量后关闭tcp通道,这样会提高浏览器的效率 减少http请求
- 通过webpack打包压缩文件
- 图片采用雪碧图,base64,字体图标
- 使用CDN(烧钱)
- 图片懒加载
- 数据延迟加载
- 服务端使用GZIP(文件压缩60%)
DNS优化
DNS预解析,大型的项目可能会有多个服务器,DNS的解析是耗费时间的,就要先对服务器的域名预解析,存储到本地,访问的时候减少一些时间
缓存优化
资源缓存: 强缓存(服务端设定): 在第一次请求这个资源之后,会得到服务端设置的响应头cache-control/Expires ,会设置强缓存的时间,会把资源存在浏览器的内存中或者硬盘上,当下一次访问时不需要DNS解析及以后的操作-(不用发送请求,直接从本地拿到)
协商缓存 (服务端设定): 通过响应头Etag/last-motified设定,前者设置唯一标识,如果后端内容改变就改变他的值,每次前端传来的值与后端对比,相同后端返回304,不用重新渲染后端内容,如果不同返回200,和后端的新资源,重新渲染
数据缓存(客户端) 把数据存到本地存储中