输入url后,浏览器到底发生了什么

97 阅读3分钟

一句话简略版

输入url后,浏览器解析地址并发送请求,将返回的页面渲染。

面试版

step1 发送网络请求

总流程

输入url-->DNS解析,得到IP地址-->TCP连接,建立数据通道-->发送http请求-->获取服务器响应-->进入页面渲染

拓展知识点

  • DNS解析
  • TCP连接三次握手
  • 服务器响应状态码
    • 404
    • 304
    • 401
  • 强缓存和协商缓存
    • 强缓存是指浏览器在本地缓存中查找资源,如果找到了缓存标识符匹配的资源,则直接使用该资源,而不会向服务器发送请求。强缓存的缓存时间是由缓存标识符中的过期时间来控制的。标识符为ETag
    • 协商缓存是指在浏览器向服务器请求资源时,服务器会根据请求头中的一些参数来判断是否命中协商缓存。如果命中,服务器会返回304状态码,并带上新的响应头通知浏览器从缓存中读取资源。协商缓存的缓存时间是由响应头中的过期时间来控制的。

step2 页面渲染

总流程

html解析为节点对象-->形成DOM-->获取css样式,会得到CSSOM-->结合为渲染树LayoutTree-->绘制paint

拓展知识点

  • 顺序问题

    • dom解析和css解析同时进行,遇到 <script> 标签时,它会停止解析并开始执行该脚本。如果脚本太大或者下载速度太慢,用户可能会看到一个部分完成的页面。因此,最好将 <script> 标签放在页面底部,以便在页面完全加载之前完成脚本的下载和执行。
    • <script>加defer和aysnc的属性。async属性告诉浏览器立即下载脚本文件,但不要等待脚本下载完成。下载完成后,浏览器会立即执行脚本。
    • defer属性告诉浏览器不要立即下载脚本文件,而是等到页面所有内容都加载完成后,再一次性将所有defer脚本下载并执行。
  • 文档可以做到部分解析吗?

    • dom可以部分解析,但是cssom不能部分解析
  • 关于卡帧

    • 主线程做的工作:解析DOM、解析CSSOM以及结合为LayoutTree,如果js动画会引起重绘和重排此时就需要重新计算布局,此时如果有js需要执行的脚本的话,会占用主线程,影响计算布局。

如何优化

  • 网络:

    • 减少HTTP请求:页面加载时,浏览器会发送HTTP请求来获取资源,减少HTTP请求可以加快页面加载速度。可以通过合并CSS、JavaScript文件、压缩文件、使用CDN等方式来减少HTTP请求。
  • 使用defer或async属性告诉浏览器可以异步加载JavaScript文件,不阻塞解析。

  • 减少重绘和回流:

    • 例如,使用fixed或absolute的position来定位产生动画的HTML元素,这样修改它们的CSS不会引起回流。还可以将DOM离线后修改,如将一个dom脱离文档流,比如display:none,再修改属性,这里只发生一次回流。 懒加载,上个模块与下个模块加载顺序
  • 解决动画卡帧
    • 使用requestAnimationFrame()把js任务分割成小块,会自动调度任务,在每帧时间完成前暂停,避免动画的卡顿
    • 使用Transform属性完成动画效果,因为transform不会调用主线程,只会调用合成器线程和栅格化线程。