MDN--Web性能

CSS 动画与 JavaScript 动画

  • 动画的实现可以有很多种方式,比如 CSS transition 和 animation 或者基于 JavaScript 的动画(使用 requestAnimationFrame())

CSS 过渡和动画

  • CSS transiton :创建当前样式与结束状态样式之间的动画。尽管一个元素处于过渡状态中,新的过渡动画也会立即从当前样式开始,而不是直接跳转到 CSS 的最终状态
  • CSS animation 允许指定多个关键帧 @keyframes 来实现,每一个关键帧都描述了动画元素在给定时间点上应该如何渲染。
    • 关键帧使用 来指定动画发生的时间点
  • 就性能方面来说,无论通过 CSS animation 还是 transition 创造动画,都没有区别。

requestAnimationFrame

  • 本方法的回调函数在绘制下一帧之前由浏览器调用。与需要一个延迟参数的 setTimeout() 或 setInterval() 相比,requestAnimationFrame() 效率要高得多。

像 CSS transitions 和 animations 一样,当页面在后台运行时,requestAnimationFrame() 会暂停。

性能对比:transition vs requestAnimationFrame

事实上,大多数场景下,基于 CSS 的动画几乎跟 JavaScript 动画表现一致。一些基于 Javascript 的动画库,像 GSAP 和 Velocity.JS 甚至声称可以做得比原生 CSS transition/animation 更好。这是可能的:

  • 因为在 repaint(重绘)事件发生之前,CSS transition 和 animation 在主的 UI 线程仅仅是重新采集元素的样式,这跟通过 requestAnimationFrame() 回调获取重新采集元素样式是一样的,也是在下一次重绘之前触发。假如二者都是在主 UI 线程创建的动画,那它们在性能方面没有差异。

脱离主线程的动画

虽然有上述的说法,我们仍然认为 CSS 动画是更好的选择。原因是:只要动画涉及的属性不引起 reflow(回流)。我们就可以把操作移出主线程。最常见的属性的 CSS transform (还有:will-change、Opacity、translate3D、等元素)。如果一个元素被提升为一个 layer,transform 属性动画就可以在 GPU 中进行。这意味着更好的等性能

动画性能总结

浏览器可以优化渲染流程,所以我们可以尽可能通过 CSS transiton 和 animation 创建动画。

优化启动性能

你能通过异步的方式做的事越多,应用就能更好的利用多核处理器!

不要将你所有的启动代码在应用主线程中的唯一一个事件处理函数中运行。相反,你应该在后台线程创建一个 Web worker,做尽可能多的工作(比如获取和处理数据)。然后,所有必须在主线程中完成的事情(比如用户事件和渲染用户界面) 应该被分成小的片段,这样,当应用启动时,应用的事件循环就可以持续地运行下去。这可以避免应用、浏览器以及/或者设备出现锁死

异步化

  • 启动时,在需要异步执行的脚本标签上使用 deferasync 属性。这会允许 HTML 解析器更高效地处理文档。 Async scripts for asm.js 中有更多关于这方面的信息。
  • 如果你需要解码资源文件(比如,解码 JPEG 文件并将其转换为原始纹理数据,以便随后在 WebGL 中使用),最好在 workers 里做这件事。
  • 当处理浏览器支持的数据格式时(例如,解析图像数据),使用设备或浏览器内置的解码器而不是运行你自己的或者使用 or using one from the original codebase。预先提供的那个基本上一定会快得多,并且能够减小你的应用的启动体积。另外,浏览器可以自动并行化这些解码器的工作。
  • 所有能并行的数据处理都应该并行化。不要一团接一团地处理数据,如果可能的话,同时处理它们!
  • 在你启动的 HTML 文件中,不要包含不会在关键路径下出现的脚本或样式表。只在需要时加载他们。
  • 不要强迫 Web 引擎构建不需要的 DOM

使用 dns-prefetch

DNS-prefetch 尝试在请求资源之前解析域名

为什么要使用 dns-prefetch

当浏览器从服务器请求资源时,必须先将该跨源域名解析为 IP 地址,然后浏览器才能发出请求。DNS 缓存可以帮助减少此延迟,而 DNS 解析可以导致请求增加明显的延迟。对于打开了许多与第三方的链接的网站,此延迟可能会大大降低加载性能

  • dns-prefetch 可帮助开发人员掩盖 DNS 解析延迟。 HTML 元素通过 dns-prefetch 的 rel 属性值提供此功能。然后在 href 属性中指明要跨源的域名:
<link rel="dns-prefetch" href="https://fonts.googleapis.com/" />
  • dns-fetch可以减少等待DNS解析的时间、减少与服务器建立连接的延迟。
  • 同时的,可以配对使用 dns-preconnect 来预连接关键的连接,它可以建立与服务器的连接,配对后的过程包括 DNS 解析,以及建立 TCP(可能还有 TLS)连接。可以进一步减少跨源请求的感知延迟。使用示例:
