沐游虞笔记
  • 前端面试题

    • HTML面试题汇总(无答案)
    • HTML面试题汇总
    • CSS 面试题汇总(无答案)
    • CSS 面试题汇总
    • javascript 面试题汇总(无答案)
    • javascript 面试题汇总
    • promise 面试题(无答案)
    • promise 面试题
    • 浏览器面试题汇总(无答案)
    • 浏览器面试题汇总
    • 网络面试题汇总(无答案)
    • 网络面试题汇总
    • 工程化面试题汇总(无答案)
    • 工程化面试题汇总
    • VUE面试题汇总(无答案)
    • VUE面试题汇总
  • 直播课文件

    • 静态页面学习指导
    • 属性的计算过程
    • 层叠继承规则总结
    • BFC
    • JS基础知识回顾
    • DOM 事件的传播机制
    • DOM 事件的注册和移除
    • 阻止事件默认行为
    • 基础领航考试题
    • 基础领航考试题(答案)
    • 2024前端发展
    • JS核心概念学习指导
    • 第三方库与工程化学习指导
    • Vue入门学习指导
    • vue进阶学习指导
    • 前端性能优化
  • 笔面试环节知识讲解

    • 目录
    • 图像处理
    • 图像处理(面试)
    • Webpack构建优化
    • Webpack构建优化(面试)
    • TTS性能优化
    • TTS性能优化(面试)
    • 实时协作
    • 实时协作(面试)
    • 网页复制图片到剪贴板
    • 网页复制图片到剪贴板(面试)
    • vite插件
    • vite插件(面试)
    • 表单数据同步与保持
    • 表单数据同步与保持(面试)
    • 优化虚拟列表
    • 优化虚拟列表(面试)
    • 微前端解决巨石应用
    • 微前端解决巨石应用(面试)
    • DNS解析与优化
    • DNS解析与优化(面试)
    • 前端监控
    • 前端监控(面试)
    • 12.跨标签页通信
    • 12.跨标签页通信(面试)
    • 13.Vite相关优化
    • 13.Vite相关优化(面试)
    • 14.计时器节流问题
    • 14.计时器节流问题(面试)
    • 15.多文件预览支持
    • 15.多文件预览支持(面试)
    • 16.defer优化白屏时间
    • 16.defer优化白屏时间(面试)
  • Vue3整体变化
  • Vue2响应式回顾
  • Vue3响应式变化
  • nextTick实现原理
  • 两道代码题
  • Vue运行机制
  • 渲染器核心功能
  • 事件绑定与更新
  • computed面试题
  • watch面试题
  • 图解双端diff
  • 图解快速dff
  • 最长递增子序列
  • 模板编译器
  • 模板编译提升
  • 组件name作用
  • 路由传参方式
  • 基础篇

    • 序章React介绍
    • JSX基础语法
    • React基本介绍
    • 表单
    • 生命周期
    • 组件与事件绑定
    • 组件状态与数据传递
    • Hooks
    • React--redux介绍
    • React-router介绍
  • 就业篇

    • 属性默认值和类型验证
    • 高阶组件
    • Ref
    • Context
    • Render Props
    • Portals
    • 错误边界
    • 组件渲染性能优化
    • 前端框架的理解
    • Reacti和Vue描述页面的区别
    • 前端框架的分类
    • 虚拟DoM
    • React整体架构
    • React渲染流程
    • Fiber双缓冲
    • MessageChannel
    • Scheduleri调度普通任务
    • Scheduleri调度延时任务
    • 最小堆
    • React中的位运算
    • beginWork工作流程
    • completeWork工作流程
    • 图解diff算法
    • commit工作流程
    • lane模型
    • React中的事件
    • Hooks原理
    • useStateuseReducer.
    • effect相关hook
    • useCallbackuseMemo
    • useRef
    • Update
    • 性能优化策略之eagerState
    • 性能优化策略之bailout
    • bailoutContextAPl
    • 性能优化对日常开发启示
  • 前端监控概述
  • 错误监控
  • 数据上报
  • 页面性能监控
  • 用户行为收集与埋点
  • CSS3手册
  • HTML5手册
  • JavaScript语言提升

    • es补充
    • 事件循环
    • promise基础
    • Promise的链式调用
    • Promise的静态方法
    • async和await
    • Promise相关面试题
  • 网络

    • 客户端与服务器
    • 关于 Apifox 的使用
  • git文档
  • 工程化

    • CommonJS
    • ES module
    • npm文档(包管理)
    • Lass笔记
    • webpack工具
  • canvas详解
  • uinapp笔记
  • 自动化测试
  • oauth2令牌

    • 认识Oauth2
    • 三方应用实现github授权
    • 微信三方应用登录实现
    • 支付宝沙箱支付功能
  • 前端面试题

    • HTML面试题汇总(无答案)
    • HTML面试题汇总
    • CSS 面试题汇总(无答案)
    • CSS 面试题汇总
    • javascript 面试题汇总(无答案)
    • javascript 面试题汇总
    • promise 面试题(无答案)
    • promise 面试题
    • 浏览器面试题汇总(无答案)
    • 浏览器面试题汇总
    • 网络面试题汇总(无答案)
    • 网络面试题汇总
    • 工程化面试题汇总(无答案)
    • 工程化面试题汇总
    • VUE面试题汇总(无答案)
    • VUE面试题汇总
  • 直播课文件

    • 静态页面学习指导
    • 属性的计算过程
    • 层叠继承规则总结
    • BFC
    • JS基础知识回顾
    • DOM 事件的传播机制
    • DOM 事件的注册和移除
    • 阻止事件默认行为
    • 基础领航考试题
    • 基础领航考试题(答案)
    • 2024前端发展
    • JS核心概念学习指导
    • 第三方库与工程化学习指导
    • Vue入门学习指导
    • vue进阶学习指导
    • 前端性能优化
  • 笔面试环节知识讲解

    • 目录
    • 图像处理
    • 图像处理(面试)
    • Webpack构建优化
    • Webpack构建优化(面试)
    • TTS性能优化
    • TTS性能优化(面试)
    • 实时协作
    • 实时协作(面试)
    • 网页复制图片到剪贴板
    • 网页复制图片到剪贴板(面试)
    • vite插件
    • vite插件(面试)
    • 表单数据同步与保持
    • 表单数据同步与保持(面试)
    • 优化虚拟列表
    • 优化虚拟列表(面试)
    • 微前端解决巨石应用
    • 微前端解决巨石应用(面试)
    • DNS解析与优化
    • DNS解析与优化(面试)
    • 前端监控
    • 前端监控(面试)
    • 12.跨标签页通信
    • 12.跨标签页通信(面试)
    • 13.Vite相关优化
    • 13.Vite相关优化(面试)
    • 14.计时器节流问题
    • 14.计时器节流问题(面试)
    • 15.多文件预览支持
    • 15.多文件预览支持(面试)
    • 16.defer优化白屏时间
    • 16.defer优化白屏时间(面试)
  • Vue3整体变化
  • Vue2响应式回顾
  • Vue3响应式变化
  • nextTick实现原理
  • 两道代码题
  • Vue运行机制
  • 渲染器核心功能
  • 事件绑定与更新
  • computed面试题
  • watch面试题
  • 图解双端diff
  • 图解快速dff
  • 最长递增子序列
  • 模板编译器
  • 模板编译提升
  • 组件name作用
  • 路由传参方式
  • 基础篇

    • 序章React介绍
    • JSX基础语法
    • React基本介绍
    • 表单
    • 生命周期
    • 组件与事件绑定
    • 组件状态与数据传递
    • Hooks
    • React--redux介绍
    • React-router介绍
  • 就业篇

    • 属性默认值和类型验证
    • 高阶组件
    • Ref
    • Context
    • Render Props
    • Portals
    • 错误边界
    • 组件渲染性能优化
    • 前端框架的理解
    • Reacti和Vue描述页面的区别
    • 前端框架的分类
    • 虚拟DoM
    • React整体架构
    • React渲染流程
    • Fiber双缓冲
    • MessageChannel
    • Scheduleri调度普通任务
    • Scheduleri调度延时任务
    • 最小堆
    • React中的位运算
    • beginWork工作流程
    • completeWork工作流程
    • 图解diff算法
    • commit工作流程
    • lane模型
    • React中的事件
    • Hooks原理
    • useStateuseReducer.
    • effect相关hook
    • useCallbackuseMemo
    • useRef
    • Update
    • 性能优化策略之eagerState
    • 性能优化策略之bailout
    • bailoutContextAPl
    • 性能优化对日常开发启示
  • 前端监控概述
  • 错误监控
  • 数据上报
  • 页面性能监控
  • 用户行为收集与埋点
  • CSS3手册
  • HTML5手册
  • JavaScript语言提升

    • es补充
    • 事件循环
    • promise基础
    • Promise的链式调用
    • Promise的静态方法
    • async和await
    • Promise相关面试题
  • 网络

    • 客户端与服务器
    • 关于 Apifox 的使用
  • git文档
  • 工程化

    • CommonJS
    • ES module
    • npm文档(包管理)
    • Lass笔记
    • webpack工具
  • canvas详解
  • uinapp笔记
  • 自动化测试
  • oauth2令牌

    • 认识Oauth2
    • 三方应用实现github授权
    • 微信三方应用登录实现
    • 支付宝沙箱支付功能
  • 浏览器面试题汇总
  • 浏览器的渲染流程

    • 浏览器的渲染流程
  • 资源提示关键词

    • 资源提示关键词
      • 渲染阻塞回顾
      • defer 和 async
      • preload
      • prefetch
      • prerender
      • preconnect
  • 浏览器的组成部分

    • 浏览器的组成部分
  • 浏览器的离线存储概述

    • 浏览器离线存储概述
  • WebSQL

    • WebSQL
  • IndexedDB

    • IndexedDB
  • File API

    • File API
  • 浏览器的缓存

    • 浏览器缓存
  • 跨标签页通信概述

    • 跨标签页通信
  • Web Worker

    • web worker
  • 浏览器面试题汇总
  • 资源提示关键词
