浏览器加载html、css、js的顺序 - 幼儿园技术家 - 博客园

来源: 浏览器加载html、css、js的顺序 – 幼儿园技术家 – 博客园

为什么要了解浏览器加载流程?

前端性能优化、SEO、首屏渲染速度、闪烁问题、Hydration mismatch 这些常见问题,本质上都与浏览器加载顺序有关,特别是排查的时候会心态爆炸。

例如实际上用 nuxtjs3 写项目的时候,首页加载老是会出现 Hydration completed but contains mismatches.,diu查了好久,把页面渲染顺序都进行调式,最后发现不是页面问题,而是在 nuxt.config.ts 多配置了首页缓存的,导致每次两端渲染不同:

    nitro.prerender.routes: ['/']

    routeRules: {
        "/": { prerender: true },
    },

虽说不是加载流程问题,但是好歹还是能排查一些问题的,掌握的话查起来还是很快的。


浏览器加载网页的完整过程

下面是简化但准确的流程:

HTML 下载 → 解析 HTML → 下载/解析 CSS → 构建渲染树 → Layout → Paint

JavaScript 则会在关键步骤中插入“阻塞点”,它会影响解析顺序与渲染顺序。


一、浏览器加载 HTML(构建 DOM)

浏览器首先从服务器下载 HTML 文件,然后:

  • 从 上到下 解析
  • 一边读一边构建 DOM 树

在解析 HTML 的过程中,如果遇到外部资源,就会触发对应行为:

  • 浏览器会并行下载 CSS
  • 不会阻塞 HTML 解析
  • 但 CSS 解析未完成前无法渲染页面(渲染阻塞)

遇到 <script>(无 async/defr)

  • 阻塞 HTML 解析
  • 下载 JS
  • 执行 JS
  • 继续解析 HTML

也就是 普通 script 会暂停 DOM 的构建


二、CSS 加载与解析(构建 CSSOM)

CSS 文件下载后需要被解析成 CSSOM(CSS 对象模型)。

CSS 是渲染阻塞的

CSSOM 未构建完成 → 浏览器无法进行首次渲染

但 CSS 不会阻塞 HTML 的解析,只会阻塞渲染阶段。


三、DOM + CSSOM → Render Tree(渲染树)

当 DOM 和 CSSOM 都准备好后,浏览器把它们合成 Render Tree:

  • DOM 决定页面结构
  • CSS 决定页面样式

两者合成渲染树后,才可以进行 Layout & Paint。


四、Layout(布局计算)

浏览器计算每个节点的:

  • 大小
  • 位置
  • 盒模型

五、Paint(绘制)

将渲染树绘制到屏幕像素上。

此时用户才看到页面。


六、JavaScript 对加载顺序的影响

JavaScript 的三种加载方式:

1. 普通 <script>(最慢)

阻塞 HTML 解析 → 下载 JS → 执行 JS → 继续解析 HTML

2. <script defer>(推荐)

并行下载 JS
HTML 完成后按顺序执行
不阻塞解析
在 DOMContentLoaded 之前执行

3. <script async>(最快,但不稳定)

并行下载
下载完立即执行(可能打断 HTML 解析)
执行顺序无法保证

浏览器加载流程

UserJS EngineCSS ParserHTML ParserBrowserUserJS EngineCSS ParserHTML ParserBrowser下载并解析 HTML遇到 <link> 开始下载 CSS(不阻塞 HTML)解析 CSS(阻塞渲染)遇到普通 <script> 下载并执行(阻塞 HTML)DOM Tree 构建完毕CSSOM 构建完毕DOM + CSSOM → Render TreeLayout(布局计算)Paint(绘制)页面显示

最终总结(记住这 7 句话就够了)

  1. HTML 自上而下解析,构建 DOM
  2. CSS 加载不阻塞 HTML,但阻塞渲染
  3. 普通 script 会阻塞 HTML 解析
  4. async 脱离顺序执行
  5. defer 按顺序、在 HTML 完成后执行
  6. DOM + CSSOM 才能进行渲染
  7. Layout → Paint 才真正显示页面
赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