首页 > 其他分享 >记录--两行CSS让页面提升了近7倍渲染性能

记录--两行CSS让页面提升了近7倍渲染性能

时间:2023-03-20 18:02:26浏览次数:36  
标签:渲染 -- auto 元素 visibility content CSS 页面

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

前言

对于前端人员来讲,最令人头疼的应该就是页面性能了,当用户在访问一个页面时,总是希望它能够快速呈现在眼前并且是可交互状态。如果页面加载过慢,你的用户很可能会因此离你而去。所以页面性能对于前端开发者来说可谓是重中之重,其实你如果了解页面从加载到渲染完成的整个过程,就知道应该从哪方面下手了。

嗯,不要跑偏了,今天我们主要来研究长列表页面的渲染性能

现如今的页面越来越复杂,一个页面往往承载着大量的元素,最常见的就是一些电商页面,数以万计的商品列表是怎么保证渲染不卡顿的,大家在面对这种长列表渲染的场景下,一般都会采用分页或者虚拟列表来减缓页面一次性渲染的压力,但这些方式都需要配合JS来时实现,那么有没有仅使用CSS就能够实现的方案呢?

答案是有的,它就是我们今天的主角 —— 内容可见性(content-visibility)

如果这篇文章有帮助到你,❤️关注+点赞❤️鼓励一下作者,文章公众号首发,关注 前端南玖 第一时间获取最新文章~

content-visibility

属性值

content-visibility是CSS新增的属性,主要用来提高页面渲染性能,它可以控制一个元素是否渲染其内容,并且允许浏览器跳过这些元素的布局与渲染。

  • visible:默认值,没有效果。元素的内容被正常布局和呈现。
  • hidden:元素跳过它的内容。跳过的内容不能被用户代理功能访问,例如在页面中查找、标签顺序导航等,也不能被选择或聚焦。这类似于给内容设置display: none
  • auto:该元素打开布局包含、样式包含和绘制包含。如果该元素与用户不相关,它也会跳过其内容。与 hidden 不同,跳过的内容必须仍可正常用于用户代理功能,例如在页面中查找、tab 顺序导航等,并且必须正常可聚焦和可选择。

content-visibility: hidden手动管理可见性

上面说到content-visibility: hidden的效果与display: none类似,但其实两者还是有比较大的区别的:

  • content-visibility: hidden 只是隐藏了子元素,自身不会被隐藏
  • content-visibility: hidden 隐藏内容的渲染状态会被缓存,所以当它被移除或者设为可见时,浏览器不会重新渲染,而是会应用缓存,所以对于需要频繁切换显示隐藏的元素,这个属性能够极大地提高渲染性能。

从这上面我们可以看到,添加了content-visibility: hidden元素的子元素确实是没有渲染,但它自身是会渲染的!

content-visibility: auto 跳过渲染工作

我们仔细想想,页面上虽然会有很多元素,但是它们会同时呈现在用户眼前吗,很显然是不会的,用户每次能够真实看到就只有设备可见区那些内容,对于非可见区的内容只要页面不发生滚动,用户就永远看不到。虽然用户看不到,但浏览器却会实实在在的去渲染,以至于浪费大量的性能。所以我们得想办法让浏览器不渲染非可视区的内容就能够达到提高页面渲染性能的效果。

我们上面说到的虚拟列表原理其实就跟这个类似,在首屏加载时,只加载可视区的内容,当页面发生滚动时,动态通过计算获得可视区的内容,并将非可视区的内容进行删除,这样就能够大大提高长列表的渲染性能。

但这个需要配合JS才能实现,现在我们可以使用CSS中content-visibility: auto,它可以用来跳过屏幕外的内容渲染,对于这种有大量离屏内容的长列表,可以大大减少页面渲染时间。

我们将上面的例子稍微改改:

<template>
  <div class="card_item">
    <div class="card_inner">
      <img :src="book.bookCover" class="book_cover" />
      <div class="card_item_right">
        <div class="book_title">{{ `${book.bookName}${index + 1}` }}</div>
        <div class="book_author">{{ book.catlog }}</div>
        <div class="book_tags">
          <div class="book_tag" v-for="(item, index) in book.tags" :key="index">
            {{ item }}
          </div>
        </div>
        <div class="book_desc">
          {{ book.desc }}
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { toRefs } from "vue";

const props = defineProps<{
  book: any;
  index: any;
}>();
const { book, index } = toRefs(props);
</script>

<style lang="less" scoped>
.card_item {
  margin: 20px auto;
  content-visibility: auto;
}
  / *
  ...
  */
</style>

首先是没有添加content-visibility: auto的效果,无论这些元素是否在可视区,都会被渲染

 如果我们在平常业务中这样写,用户进入到这个页面可能就直接口吐芬芳了,为了性能考虑,我们为每一个列表项加上:

.card_item {
  content-visibility: auto;
}

这个时候我们再来看下效果:

从第10个开始,这些没在可视区的元素就没有被渲染,这可比上面那种全部元素都渲染好太多了,但是如果浏览器不渲染页面内的一些元素,滚动将是一场噩梦,因为无法正确计算页面高度。这是因为,content-visibility会将分配给它的元素的高度(height)视为0,浏览器在渲染之前会将这个元素的高度变为0,从而使我们的页面高度和滚动变得混乱。

content-v4.gif

这里我们可以看到页面上的滚动条会出现抖动现象,这是因为可视区外的元素只有出现在了可视区才会被渲染,这就回导致前后页面高度会发生变化,从而出现滚动条的诡异抖动现象,这是虚拟列表基本都会存在的问题。

⚠️注意:当元素接近视口时,浏览器不再添加size容器并开始绘制和命中测试元素的内容。这使得渲染工作能够及时完成以供用户查看。

