说一下地址栏输入 url 后发生了什么 [ 绝了 ]

1,379 阅读5分钟

前言

这个问题相信很多童鞋在面试中都遇到过,纵使没有遇到过,起码也看到过,思考过......

值得深思嘛 ? 值 ! 为什么 ? 笔者曾今就因为这个问题被 吊打 过,事情是这样的,某年某月的某一天

  • 面试官:说一下地址栏输入 url 后浏览器渲染页面的过程
  • 我:dns 域名解析 -> 发起 http,创建 tcp 链接(三次握手,四次挥手)-> 浏览器拿到返回实体 -> 渲染到页面(又扯了一下重绘和回流)
  • 面试官:完了 ?
  • 我:目前就大概就知道这些
  • 凉凉,面试官劈里啪啦的说了一堆,反正我是没听懂,还一个劲的在点头,嗯,是,对

事后回想起这个问题,才发现,涉及的东西太多了,不仅富有广度,且还有一定深度,后来我也查了一些资料,做了一些学习,当年没有写博客的习惯,如今再巩固一遍,分享给大家

首先从输入 url 开始

当在浏览器地址栏输入一个 url 时,首先会判断这个 url 是否是一个网址,如果不是一个网址,则会默认使用浏览器的搜索引擎, 将输入的字段作为搜索关键字进行搜索并查询 这里会过滤搜索关键字非法字符,转义等

那么如果是一个网址,则会把这个 url 发送给网络进程,首先会在缓存里查找这个地址, 缓存

这里说一下浏览器缓存优先级 点击查看详情-浏览器网络系列进阶

  1. 先在内存中查找
  2. 如果内存中不存在,则在硬盘中查找
  3. 如果硬盘中也没有,那么就进行网络请求
  4. 请求获取的资源再缓存到硬盘和内存

如果缓存中没有找到输入的 url 地址则会进行 url 解析,解析出要请求的服务器ip地址

url 解析 + dns 域名解析

一个 url 的组成是 协议 + 域名 + 端口 + 资源路径

  • 协议: 一般常见的是 http协议, https协议
  • 域名:其实本质就是一个 ip 地址,常用一个别名替代,看起来更语义化一些; 就类似 张三(别名),身份证号(ip) 这个样子
  • 端口:http 默认 80 , https 默认 443
  • 资源路径: 就是请求服务器下对应的资源路径 + 参数

那通过上边的结构,知道域名了,就需要进行 dns 域名解析,目的是找到域名对应的 ip 地址,ok,来了解一些 dns 域名解析

dns 域名解析

这里跟浏览器识别 url 地址有点像,也需要去看看有没有曾经解析过的缓存,这个查找缓存的过程就比较简单,递归查询,找到就结束

  1. 客户端查找
  2. 浏览器内存中查找
  3. 本地 hosts 文件中查找
  4. 本地 dns 解析的缓存中查找
  5. 本地 dns 服务器转发请求 只能出去找了

上述前四步都没有找到,那么就本地 dns 服务器转发请求了,去外部查找对应的根域,顶级域,权威域。

好了,找到对应的 ip 地址之后,就会发起 http 请求建立 tcp 链接了

tcp 三次握手

三次握手,四次挥手,这里我截了两张图,是我的另一篇文章中内容,这里就没有再写一遍 查看

image.png

tcp 四次挥手

image.png

浏览器渲染

截至到这里,已经拿到了对应资源的响应实体了,剩下的就是浏览器如何解析和渲染,网上找了张图,如下

image.png

具体解析页面步骤

  1. 浏览器通过 HTMLParser 把 HTML 解析成 DOM Tree (俗称DOM树)
  2. 浏览器通过 CSSParser 把 CSS 解析成 Style Rule Tree(俗称CSSOM树)
  3. 浏览器将 JavaScript 通过 DOM API 和 CSSOM API 将 JS 代码解析并应用到布局中,根据 DOM 树和 CSSOM 树来构造 Render Tree(Rander 树)

最终的 Rander 树就是整个页面的文档结构抽象表示,然后按要求呈现响应的结果

  • 渲染引擎

渲染引擎:主要负责取得网页的内容(HTML、XML、图像等等)、以及计算网页的显示方式,然后会输出至浏览器,浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同

  • Js引擎

JS引擎:主要负责解析和执行javascript代码来实现网页的动态效果

重绘与回流

  • 重绘:元素的样式发生改变
  • 回流:元素的大小或者位置发生了变化,触发了重新布局,导致 render tree 重新计算布局和渲染

注意,重绘不一定触发回流,但是回流一定触发重绘

优化

通过上边的两种情况,我们可以联想到,减少页面的重绘与回流就可以大大提升渲染的效率和体验性能 。所以从侧面推敲一下

减少零碎的DOM操作,尽量做到批量更新操作(不分节点还是样式属性), 避免频繁的重绘与回流,不过目前主流技术栈 Vue,React 都是虚拟 dom ,可以忽略这一点。

小小鼓励,大大成长,欢迎点赞