如何只使用CSS提升页面渲染速度

Souleigh ✨
• 阅读 1304

用户喜欢快速的 Web 应用。他们期望页面加载速度快,运行流畅。如果滚动时出现动画中断或延迟,用户很可能就会离开你的网站。作为一名开发者,你可以做很多事情来提升用户体验。本文主要介绍你可以用来提升页面渲染速度的 4 个 CSS 技巧。

1. Content-visibility

一般来说,大部分 Web 应用都有复杂的 UI 元素,并且它的扩展超出了用户在浏览器视图中所能看到的范围。在这种情况下,我们可以使用content-visibility来跳过渲染屏幕之外的内容。如果你有大量屏幕之外的内容的话,这会大大减少页面渲染时间。

这个功能是最新添加的功能之一,而且它是提升渲染性能最有影响力的功能之一。content-visibility接受几个值,我们可以在一个元素上使用content-visibility: auto;来立即获得性能提升。

我们可以看下面这个页面,包含很多显示不同信息的卡片。虽然屏幕能显示大约 12 个卡片,但列表中有差不多 375 个卡片。如你所见,浏览器花费 1037ms 来渲染这个页面。

如何只使用CSS提升页面渲染速度一般 HTML 页面

下一步,你可以向所有的卡片中加入content-visibility

在这个例子中,向页面中加入content-visibility后,渲染时间下降到 150ms。性能提升了 6 倍以上。

如何只使用CSS提升页面渲染速度使用 content-visibility

如你所见,content-visibility 的功能很强大,对于改善页面渲染时间非常有用。根据我们目前为止讨论的内容,你一定在想它是针对页面渲染的灵丹妙药。

content-visibility 的限制

然而,也有一些领域 content-visibility 不适合。我想强调 2 点供你考虑。

这个功能还是实验性的。 目前,Firefox(PC 和 Android 版本)、Internet Explorer (我不认为他们计划向 IE 中添加这个功能) 以及 Safari (Mac 和 iOS) 不支持 content-visibility。

与滚动条行为相关的问题。 由于元素最初渲染的高度是 0px,当你向下滚动时,这些元素会进入屏幕。实际的内容会被渲染,这个元素的高度会被相应地更新。这会使滚动条出现预料之外的行为。

如何只使用CSS提升页面渲染速度使用 content-visibility 的滚动行为

为了修复这个滚动条问题,你可以使用另一个 CSS 属性,contain-intrinsic-size。它指定了一个元素的自然大小。因此,这个元素会用指定的高度渲染,而不是 0px。

.element{  
    content-visibility: auto;  
    contain-intrinsic-size: 200px;  
}

然而,在实验时,我发现即使使用containt-intrinsic-size,如果我们有很多元素都使用content-visibility且设置为auto,你仍然会有微小的滚动条问题。因此,我的建议是规划你的布局,将它分解为几个部分,然后在那几个部分上使用 content-visibility 来获取更好的滚动条行为。

2.Will-change属性

浏览器上的动画并不是一个新鲜事物。通常,这些动画与其它元素一起正常渲染。然而,浏览器现在能够使用 GPU 来优化这些动画的某些操作。

使用 will-change CSS 属性,我们可以表明该元素将要修改特定的属性,让浏览器提前执行必要的优化。

底层发生的是,浏览器会为这个元素创建一个单独的层。然后,浏览器将这个元素的渲染委托给 GPU,以及其它一些优化。由于 GPU 加速接管了动画渲染,最终这个动画会更流畅。

考虑如下 CSS 类:

// In stylesheet  
.animating-element {  
  will-change: opacity;  
}  
// In HTML  
<div class="animating-elememt">  
  Animating Child elements  
</div>

当在浏览器中渲染上面的代码时,它会识别出will-change属性,并优化未来与不透明度 opacity 相关的变更。

根据 Maximillian Laumeister 所做的性能基准测试,你可以看到他只改变了一行代码就获得了超过 120FPS 的渲染速度,而最初的渲染速度大约是 50FPS。

如何只使用CSS提升页面渲染速度不使用 will-change;图片来源:Maximilian

如何只使用CSS提升页面渲染速度使用 will-change;图片来源:Maximilian

什么时候不要用 will-change