这也是为什么上面我们看到的是从第十个才开始不渲染子元素,因为它需要一个缓冲区以便浏览器能够在页面发生滚动时及时渲染呈现在用户眼前。

上面提到的size其实是一种 CSS 属性的潜在值contain,它指的是元素上的大小限制确保元素的框可以在不需要检查其后代的情况下进行布局。这意味着如果我们只需要元素的大小,我们可以跳过后代的布局。

contain-intrinsic-size 救场

页面在滚动过程中滚动条一直抖动,这是一个不能接受的体验问题,为了更好地实现content-visibility,浏览器需要应用 size containment 以确保内容的渲染结果不会以任何方式影响元素的大小。这意味着该元素将像空的一样布局。如果元素没有在常规块布局中指定的高度,那么它将是 0 高度。

这个时候我们可以使用contain-intrinsic-size来指定的元素自然大小,确保我们未渲染子元素的 div 仍然占据空间,同时也保留延迟渲染的好处。

语法

此属性是以下 CSS 属性的简写:

  • contain-intrinsic-width
  • contain-intrinsic-height
/* Keyword values */
contain-intrinsic-width: none;

/* <length> values */
contain-intrinsic-size: 1000px;
contain-intrinsic-size: 10rem;

/* width | height */
contain-intrinsic-size: 1000px 1.5em;

/* auto <length> */
contain-intrinsic-size: auto 300px;

/* auto width | auto height */
contain-intrinsic-size: auto 300px auto 4rem;

contain-intrinsic-size 可以为元素指定以下一个或两个值。如果指定了两个值,则第一个值适用于宽度,第二个值适用于高度。如果指定单个值,则它适用于宽度和高度。

实现

我们只需要给添加了content-visibility: auto的元素添加上contain-intrinsic-size就能够解决滚动条抖动的问题,当然,这个高度约接近真实渲染的高度,效果会越好,如果实在无法知道准确的高度,我们也可以给一个大概的值,也会使滚动条的问题相对减少。

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

之前没添加contain-intrinsic-size属性时,可视区外的元素高度都是0,现在这些元素高度都是我们设置的contain-intrinsic-size的值,这样的话整个页面的高度就是不会发生变化(或者说变化很小),从而页面滚动条也不会出现抖动问题(或者说抖动减少)

content-v6.gif

性能对比

上面说了这么多,content-visibility是否真的能够提高页面的渲染性能呢,我们来实际对比看看:

  • 首先是没有content-visibility的页面渲染
  • 然后是有content-visibility的页面渲染

上面是用1000个列表元素进行测试的,有content-visibility的页面渲染花费时间大概是37ms,而没有content-visibility的页面渲染花费时间大概是269ms,提升了足足有7倍之多!!!

对于列表元素更多的页面,content-visibility带来的渲染性能提升会更加明显。

思考

标签:渲染,--,auto,元素,visibility,content,CSS,页面
From: https://www.cnblogs.com/smileZAZ/p/17237191.html

相关文章

  • 解决Windows远程桌面“由于安全设置错误, 客户端无法连接到远程计算机”
     远程桌面连接时报“由于安全设置错误,客户端无法连接到远程计算机”  解决方法如下:一、打开运行对话框,两种方式,点击开始→运行或Win+R,输入“gpedit.msc”,打开本......
  • linux安装mysql8
    #解压tarxvJfmysql-8.0.30-linux-glibc2.12-x86_64.tar.xz#改名mvmysql-8.0.30-linux-glibc2.12-x86_64mysql-8.0.30cdmysql-8.0.30;mkdirdata;mkdirlog......
  • (二十一)桥接模式
    1.概述合成/聚合复用原则(CARP),尽量使用合成/聚合,尽量不要使用类继承。合成(Composition,也有翻译成组合)和聚合(Aggregation)都是关联的特殊种类。聚合表示一种弱的“拥有”关......
  • 全链路压测(13):高可用和性能优化
    转载:https://www.cnblogs.com/imyalost/p/16295324.html大家好,这是全链路压测系列的第十三篇文章,也是倒数第二篇文章。前面用了很多篇幅介绍了包括全链路压测的调研验证......
  • Mybatis 源码(四):Mapper的解析工作
    1、Mapper配置方式1、package方式指定包路径:<mappers><packagename="org.snails.mapper"/></mappers>2、resource方式指定mapper.xml文件的相对路径:<map......
  • Go语言:利用 TDD 测试驱动开发帮助理解数组与动态数组(切片)的区别
    ArrayVSSlice数组允许你以特定的顺序在变量中存储相同类型的多个元素。对于数组来说,最常见的就是迭代数组中的元素。我们创建一个Sum函数,它使......
  • 全链路压测(14):生产全链路压测SOP
    转载:https://www.cnblogs.com/imyalost/p/16320668.html全链路压测系列文章,写到这里就算告一段落了,最初萌生写全链路压测系列文章,还是在21年9月份。兜兜转转写了很久,草稿......
  • 华为核心交换机VRRP与DHCP
    2023.3.20--16.52华为核心交换机VRRP与DHCP 拓扑:原理1、建立VRRP主备份,可以将两台设备虚拟成一台设备;(作用于指定接口)此时,在对应的vrid组里,可以将不同的VRRP设备配......
  • linux安装redis
    redis-server../redis.conf开启服务,进程得守护着,命令终端不能退出redis-server&../redis.conf开启服务,进程不用留在终端打开的效果解决办法:https://www.......
  • pgadmin4工具安装及使用
    一、pgAdmin简介pgAdmin,是一个维护和管理Postgres数据库用通用工具。pgadmin官网下载地址:https://www.pgadmin.org/二、安装pgadmin4-6.18-x64.exe双击软件打开运行,弹......