Code前端首页关于Code前端联系我们

css3实现乞丐版的前置弹幕效果实现及性能优化

terry 2年前 (2023-09-27) 阅读数 91 #数据结构与算法

1. css3实现乞丐版弹幕

(1)如何通过css3实现弹幕

首先我们看看如何通过css实现弹幕 弹幕最简单:

首先定义HTML弹幕结构:

<div class="block">我是弹幕</div>
复制代码

通过移动该方块即可实现弹幕移动。以弹幕从右向左移动为例,弹幕起始位置在容器左侧,贴边隐藏(弹幕左侧与容器右侧重合),可绝对达到了。位置与变换:

.block{
   position:absolute;
}
复制代码

初始位置:

from{
    left:100%;
    transform:translateX(0)
}
复制代码

向左移动两帧弹幕动画结束位置:

@keyframes barrage{
   from{
     left:100%;
     transform:translateX(0);
   }
   to{
     left:0;
     transform:translateX(-100%);
   }
}
复制代码

将这个动画引入弹幕元素:

.block{
  position:absolute;
  /* other decorate style */
  animation:barrage 5s linear 0s;
}
复制代码

这样,乞丐版的弹幕效果可以实现:css3实现乞丐版前端弹幕效果实现方式及性能优化

(2)弹幕的缺陷是通过绝对位置和左侧位置来实现的

先讲解一下css渲染过程

  • I)根据HTML结构创建DOM树( DOM树包含外观的节点:无)
  • II)基于DOM树,根据节点的几何属性(margin/padding/width/height/left等)生成渲染树
  • III)继续基于渲染树来渲染颜色、字体等属性

如果I)和II)中的属性改变回流(reflow)会发生什么,如果只改变III)中的属性,只需要重绘(重绘)将会发生。显然我们从CSS渲染过程中也可以看出:回流必然伴随着重绘。

reflow(回流):当渲染树的部分或全部由于尺寸、边距等问题发生改变,需要重新构建时,该过程称为回流。 repaint(重绘):当某些策略改变元素时,例如外观和背景颜色。会引起布局变化并需要重新渲染的过程称为重绘

reflow(回流)会影响浏览器的CSS渲染速度,所以在优化网页性能时,需要减少回流的发生。

第一部分我们使用left属性来实现弹幕效果。左侧会改变元素的布局,从而出现回流,从而导致弹幕动画在移动端页面卡顿。

2。 CSS3弹幕性能优化

我们发现第一部分的弹幕动画有卡顿的问题。让我们看看如何解决动画卡住的问题。

(1) CSS开启硬件加速

使用CSS在浏览器中开启硬件加速,并使用GPU(图形处理单元)来提高网页性能。正因为如此,我们可以利用GPU的强大功能来让我们的网站或应用程序运行得更加流畅。

CSS 动画、转换和转场不会自动开启 GPU 加速,而是由浏览器的缓慢软件渲染引擎执行。那么如何切换到GPU模式呢?许多浏览器提供特定的触发 CSS 规则。

更常见的方式是通过3D变换(translate3d属性)启用硬件加速。为此,我们将动画改为:

@keyframes barrage{
   from{
     left:100%;
     transform:translate3d(0,0,0);
   }
   to{
     left:0;
     transform:translate3d(-100%,0,0);
   }
}
复制代码

这样,我们就可以通过开启硬件加速来优化网页的性能。但这种方法并没有从根本上解决问题。同时,使用GPU会增加内存使用量,这会减少移动设备的电池寿命等。

(2)不要改变left属性

第二种办法就是想办法在弹幕动画前后不改变left属性的值,这样就不会发生回流。

我们想要只通过translateX来确定弹幕节点的初始位置,但是translateX(-100%)是相对于弹幕节点本身的,而不是相对于父元素的,所以我们将js和css配对,在js中得到弹幕节点所在父元素的宽度,然后根据其宽度确定弹幕节点的初始位置。

以父元素为body为例:

//css
 .block{
  position:absolute;
  left:0;
  visibility:hidden;
  /* other decorate style */
  animation:barrage 5s linear 0s;
}
//js
let style = document.createElement('style');
document.head.appendChild(style);
let width = window.innerWidth;
let from = `from { visibility: visible; -webkit-transform: translateX(${width}px); }`;
let to = `to { visibility: visible; -webkit-transform: translateX(-100%); }`;
style.sheet.insertRule(`@-webkit-keyframes barrage { ${from} ${to} }`, 0);
复制代码

除了js耦合计算父元素的宽度来确定弹幕节点的初始位置外,这里在弹幕节点中我们需要防止从显示位置开始,增加可见性:隐藏属性。防止弹幕节点在开始位置确定之前就显示在父容器中。仅当您从起始位置开始滚动时才会出现弹幕。

但是这种CSS实现方式要实现额外的弹幕功能比较麻烦,比如如何控制弹幕暂停等等。

作者:yuxiaoliang
链接:https://juejin.im/post/5b44112cf265da0fa42cc04e
来源:掘金版权所有。商业转载请联系作者获取授权。非商业转载请注明出处。

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

热门