稀土掘金 稀土掘金

使用CSS变量要注意的性能问题

英文原文地址: lisilinhart.info/posts/css-v…

概览

  • 注意样式重排,因为CSS变量是可继承的,改动父元素上的变量也会影响其子元素
  • 尽量为每个元素使用单个类名(而不是嵌套类名),让浏览器更简单的计算样式
  • calc()与变量一起使用也有不错的性能,只需要注意有些浏览器不支持如degms等单位
  • 在JS中尽量使用setProperty而不是行内样式来设置CSS变量

全局与局部变量

大部分编程语言中都有这样的概念——变量的范围。它定义了一个变量应该作用于整个文档中还是这个文档的子部分(如JS中定义全局变量和在某个函数内定义局部变量)。在CSS中,我们可以这样定义一个全局变量:

 :root {
     --main-color: tomato;
 }

如果我们想要变量只在某个模块可见,我们可以这样定义一个局部变量:

 /* 在某个类名下定义,此处title和其子元素都可以访问到变量 */
 .title {
     --title-color: aqua;
     color: var(--title-color);
 }

其实我们大可不必在某个模块中专门定义一个如--title-color这样的名称,我们可以使用与全局变量相同的名称,这只会影响到这个模块下全局变量的定义而不会影响全局变量在其它地方的使用:

 /* 其它用到--main-color的地方仍使用tomato */
 :root {
     --main-color: tomato;
 }
 .title {
   --main-color: aqua;
     color: var(--main-color);
 }

继承和样式重排

在叙述之前,我会简要介绍一下元素类名的两种命名方式:每个类基于功能命名,用嵌套表示层级关系和BEM命名规范(我的理解是每个类命名为父元素类名__功能名),下面是例子。

 /* 功能命名,嵌套表示层级,使用less书写 */
 .card {
     .heading {
         .title {
         
         }
     }
 }
 /* BEM */
 .card {}
 .card__heading {}
 .card__heading__title {}

想要理解变量范围对于性能的影响,我们得先了解浏览器是如何处理样式计算的。

例如你写了一段这样的cssp:nth-last-child(1),浏览器就需要找到所有的p标签,并判断它是否是最后一个p标签,这可能要比用选择器和元素对比的开销大很多,因为前者是基于类匹配的。

使用BEM来书写类名会让浏览器更轻松的计算样式,因为这不需要让一个元素与兄弟节点对比确定它是否要应用某些样式。(个人认为具体使用BEM来写类名还是嵌套式要根据具体项目决定,有时候牺牲一些性能换来清晰的代码结构也是值得的,嵌套可以保证一些公共部分的复用利于后期维护)

CSS变量与样式重排

因为CSS变量是可继承的,修改它们会导致所有子元素的样式重排。除了修改CSS变量会导致这种现象,对于如colorfont这样的可继承属性亦是如此。

为了阻止大量的子元素受到影响,我们应尽量在最深的层级去修改这些属性。

样式重排的例子

为了测量在父元素上设置变量和在子元素上设置变量的性能差别,下面创建了一个拥有25000个子元素的元素。

 <div class="container">
   <span class="el"></span>
 ... 25000 more elements
 </div>
 .el {
     background: var(--bg, orange);
 }

下面是对于拥有25000个子元素的元素,通过js在父元素上设置变量和在子元素上设置变量的性能差别。

css-variables-style-recalc.550.webp

在Calc()中使用CSS变量

当我们结合calc()使用CSS变量,它的功能会更加强大。尤其是在写transform时单独定义一个无单位的变量和多个属性名,用变量的值和它们的单位相关联是更好的选择而且能让修改过渡变得更简单。直到现在,calc()多用于计算响应式元素的宽高。如果我们想要一个比100%宽少100px的元素,可以这样写:

 .container {
   width: calc(100% - 100px);
 }

与CSS变量结合使用时,calc()可以做更多事情。你可以这样为一个没有单位的CSS变量加上单位:

 :root {
     --duration: 2000;
 }
 
 div {
   animation-duration: calc(var(--duration) * 1ms);
 }

使用calc()的性能

下面列举了6种不同情况的性能:variable + calc + px、variable + px、px、variable + calc + percent、variable + percent和percent。

css-variables-calc.550.webp

使用JS设置CSS变量

调用setProperty方式:

 element.style.setProperty('--color', 'green'); 

内联样式:

 element.style = '--color: green';

测试用例每次都应用在100条html元素上。Safari中,设置内联样式比setProperty方式要快得多,而谷歌浏览器中两者没有太显著的差别,在火狐浏览器中则是与Safari浏览器表现相反。因此在使用时最好还是使用setProperty的方式,因为在火狐浏览器中使用内联样式非常之慢。

玻璃钢生产厂家玻璃钢花盆花器品牌好惠州玻璃钢雕塑制作厂家东莞玻璃钢透光雕塑公司镜面玻璃钢雕塑生产厂家门头玻璃钢雕塑价格珠海小区玻璃钢雕塑价格云南砂岩雕塑玻璃钢雕塑南京创意玻璃钢雕塑联系方式甘孜玻璃钢花盆雕塑定制厂家安徽楼盘玻璃钢卡通形象雕塑商场美陈报价预算金华动物玻璃钢雕塑上海周年庆典商场美陈费用长寿玻璃钢花盆花器佛山树脂玻璃钢雕塑供应商信阳玻璃钢动物雕塑制作厂家玻璃钢蓝球雕塑西藏玻璃钢浮雕人物山水雕塑马鞍山玻璃钢雕塑定做价格玻璃钢金属雕塑私人定做辽宁玻璃钢雕塑销售公司湖北玻璃钢雕塑专业定制厂家中秋 商场美陈株洲卡通玻璃钢雕塑扬州黑色玻璃钢花盆树脂玻璃钢雕塑厚度景观玻璃钢雕塑怎么联系陕西公园水景玻璃钢人物雕塑淮安玻璃钢仿铜雕塑制作牟平玻璃钢卡通雕塑香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化