http1、http2、http3的区别
常用的http状态码
- 5xx:服务端出错
- 4xx:客户端出错
- 3xx:重定向
- 2xx:ok
- 1xx:请求正在处理中
OSI模型
- 物理层
- 数据链路层:各段链路的通信协议
- 网络层:基于Ip地址进行路由转发
- 传输层:建立TCP或UDP连接
- 会话层:建立app间的连接
- 表示层:对app中的数据进行编码
- 应用层:用户app里的数据
什么是TCP 和 UDP
TCP/UDP协议都是工作在传输层的协议、 目标都是在程序之间传输数据
TCP:数据完整、响应不一定及时,基于连接
UDP:数据不一定完整、响应及时,基于非连接,性能损耗少、资源占用少
TCP的三次握手和四次挥手
三次握手:建立连接的过程 (SYN包:能否建立连接 > SYN+ACK包:同意建立连接 > ACK包: 连接建立)
四次挥手:断开连接的过程(FIN包:客户端进入终止等待1状态 > ACK包:服务端关闭等待状态,客户端进入终止等待2状态 > FIN包:服务端进入最后确认状态 > ACK包:客户端进入超时等待状态)
DNS解析流程(?)
在浏览器中输入url后发生了什么
- DNS对域名进行解析
- 建立TCP连接
- 发送HTTP请求
- 服务器处理请求
- 返回响应结果
- 浏览器解析HTML
- 浏览器渲染
GET 和 POST的区别
本质区别:GET是从服务器上获得数据;POST是向服务器传递数据
- GET参数在url上可见(通过拼接url传参)、POST参数在url上不可见(通过body传参)
- GET在浏览器回退时是无害的,而POST会再次提交请求。
- GET请求会被浏览器主动缓存,而POST不会,除非手动设置。
- GET请求在URL中传送的参数是有长度限制的,而POST么有。
强制缓存和协商缓存
缓存就是浏览器对用户近期请求过的资源进行缓存,这样当用户再次请求时,就可以直接从本地加载资源,达到性能优化的目的。
强制缓存:不会在向服务端发送请求,响应头中cache-control max-age就是缓存的时间。状态码为200
协商缓存:响应头中cache-control : no-cache,会先向服务端发送请求,如果服务端资源更新,便更新缓存,可以用来解决强制缓存资源不更新的问题。
垃圾回收机制
引用计数法:垃圾回收器会记录每个变量被引用的次数,当次数为0时,就清楚变量。该方法的缺点是无法处理循环引用的状况,可能造成内存泄漏。
标记清楚法:垃圾回收器会定期扫描内存中的对象、从根对象开始遍历内存中的所有对象。对于可达对象,通过标记它们来标识它们是可达对象;对于未被标记的对象,就说明它们是不可达对象,需要被清除。该算法的优点是可以处理循环引用的情况,但在执行时间上可能会比较长,影响程序的性能。
页面(浏览器)渲染的流程
- 解析html绘制DOM树
- 解析css绘制 CSSOM Tree
- 把DOM树和CSSOM 树结合生成render Tree
- 布局
- 绘制
重绘和重排
重绘:当元素属性的改变不影响DOM Tree的结构,即不会影响浏览器的布局,只是“表象”发生变化(如background-color,visibility等),那么针对新样式对元素进行重新绘制。
重排:当Rendering Tree 中部分元素的尺寸大小、布局、隐藏等属性改变时,浏览器的布局需要调整,则需要重新渲染DOM。这个过程就叫回流。回流也叫重排(对整个页面进行重新排版)。
重排一定重绘,重绘不一定重排
何时重排
- 元素大小发生改变
- 添加新的dom元素
- 元素的位置改变
- 元素的内容改变
- 页面初始化渲染
- 浏览器窗口大小改变
- 访问一些特定的属性,如:(offsetTop、offsetLeft、offsetWidth、offsetHeight)
- 调用特定的方法:(getComputedStyle()、getBoundingClientRect())
如何减少重排、重绘
- 减少重排范围
- 避免使用Table布局
- 减少重排次数
- 避免一条一条的修改DOM的样式,可以直接修改DOM的className
- 避免把DOM结点的属性值放在一个循环里当成循环里的变量
- 使DOM脱离文档流,再作批量处理
const ele = document.getElementById('test');
ele.style.display = 'none';
// 隐藏成功,已脱离文档流,开始操作
// bababa
// bababa
// bababa
// 操作完成,可以加回文档流
ele.style.display = 'block';
- 使用document fragment在DOM Tree之外建立一个子树
const ele = document.getElementById('test');
const fragment = document.createDocumentFragment();
// 对子树 fragment操作
// bababa
// bababa
// bababa
// 添加回去
ele.appendChild(fragment);
- 将待处理元素拷贝至一个脱离文档流的节点,处理完再代替原节点
const ele = document.getElementById('test');
const cloneNode = ele.cloneNode(true);
// 处理脱离文档流的节点cloneNode
// bababa
// bababa
// bababa
// 拿cloneNode代替原节点
ele.parentNode.replaceChild(cloneNode,ele);
- 启用GPU加速( 通过transform、opacity、filter、will-change来触发CSS硬件加速)
- 将复杂的元素绝对定位或固定定位,使它脱离文档流。