luzhichang
2023-10-14
目录

资源提示关键词

# 资源提示关键词

在上一篇文章中,我们介绍了浏览器的渲染流程,这篇文章中,我们将重点聚焦在渲染阻塞上,来详细看一下渲染阻塞以及一些常见的解决方法。

本文主要包含以下内容:

  • 渲染阻塞回顾
  • defer 和 async
  • preload
  • prefetch
  • prerender
  • preconnect

# 渲染阻塞回顾

我们都知道,HTML 用于描述网页的整体结构。为了理解 HTML,浏览器必须将它转为自己能够理解的格式,也就是 DOM(文档对象模型)

浏览器引擎有一段特殊的代码,称为解析器,用于将数据从一种格式转换为另一种格式。

image-20211206161457653

浏览器一点一点地构建 DOM。一旦第一块代码进来,它就会开始解析 HTML,将节点添加到树结构中。

ezgif-2-2688553063

构建出来的 DOM 对象,实际上有 2 个作用:

  • HTML 文档的结构以对象的方式体现出来,形成我们常说的 DOM 树

  • 作为外界的接口供外界使用,例如 JavaScript。当我们调用诸如 document.getElementById 的方法时,返回的元素是一个 DOM 节点。每个 DOM 节点都有许多可以用来访问和更改它的函数,用户看到的内容也会相应地发生变化。

