前言
hello world欢迎来到前端的新世界
😜当前文章系列专栏:前端面试
🐱👓博主在前端领域还有很多知识和技术需要掌握,正在不断努力填补技术短板。(如果出现错误,感谢大家指出)🌹
💖感谢大家支持!您的观看就是作者创作的动力
合成事件原理
为了解决跨浏览器兼容性问题,React 会将浏览器原生事件(Browser Native Event)封装为合成事件(SyntheticEvent)传入设置的事件处理器中。这里的合成事件提供了与原生事件相同的接口,不过它们屏蔽了底层浏览器的细节差异,保证了行为的一致性。另外有意思的是,React 并没有直接将事件附着到子元素上,而是以单一事件监听器的方式将所有的事件发送到顶层进行处理。这样 React 在更新 DOM 的时候就不需要考虑如何去处理附着在 DOM 上的事件监听器,最终达到优化性能的目的
- 所有的事件挂在document上,DOM 事件触发后冒泡到 document;React 找到对应的组件,造出一个合成事件出来;并按组件树模拟一遍 件冒泡。
- event不是原生的,是SyntheticEvent合成事件对象
- 和Vue事件不同,和DOM事件也不同
React 17 之前的事件冒泡流程图
所以这就造成了,在一个页面中,只能有一个版本的 React。如果有多个版本,事件就乱套了。值得一提的是,这个问题在 React 17 中得到了解决,事件委托不再挂在 document 上,而是挂在 DOM 容器上,也就是 ReactDom.Render 所调用的节点上。
React 17 后的事件冒泡流程图
那到底哪些事件会被捕获生成合成事件呢?可以从 React 的源码测试文件中一探究竟。下面的测试快照中罗列了大量的事件名,也只有在这份快照中的事件,才会被捕获生成合成事件。
// react/packages/react-dom/src/__tests__/__snapshots__/ReactTestUtils-test.js.snap Array [ "abort", "animationEnd", "animationIteration", "animationStart", "auxClick", "beforeInput", "blur", "canPlay", "canPlayThrough", "cancel", "change", "click", "close", "compositionEnd", "compositionStart", "compositionUpdate", "contextMenu", "copy", "cut", "doubleClick", "drag", "dragEnd", "dragEnter", "dragExit", "dragLeave", "dragOver", "dragStart", "drop", "durationChange", "emptied", "encrypted", "ended", "error", "focus", "gotPointerCapture", "input", "invalid", "keyDown", "keyPress", "keyUp", "load", "loadStart", "loadedData", "loadedMetadata", "lostPointerCapture", "mouseDown", "mouseEnter", "mouseLeave", "mouseMove", "mouseOut", "mouseOver", "mouseUp", "paste", "pause", "play", "playing", "pointerCancel", "pointerDown", "pointerEnter", "pointerLeave", "pointerMove", "pointerOut", "pointerOver", "pointerUp", "progress", "rateChange", "reset", "scroll", "seeked", "seeking", "select", "stalled", "submit", "suspend", "timeUpdate", "toggle", "touchCancel", "touchEnd", "touchMove", "touchStart", "transitionEnd", "volumeChange", "waiting", "wheel", ]
如果DOM上绑定了过多的事件处理函数,整个页面响应以及内存占用可能都会受到影响。React为了避免这类DOM事件滥用,同时屏蔽底层不同浏览器之间的事件系统的差异,实现了一个中间层 - SyntheticEvent
- 当用户在为onClick添加函数时,React并没有将Click绑定到DOM上面
- 而是在document处监听所有支持的事件,当事件发生并冒泡至document处时,React将事件内容封装交给中间层 SyntheticEvent (负责所有事件合成)
- 所以当事件触发的时候, 对使用统一的分发函数 dispatchEvent 将指定函数执行
为何要合成事件
- 兼容性和跨平台
- 挂在统一的document上,减少内存消耗,避免频繁解绑
- 方便事件的统一管理(事务机制)
- dispatchEvent事件机制
http1.0和http2.0和http3.0的版本之间的差异?
- HTTP 0.9
- 1991年,最最最开始的版本,功能比较少,只有一个命令GET,只支持纯文本内容,该版本已经过时。
- HTTP 1.0
- 任何格式都可以发送,这使得互联网不仅可以传输文字,还能传输图像,视频,二进制等文件
- 新增了POST和HEAD命令
- http请求回应的格式改变,除了数据部分,每次通信必须包括头信息(HTTP header),用来描述一些头信息的元数据
- 只使用 header 中的 If-Modified-Since 和 Expires 作为缓存失效的标准。
- 不支持断点续传,也就是说,每次都会传送全部的页面和数据。
- 通常每台计算机只能绑定一个 IP,所以请求消息中的 URL 并没有传递主机名(hostname)
- HTTP 1.1
- 引入了持久连接( persistent connection),即TCP连接默认不关闭,可以被多个请求复用,不用声明Connection: keep-alive。长连接的连接时长可以通过请求头中的 keep-alive 来设置
- 引入了管道机制( pipelining),即在同一个TCP连接里,客户端可以同时发送多个 请求,进一步改进了HTTP协议的效率。
- HTTP 1.1 中新增加了 E-tag,If-Unmodified-Since, If-Match, If-None-Match 等缓存控制标头来控制缓存失效。
- 支持断点续传,通过使用请求头中的 Range 来实现。
- 使用了虚拟网络,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。
- 新增方法:PUT、 PATCH、 OPTIONS、 DELETE。
- http1.x版本问题
- 传输数据的过程中所有内容都是明文的,无法验证对方身份,无法保证数据的安全性
- HTTP/1.1 版本默认允许复用TCP连接,但是在同一个TCP连接里,所有数据通信是按次序进行的,服务器通常在处理完一个回应后,才会继续去处理下一个,这样子就会造成队头阻塞。
- http/1.x 版本支持Keep-alive,用此方案来弥补创建多次连接产生的延迟,但是同样会给服务器带来压力,并且的话,对于单文件被不断请求的服务,Keep-alive会极大影响性能,因为它在文件被请求之后还保持了不必要的连接很长时间。
- HTTP 2.0
- 二进制分帧 这是一次彻底的二进制协议,头信息和数据体都是二进制,并且统称为"帧":头信息帧和数据帧。
- 头部压缩 HTTP 1.1版本会出现 User-Agent、Cookie、Accept、Server、Range 等字段可能会占用几百甚至几千字节,而 Body 却经常只有几十字节,所以导致头部偏重。HTTP 2.0 使用 HPACK 算法进行压缩。
- 多路复用 复用TCP连接,在一个连接里,客户端和浏览器都可以同时发送多个请求或回应,且不用按顺序一一对应,这样子解决了队头阻塞的问题。
- 服务器推送 允许服务器未经请求,主动向客户端发送资源,即服务器推送。
- 请求优先级 可以设置数据帧的优先级,让服务端先处理重要资源,优化用户体验。
特点 | HTTP/1.0 | HTTP/1.1 | HTTP/2 | HTTP/3 |
并发请求 | 不支持 | 支持有限 | 引入多路复用,支持更高级别并发请求 | 引入QUIC协议,通过多路复用和UDP传输支持更高级别的并发请求 |
请求头压缩 | 不支持 | 支持有限 | HPACK算法压缩 | QPACK算法压缩 |
二进制转换 | 不支持 | 不支持 | 支持 | 支持 |
服务器推送 | 不支持 | 不支持 | 支持,服务器可以主动推送资源给客户端 | 支持,服务器可以主动推送资源给客户端 |
连接复用 | 不支持 | 持久连接 | 多路复用,多个请求可以通过单个连接表并行处理 | 多路复用,多个请求可以通过单个连接表并行处理 |
安全性 | 不支持 | HTTPS,支持加密传递 | HTTPS,支持加密传递 | HTTPS,支持加密传递 |
可靠性 | 不支持 | 不支持 | 支持头部压缩,流控制和服务器推送,可靠性强 | QUIC协议,通过UDP传输提升传输的可靠性 |
开发复杂性 | 简单 | 友好 | 新概念和协议,相对复杂 | QUIC协议,相对负责 |
底层协议 | tcp | tcp | TCP和TCS的加密传递 | QUIC |
对丢包和延迟的影响力 | 恢复较慢,容易堵塞 | 恢复较快,使用流方式并行处理请求 | 恢复较快,使用流方式并行处理请求 | 恢复较快,QUIC通过UDP传输有利于降低延迟和丢包的影响 |
适用场景 | 静态Web页面和静态资源 | 大多数Web应用程序 | 复杂Web应用程序 | 更为复杂Web应用程序 |
显示详细信息
http状态码?
1xx(信息性状态码):表示请求已被接受,需要继续处理。
- 100 Continue:服务器已经收到请求的部分,客户端可以继续发送剩余部分。
- 101 Switching Protocols:服务器已经理解了客户端的请求,并将通过Upgrade消息头通知客户端采用不同的协议。
2xx(成功状态码):表示请求被成功接收、理解、接受或处理。
- 200 OK:请求成功。
- 201 Created:请求已经被实现,而且有一个新的资源已经依据请求的需要而建立。
- 204 No Content:服务器成功处理了请求,但没有返回任何内容。
3xx(重定向状态码):表示需要进行更多操作才能完成请求。
- 301 Moved Permanently:请求的资源已被永久移动到新位置。
- 302 Found:请求的资源现在临时从不同的URI响应请求。
- 304 Not Modified:自从上次请求后,请求的资源未发生更改。
4xx(客户端错误状态码):表示客户端发送的请求有误。
- 400 Bad Request:服务器无法理解请求格式。
- 403 Forbidden:服务器拒绝请求。
- 404 Not Found:请求的资源不存在。
5xx(服务器错误状态码):表示服务器无法完成明显有效的请求。
- 500 Internal Server Error:服务器遇到了一个未曾预料的状况,导致它无法完成对请求的处理。
- 503 Service Unavailable:服务器目前无法处理请求。
我们可以根据http状态码返回的code来迅速定位到我们项目中是发生了什么问题。方便我们调试程序中出现的bug
后言
创作不易,要是本文章对广大读者有那么一点点帮助 不妨三连支持一下,您的鼓励就是博主创作的动力