<link rel="preconnect" href="https://fonts.googleapis.com/" crossorigin />
<link rel="dns-prefetch" href="https://fonts.googleapis.com/" />

  • 一些资源(如字体)以匿名模式加载。在这种情况下,应使用预连接提示设置 crossorigin 属性。如果省略了它,则浏览器将仅执行 DNS 查找。

关键渲染路径

关键渲染路径是浏览器将 HTML、CSS、JavaScript 转换为屏幕上的像素所经历的步骤序列。优化关键渲染路径可提高渲染性能。关键渲染路径包含了 DOM、CSSOM、Render Tree和布局

理解 CRP

网页的请求从HTML文件请求开始。浏览器解析 HTML,转换收到的数据为 DOM 树。浏览器每次发现外部资源就初始化请求,无论是样式、脚本或者嵌入的图片引用。有时请求会阻塞,在解析 HTML,发请求和构造 DOM 直到文件结尾,这时开始构造 CSS 对象模型。等到 DOM 和 CSSOM 完成之后,浏览器构造渲染树,计算所有可见内容的样式。一旦渲染树完成布局开始,定义所有渲染树元素的位置和大小。完成之后,页面被渲染完成,或者说是绘制到屏幕上。

DOM

DOM 构建是增量的。HTML 响应变成令牌(token),令牌变成节点,而节点又变成 DOM 树。单个 DOM 节点以 startTag 令牌开始,以 endTag 令牌结束。节点包含有关 HTML 元素的所有相关信息。该信息是使用令牌描述的。节点根据令牌层次结构连接到 DOM 树中。如果另一组 startTag 和 endTag 令牌位于一组 startTag 和 endTag 之间,则你在节点内有一个节点,这就是是我们定义 DOM 树层次结构的方式。

节点数量越多,关键渲染路径中的后续事件将花费的时间就越长。

CSSOM

DOM 是增量的,但CSSOM不是。CSS 是渲染阻塞的:浏览器会阻塞页面渲染直到它接收和执行了所有的 CSS。CSS 是渲染阻塞是因为规则可以被覆盖,所以内容不能被渲染直到 CSSOM 的完成。

CSS 中,因为后续规则可能被之前的所覆盖。CSS 对象模型随着 CSS 的解析而被构建,但是直到完成都不能被用来构建渲染树,因为样式将会被之后的解析所覆盖而不应该被渲染到屏幕上。

从选择器性能的角度,更少的特定选择器上比更多的要快。因为当浏览器发现一个选择器,必须沿着 DOM 向上走来检查该选择器是否存在一个祖先。越是具体的标签浏览器就越需要更多的工作,但是这样的弊端未必值得优化。

更具体的规则更耗费性能是因为他必须遍历更多的 DOM 树节点,但是这所带来的额外消耗通常很小,仅仅只是毫秒级的差距。

优化CRP

提升页面加载速度需要通过加载资源的优先级、控制他们加载的顺序和减少这些资源的体积。性能提示包括:

  • 通过异步、延迟加载或者消除非关键资源来减少关键资源的请求数量。
  • 优化必须的请求数量和每个请求的文件体积
  • 通过区分关键资源的优先级来优化被加载关键资源的顺序,来缩短关键路径长度

懒加载

懒加载是一种将资源标识为非阻塞资源,并仅在需要时加载它们的策略。这是一种缩短关键渲染路径长度的方法,可以缩短页面加载时间。

延迟加载可以在应用程序的不同时刻发生,但通常会在某些用户交互上发生(如滚动和导航)

常规

代码拆分–在前期发送所需的最小代码,改善页面加载时间。其余的可以按需加载。

  • 入口点分离:通过应用的入口点分离代码
  • 动态分离:通过动态 import() 语句分离代码

脚本类型模块

  • 任何类型为 type=“module” 的脚本标签都会被视为一个 JavaScript模块,并且默认情况下会被延迟。

CSS

  • 默认情况下,CSS 被视为渲染阻塞资源,因此,在 CSSOM 构造完成之前,浏览器不会渲染任何已处理的内容。建议使用媒体类型和查询实现非阻塞渲染
<link href="style.css" rel="stylesheet" media="all" />
<link href="portrait.css" rel="stylesheet" media="(orientation:portrait)" />
<link href="print.css" rel="stylesheet" media="print" />

字体

默认情况下,字体请求会延迟到构造渲染树之前,这可能会导致文本渲染延迟。

可以使用 、CSS font-displat属性、字体加载API来覆盖默认行为并预加载网络字体资源。

图片和 iframe

大多数情况,这些图片都在屏幕之外,需要用户互动才能看到

  • Loading 属性
<img src="转存失败,建议直接上传图片文件 image.jpg" alt="...转存失败,建议直接上传图片文件" loading="lazy">
<iframe src="video-player.html" title="..." loading="lazy"></iframe>
  • 使用监听器:Intersection Observer 观察元素什么时候进入或退出浏览器的视口

渲染页面:浏览器的工作原理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值