尽管will-change是用来提升性能的,但如果你误用它,也会降低 Web 应用的性能。

使用will-change表明这个元素将来会改变

因此,如果你试图将will-change与同步动画一起使用,它不会给你优化。因此,建议在父元素上使用 will-change,在子元素上使用动画。

.my-class{  
  will-change: opacity;  
}  
.child-class{  
  transition: opacity 1s ease-in-out;  
}

不要使用未设置动画的元素。 当你在一个元素上使用will-change,浏览器会尝试通过将它放到一个新层中并将转换移交给 GPU 来优化它。如果你没有要转换的东西,这会导致资源浪费。

最后要记住的是,建议在完成所有动画之后将 will-change 从元素上删除。

3. 减少渲染阻塞时间

今天,许多 Web 应用必须满足许多形式因素,包括 PC、平板电脑和移动手机等。为了实现这种响应式特性,我们必须根据媒介大小编写新的样式。在页面渲染时,直到 CSS 对象模型(CSS Object Model,CSSOM)准备就绪,它才开始渲染阶段。根据你的 Web 应用,你可能有一个很大的样式表来满足所有的设备形式因素。

然而,假设我们根据形式因素将它拆分成多个样式表。在这种情况下,我们可以只让主 CSS 文件阻塞关键路径,并将其优先下载,让其它样式表以低优先级的方式下载。

<link rel="stylesheet" href="styles.css">

如何只使用CSS提升页面渲染速度单个样式表

在将它分解成多个样式表后:

<!-- style.css contains only the minimal styles needed for the page rendering -->  
<link rel="stylesheet" href="styles.css" media="all" />  
<!-- Following stylesheets have only the styles necessary for the form factor -->  
<link rel="stylesheet" href="sm.css" media="(min-width: 20em)" /><link rel="stylesheet" href="md.css" media="(min-width: 64em)" /><link rel="stylesheet" href="lg.css" media="(min-width: 90em)" /><link rel="stylesheet" href="ex.css" media="(min-width: 120em)" /><link rel="stylesheet" href="print.css" media="print" />

如何只使用CSS提升页面渲染速度

如你所见,根据形式因素拆分样式表能够减少渲染阻塞时间。

4. 避免使用 @import 来包含多个样式表

使用@import,我们可以在一个样式表中包含另一个样式表。当我们在处理一个大型项目时,使用@import会让代码更简洁。

关于 @import 的一个关键事实是,它是一个阻塞调用,因为它必须发起一个网络请求来获取这个文件,解析它,然后将它包含在样式表中。如果我们在样式表中有嵌套的 @import,它会妨碍渲染性能。

# style.css  
@import url("windows.css");  
# windows.css  
@import url("componenets.css");

如何只使用CSS提升页面渲染速度使用 imports 的瀑布图

与其使用@import,我们可以使用多个链接 link 实现相同的功能且具有更好的性能,因为它允许并行下载样式表。

如何只使用CSS提升页面渲染速度使用链接的瀑布图

结论

除了本文我们讨论的 4 个方面,还有一些其它的方法我们可以使用 CSS 来提高 Web 页面的性能。CSS 最新的特性之一,content-visibility,在未来几年看起来很有前景,因为它可以在页面渲染方面带来数倍的性能提升。

最重要的是,我们不用编写一句 JavaScript 代码就可以获得所有这些性能提升。

我相信,你可以结合以上特性,为最终用户构建性能更好的 Web 应用。我希望这篇文章是有用的。谢谢!

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Stella981 Stella981
3年前
Sass
嵌套规则(NestedRules)Sass允许将一套CSS样式嵌套进另一套样式中,内层的样式将它外层的选择器作为父选择器mainp{color:00ff00;width:97%;.redbox{
Wesley13 Wesley13
3年前
JS和CSS加载(渲染)机制不同
一、结论CSS可以在页面加载完成后随时渲染。举个例子:通过js给某个元素加一个id或者css,只要这个id或者css有对应的样式,此元素的样式就会自动生效。JS不可以在页面加载完成后生效。最明显的例子就是使用EasyUI的时候,iframe中哪些样式无效(EasyUi是依靠JS进行样式处理的,所以无法运行JS,那么样式也就无法设置。简单点说
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这