ezgif-2-01a1ded8c4

CSS 样式会被映射为 CSSOM( CSS 对象模型),它和 DOM 很相似,但是针对的是 CSS 而不是 HTML。

在构建 CSSOM 的时候,无法进行增量构建(不像构建 DOM 一样,解析到一个 DOM 节点就扔到 DOM 树结构里面),因为 CSS 规则是可以相互覆盖的,浏览器引擎需要经过复杂的计算才能弄清楚 CSS 代码如何应用于 DOM。

image-20211206161700033

当浏览器正在构建 DOM 时,如果它遇到 HTML 中的 <script>...</script> 标记,它必须立即执行它。如果脚本是外部的,则必须先下载脚本。

过去,为了执行脚本,必须暂停解析。解析会在 JavaScript 引擎执行完脚本中的代码后再次启动。

image-20211206161717368

为什么解析必须停止呢?

原因很简单,这是因为 Javascript 脚本可以改变 HTML 以及根据 HTML 生成的 DOM 树结构。例如,脚本可以通过使用 document.createElement( ) 来添加节点从而更改 DOM 结构。

image

这也是为什么我们建议将 script 标签写在 body 元素结束标签前面的原因。

<body>
    <!-- HTML Code -->
    <script>
        JS Code...
    </scirpt>
