输入url渲染以及渲染原理

99 阅读3分钟

作者:Sean

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天
前言:经典面试题,输入一个 url 到浏览器地址栏中直到页面有内容展示过程中发生了什么? 高级前端必会面试题

URL 的组成

URL = 协议 + 主机 + 端口 + 路径 + 查询参数 + 锚点 seanmr.github.io:8080/20210226/in…

url1.png

解析域名

通过 DNS 解析域名的实际 IP 地址

  • 递归查找:浏览器缓存找对应 ip 地址 —> os 系统(例如 windows 系统的host文件)的 DNS 缓存找 —> 路由器的 DNS 缓存找 —> ISP(运营商)的 DNS 缓存找。如果都没有找到:
  • 迭代查找:根域名服务器 —> com 顶级域名服务器 —> 二级域名服务器

url2.png

检查缓存

  • 通过Cache-ControlExpires来检查是否命中强缓存,命中则直接取本地磁盘的 html,不需要发送请求
  • 如果没有命中强缓存,则会向服务器发起请求(先进行下一步的 TCP 连接),服务器通过ETagLast-Modify来取服务器确认返回的响应是否被更改(协商缓存),若无更改则返回状态码(304),浏览器取本地缓存
  • 若强缓存和协商缓存都没有命中则发送网络请求

建立-TCP-连接

TSL 加密

https 还需要经过 TSL 或者 SSL 加密,四次握手

服务器响应

  • 服务器可能是server也可能是cdn (内容分发网络,用来加快传输速度,主要用来存储静态文件)
  • 服务器上可能会通过nginx等设置静态资源代理,将 url 对应的 html 等静态资源返回。nginx 是常用的反向代理服务器
  • 这一阶段可能会发生服务端渲染,如果网站是博客或者其他需要 seo 友好的页面时。常见方案有:ejs, art-template。基于框架的nuxt.jsnext.js

浏览器解析与渲染

解析 html 与 css

html解析

  • 浏览器首先将接受到的字节数据(也就是 0 和 1)转换成字符串(也就是我们写的代码),
  • 然后浏览器会将这些字符串通过词法分析(标记化 tokenization)转换成标记(token,构成代码的最小单位)。例如<a>就会被打上一个标记
  • 标记化结束后,浏览器会将这些标记转为Node,这些Node根据不同Node之间的联系构建一棵DOM

css解析

  • 解析过程与html解析相似,最终递归出CSSOM
  • 避免写过于具体的 css 选择器,例如div > a > span,浏览器会从右向左查找,先找到所有 span 标签所在位置,再向上查找有没有 a 标签,符合条件再向上查找有无 div 标签,最终再给完全符合条件的标记设置样式。这样的递归过于复杂

渲染阻塞

|
  • HTML 和 CSS 解析过程中一定会阻塞渲染,所以要降低一开始渲染的文件的大小,扁平层级,优化选择器。
  • JS 解析会阻塞 DOM 构建和渲染,具体表现为解析到script标签,暂停构建DOM,开始下载 JS 文件,并解析执行。再从暂停的地方重新开始构建DOM
    • 应当将 script 标签写到 body 的最下方,等待 DOM 解析构建渲染完成,再解析执行 JS 脚本
    • script 加defer属性,表示 JS 脚本会并行下载,等待 HTML 解析完成后再执行
    • script 加async属性,表示这个 JS 脚本没有任何依赖,它的解析和执行是不会阻塞渲染的

回流与重绘

生成渲染树

  • 渲染树只会包含需要渲染的节点以及这些节点的信息,display: none的节点则不被包含在渲染树中
  • 渲染树生成后,浏览器会根据渲染树进行布局,这个过程叫做回流,在屏幕上呈现图层

断开连接

四次挥手