前言
这个问题相信很多童鞋在面试中都遇到过,纵使没有遇到过,起码也看到过,思考过......
值得深思嘛 ? 值 ! 为什么 ? 笔者曾今就因为这个问题被 吊打
过,事情是这样的,某年某月的某一天
- 面试官:
说一下地址栏输入 url 后浏览器渲染页面的过程
- 我:
dns 域名解析 -> 发起 http,创建 tcp 链接(三次握手,四次挥手)-> 浏览器拿到返回实体 -> 渲染到页面(又扯了一下重绘和回流)
- 面试官:
完了 ?
- 我:
目前就大概就知道这些
凉凉,面试官劈里啪啦的说了一堆,反正我是没听懂,还一个劲的在点头,嗯,是,对
事后回想起这个问题,才发现,涉及的东西太多了,不仅富有广度,且还有一定深度,后来我也查了一些资料,做了一些学习,当年没有写博客的习惯,如今再巩固一遍,分享给大家
首先从输入 url 开始
当在浏览器地址栏输入一个 url 时,首先会判断这个 url 是否是一个网址,如果不是一个网址,则会默认使用浏览器的搜索引擎, 将输入的字段作为搜索关键字进行搜索并查询 这里会过滤搜索关键字非法字符,转义等
那么如果是一个网址,则会把这个 url 发送给网络进程,首先会在缓存里查找这个地址, 缓存
这里说一下浏览器缓存优先级 点击查看详情-浏览器网络系列进阶
- 先在内存中查找
- 如果内存中不存在,则在硬盘中查找
- 如果硬盘中也没有,那么就进行网络请求
- 请求获取的资源再缓存到硬盘和内存
如果缓存中没有找到输入的 url 地址则会进行 url 解析,解析出要请求的服务器ip地址
url 解析 + dns 域名解析
一个 url 的组成是 协议 + 域名 + 端口 + 资源路径
- 协议: 一般常见的是 http协议, https协议
- 域名:其实本质就是一个 ip 地址,常用一个别名替代,看起来更语义化一些; 就类似 张三(别名),身份证号(ip) 这个样子
- 端口:http 默认 80 , https 默认 443
- 资源路径: 就是请求服务器下对应的资源路径 + 参数
那通过上边的结构,知道域名了,就需要进行 dns 域名解析,目的是找到域名对应的 ip 地址,ok,来了解一些 dns 域名解析
dns 域名解析
这里跟浏览器识别 url 地址有点像,也需要去看看有没有曾经解析过的缓存,这个查找缓存的过程就比较简单,递归查询,找到就结束
- 客户端查找
- 浏览器内存中查找
- 本地 hosts 文件中查找
- 本地 dns 解析的缓存中查找
- 本地 dns 服务器转发请求
只能出去找了
上述前四步都没有找到,那么就本地 dns 服务器转发请求了,去外部查找对应的根域,顶级域,权威域。
好了,找到对应的 ip 地址之后,就会发起 http 请求建立 tcp 链接了
tcp 三次握手
三次握手,四次挥手,这里我截了两张图,是我的另一篇文章中内容,这里就没有再写一遍
查看
tcp 四次挥手
浏览器渲染
截至到这里,已经拿到了对应资源的响应实体了,剩下的就是浏览器如何解析和渲染,网上找了张图,如下
具体解析页面步骤
- 浏览器通过 HTMLParser 把 HTML 解析成 DOM Tree (俗称DOM树)
- 浏览器通过 CSSParser 把 CSS 解析成 Style Rule Tree(俗称CSSOM树)
- 浏览器将 JavaScript 通过 DOM API 和 CSSOM API 将 JS 代码解析并应用到布局中,根据 DOM 树和 CSSOM 树来构造 Render Tree(Rander 树)
最终的 Rander 树就是整个页面的文档结构抽象表示,然后按要求呈现响应的结果
- 渲染引擎
渲染引擎:主要负责取得网页的内容(HTML、XML、图像等等)、以及计算网页的显示方式,然后会输出至浏览器,浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同
- Js引擎
JS引擎:主要负责解析和执行javascript代码来实现网页的动态效果
重绘与回流
- 重绘:元素的样式发生改变
- 回流:元素的大小或者位置发生了变化,触发了重新布局,导致 render tree 重新计算布局和渲染
注意,重绘不一定触发回流,但是回流一定触发重绘
优化
通过上边的两种情况,我们可以联想到,减少页面的重绘与回流就可以大大提升渲染的效率和体验性能 。所以从侧面推敲一下
减少零碎的DOM操作,尽量做到批量更新操作(不分节点还是样式属性), 避免频繁的重绘与回流
,不过目前主流技术栈 Vue,React 都是虚拟 dom ,可以忽略这一点。
小小鼓励,大大成长,欢迎点赞