</body>

接下来我们回头来看一下 CSS 是否会阻塞渲染。

看上去 JavaScript 会阻止解析,是因为它可以修改文档。那么 CSS 不能修改文档,所以它似乎没有理由阻止解析,对吧?

但是,如果脚本中需要获取一些尚未解析的样式信息怎么办?在 JavaScript 中完全可以访问到 DOM 节点的某些样式,或者使用 JavaScript 直接访问 CSSOM。

image-20211206161801072

因此,CSS 可能会根据文档中外部样式表和脚本的顺序阻止解析。如果在文档中的脚本之前放置了外部样式表,则 DOM 和 CSSOM 对象的构建可能会相互干扰。

当解析器到达一个脚本标签时,在 JavaScript 执行完成之前无法继续构建 DOM,然而如果这一段 JavaScript 中涉及到访问和使用 CSSOM,那么必须等待 CSS 文件被下载、解析并且 CSSOM 可用。如果 CSSOM 处于未可用状态,则会阻塞 JavaScript 的执行。

image-20211206161819188

(上图中 JavaScript 的执行被 CSS 构建 CSSOM 的过程阻塞了)

另外,虽然 CSS 不会阻塞 DOM 的构建,但是也会阻塞渲染。

还记得我们前面有讲过要 DOM 树和 CSSOM 树都准备好,才会生成渲染树( Render Tree )么,浏览器在拥有 DOM 和 CSSOM 之前是不会显示任何内容。

这是因为没有 CSS 的页面通常无法使用。如果浏览器向你展示了一个没有 CSS 的凌乱页面,那么片刻之后就会进入一个有样式的页面,不断变化的内容和突然的视觉变化会给用户带来混乱的用户体验。

2021-11-22 15.59.41

(这种糟糕的用户体验有一个名字,叫做“无样式内容闪现”,Flash of Unstyled Content,或者简称 FOUC )

为了解决这些问题,所以我们需要尽快的交付 CSS。

这也解释了为什么“顶部样式,底部脚本”被称之为“最佳实践”。

随着现代浏览器的普及,浏览器为我们提供了更多强大的武器(资源提示关键词),合理利用,方可大幅提高页面加载速度。

# defer 和 async

现代浏览器引入了 defer 和 async。

async 表示加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行(异步)。也就是说下载 JS 文件的时候不会阻塞 DOM 树的构建,但是执行该 JS 代码会阻塞 DOM 树的构建。

<script async src="script.js"></script>

defer 表示加载后续文档元素的过程将和 script.js 的加载并行进行(异步),但是 script.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。也就是说,下载 JS 文件的时候不会阻塞 DOM 树的构建,然后等待 DOM 树构建完毕后再执行此 JS 文件。

