浏览器输入网址到渲染出页面流程
浏览器输入网址到渲染出页面流程
详细阅读:github - 当你在浏览器中输入 google.com 并且按下回车之后发生了什么?
输入网址
浏览器进行地址解析,将解析出的域名进行
DNS
解析url
解析:网络标准规定了URL只能是字母和数字,还有一些其它特殊符号(-_.~ ! * ‘ ( ) ; : @ & = + $ , / ? # [ ],但是有部分特殊字符需要进行编码否则会出现歧义。使用encodeURI(...)
和encodeURIComponent(...)
进行编码。使用decodeURI(...)
和decodeURIComponent(...)
进行解码。规则采用UTF-8
。请注意,
encodeURI
自身无法产生能适用于HTTP GET 或 POST 请求的URI,例如对于 XMLHTTPRequests, 因为 “&”, “+”, 和 “=” 不会被编码,然而在 GET 和 POST 请求中它们是特殊字符。然而encodeURIComponent
这个方法会对这些字符编码。DNS
解析: 先查看浏览器DNS
缓存中是否有域名对应的IP
,如果没有,则看操作系统DNS
缓存中是否有对应的IP
(例如Windows的hosts文件),依旧没有就对本地区的DNS
服务器发起请求,如果还是没有,就直接到Root Server
域名服务器请求解析。(非转发模式)一般使用
UDP
协议向DNS
服务器进行寻址。DNS查询有两种模式,转发模式和非转发模式。转发模式,第一台DNS服务器查找不到,会转发到其他DNS服务器上查找,如果其他DNS服务器上也没有就会到根服务器查找。
前端DNS优化:可以在html页面头部写入dns缓存地址
<meta http-equiv="x-dns-prefetch-control" content="on" /> <link rel="dns-prefetch" href="http://bdimg.share.baidu.com" />
通过
IP
寻址和ARP
,找到目标服务器地址。获取到
IP
后,直接通过IP
寻址找到IP
对应的服务器,然后通过ARP
协议找到服务器的MAC
地址。进行
TCP
三次握手,建立TCP
连接。- 第一次握手:主机A发送位码为SYN=1的TCP包给服务器,并且随机产生一个作为确认号(这是tcp包的一部分),主机B收到SYN码后直到A要求建立连接;
- 第二次握手:主机B收到请求后,向A发送确认号(主机A的seq+1),syn=1,seq = 随机数 的TCP包;
- 主机A收到后检查确认号是否正确,即第一次A发送的确认号是否+1了,以及位码ack是否为1,若正确,主机A会再发送确认号(主机B的seq+1),ack=1,主机B收到后确认seq值与ack=1则连接建立成功。
浏览器发送数据请求,等待服务器响应。
根据数据请求判断是否使用浏览器缓存。
如果使用浏览器强缓存,则不会对服务器进行请求,直接响应数据请求,返回浏览器缓存数据。
如果是协商缓存机制,会向服务器进行询问缓存使用结果,注意启发式缓存。
如果不使用缓存,则会向服务器请求数据。
服务器处理请求,并对请求做出响应。
浏览器收到服务器响应,得到网页代码。
渲染页面
HTML解析:HTML词法分析和语法分析
外部样式、脚本加载(async / defer)
构建DOM树(DOM tree):从上到下解析HTML文档生成DOM节点树(DOM tree),也叫内容树(content tree);
JS会阻塞DOM树的解析,但是CSS不会阻塞DOM树的解析。所以如果不得不将JS文件放在头部,可以将JS文件放在CSS文件引入之上。且JS文件中最好不要有修改样式的操作,不然会和预期结果不一致,同时也无法进行DOM操作。
构建CSSOM(CSS Object Model)树:加载解析样式生成CSSOM树;
构建渲染树(render tree):根据DOM树和CSSOM树,生成渲染树(render tree);
渲染树:按顺序展示在屏幕上的一系列矩形,这些矩形带有字体,颜色和尺寸等视觉属性。
- 浏览器从DOM树的根节点开始遍历每个可见节点。
- 对于每个可见节点,找到CSSOM树中对应的规则,并应用它们。
- 根据每个可见节点以及其对应的样式组合生成渲染树。
布局(layout):根据渲染树将节点树的每一个节点布局在屏幕上的正确位置;
绘制(painting):遍历渲染树绘制所有节点,为每一个节点适用对应的样式,这一过程是通过UI后端模块完成;
执行JavaScript:加载并执行JavaScript代码(包括内联代码或外联JavaScript文件);
回流(Reflow / 重排):当
Render Tree
中部分或全部元素的尺寸、结构、或某些属性发生改变时,浏览器重新渲染部分或全部文档的过程称为回流。回流操作:页面首次渲染、浏览器窗口大小发生改变、元素尺寸或位置发生改变、元素内容变化、元素字体大小变化、添加或删除可见的DOM元素等
回流必将引起重绘,重绘不一定会引起回流。回流比重绘代价要更高
获取
document.body.offsetHeight
等一些数据会引起浏览器重绘。重绘(Repaint):当页面中元素样式的改变并不影响它在文档流中的位置时(例如:
color
、background-color
、visibility
等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘。更多资料:基础系列-重绘与回流
HTML词法分析和语法分析,CSS解析, 合成图层、合成线程调用光栅化线程池,生成位图后浏览器进程间通信过程,显卡缓存与显示器的关系
浏览器断开连接,四次挥手。
一个http请求-响应,就会触发一次三次握手,四次挥手。
http 1.1 有相关长连接(keep-alive)设置。一个长连接会保持一段时间,重复用于发送一系列请求,节省了新建 TCP 连接握手的时间,还可以利用 TCP 的性能增强能力。当然这个连接也不会一直保留着:连接在空闲一段时间后会被关闭(服务器可以使用
Keep-Alive
协议头来指定一个最小的连接保持时间)。更多阅读:计算机网络-HTTP系列
常见的网络攻击
常见的网络攻击
注入攻击(Injection)
常见的是SQL
注入攻击。
前端传入用户输入的数据,后端不进行校验直接拼接SQL
语句进行处理,容易发生注入攻击。
SQL
注入漏洞可以让攻击者直接对网站数据库执行构造好的SQL
语句,在无需用户权限的情况下即可实现对数据的访问、修改甚至是删除。
跨域问题
高性能HTML5
浏览器缓存机制
浏览器缓存原理
浏览器向服务器首次发起请求后拿到请求结果,会根据响应报文中HTTP头的缓存标识,决定是否缓存结果。如果需要进行缓存,则将请求结果和缓存标识存入浏览器缓存中。
浏览器每次发起请求,都会在浏览器缓存中查找当前请求结果及缓存标识。
浏览器缓存策略
- 浏览器在加载资源时,向浏览器缓存中查找请求结果。如果存在请求结果,则根据缓存标识
expires
和cache-control
来判断是否命中强缓存,是则直接从缓存读取资源,不会发请求到服务器。如果不存在请求结果,则发送请求到服务器。 - 存在请求结果,但是不是强缓存或强缓存已失效,浏览器一定会发送一个请求到服务器,通过响应首部字段的
last-modified
和etag
验证资源是否命中协商缓存,如果是,服务器会将这个请求返回,但是不会返回这个资源的数据,依然是从缓存中读取资源。 - 如果前面两者都没有命中,直接从服务器加载资源。
基础系列-this和对象原型
2021年3月面试总结
webpack系列-进阶
编写一个简单的Loader
参考文档
loader api: https://webpack.docschina.org/api/loaders/
resolveLoader: https://webpack.docschina.org/configuration/resolve/#resolveloader