<script defer src="myscript.js"></script>

具体加载瀑布图如下图所示:

image-20211208112125053

# preload

preload 顾名思义就是一种预加载的方式,它通过声明向浏览器声明一个需要提前加载的资源,当资源真正被使用的时候立即执行,就无需等待网络的消耗。

<link rel="stylesheet" href="style2.css">
<script src="main2.js"></script>

<link rel="preload" href="style1.css" as="style">
<link rel="preload" href="main1.js" as="script">

在上面的代码中,会先加载 style1.css 和 main1.js 文件(但不会生效),在随后的页面渲染中,一旦需要使用它们,它们就会立即可用。

可以使用 as 来指定将要预加载的内容类型。

image-20211208112151152

preload 指令的一些优点如下:

  • 允许浏览器设置资源优先级,从而允许 Web 开发人员优化某些资源的交付。

  • 使浏览器能够确定资源类型,因此它可以判断将来是否可以重用相同的资源。

  • 浏览器可以通过引用 as 属性中定义的内容来确定请求是否符合内容安全策略。

  • 浏览器可以根据资源类型发送合适的 Accept 头(例如:image/webp )

# prefetch

prefetch 是一种利用浏览器的空闲时间加载页面将来可能用到的资源的一种机制,通常可以用于加载非首页的其他页面所需要的资源,以便加快后续页面的首屏速度。

prefetch 加载的资源可以获取非当前页面所需要的资源,并且将其放入缓存至少 5 分钟(无论资源是否可以缓存)。并且,当页面跳转时,未完成的 prefetch 请求不会被中断;

它的用法跟 preload 是一样的:

<link rel="prefetch" href="/path/to/style.css" as="style">

DNS prefetching

DNS prefetching 允许浏览器在用户浏览时在后台对页面执行 DNS 查找。这最大限度地减少了延迟,因为一旦用户单击链接就已经进行了 DNS 查找。

通过将 rel="dns-prefetch" 标记添加到链接属性,可以将 DNS prefetching 添加到特定 URL。建议在诸如 Web 字体、CDN 之类的东西上使用它。

<!-- Prefetch DNS for external assets -->
<link rel="dns-prefetch" href="//fonts.googleapis.com">
<link rel="dns-prefetch" href="//www.google-analytics.com">
<link rel="dns-prefetch" href="//cdn.domain.com">

# prerender

prerender 与 prefetch 非常相似,prerender 同样也是会收集用户接下来可能会用到的资源。

不同之处在于 prerender 实际上是在后台渲染整个页面。

<link rel="prerender" href="https://www.keycdn.com">

# preconnect

我们要讨论的最后一个资源提示是 preconnect。

preconnect 指令允许浏览器在 HTTP 请求实际发送到服务器之前设置早期连接。

我们知道,浏览器要建立一个连接,一般需要经过 DNS 查找,TCP 三次握手和 TLS 协商(如果是 https 的话),这些过程都是需要相当的耗时的。所以 preconnet,就是一项使浏览器能够预先建立一个连接,等真正需要加载资源的时候就能够直接请求了。

image-20211208112216614

以下是为 CDN URL 启用 preconnect 的示例。

<link href="https://cdn.domain.com" rel="preconnect" crossorigin>

在上面的代码中,浏览器会进行以下步骤:

  • 解释 href 的属性值,判断是否是合法的 URL。如果是合法的 URL,然后继续判断 URL 的协议是否是 http 或者 https,如果不是合法的 URL,则结束处理。
  • 如果当前页面 host 不同于 href 属性中的 host,那么将不会带上 cookie,如果希望带上 cookie 等信息,可以加上 crossorign 属性。

-EOF-

浏览器的渲染流程
浏览器的组成部分

← 浏览器的渲染流程 浏览器的组成部分→

Theme by Vdoing | Copyright © 2021-2024 蜀ICP备2024068710号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式