浅析CSS的性能优化

栏目:资讯发布:2023-09-30浏览:3收藏

浅析CSS的性能优化,第1张

下面我们来看一个动画效果(类似平时页面滚动功能),在该动画是让一个球沿着某种路径移动。最简单的方式就是实时调整它们的left和top属性,使用css动画实现。

在运行的时候即使是在电脑浏览器上也会隐约觉得动画的运行并不流畅,更不要提在移动端达到60fps的流畅效果了。这是因为top和left的改变会触发浏览器的reflow和repaint,整个动画过程都在不断触发浏览器的重新渲染,这个过程是很影响性能的。

为了解决这个问题,我们使用transform中的translate()来替换top和left

这个时候我们就会发现整个动画效果流畅了很多,在动画移动的过程中也没有发生repaint和reflow。那么为什么transform没有出发repaint呢?原因就是transform动画由GPU控制,支持硬件加速,并不需要软件方面的渲染。

浏览器收到页面文档后,会将文档中的标记语言解析为DOM树,DOM和CSS结合后形成浏览器构建页面的渲染树,渲染树中包含了大量的渲染元素,每一个渲染元素会被分到一个图层中,每个又会被加载到GPU形成渲染纹理,而图层在GPU中transform是不会触发repaint的,这一点非常类似3D绘图功能,最终这些使用transform的图层都会使用独立的合成器进程进行处理,移动时的变化也是独立的,不会影响到页面的其他元素,造成重排重绘是因为影响到页面的其他图层元素导致的,可以理解为其他元素都是在一个图层空间,所以一个图层移动其他的也会收到影响,而transform创建了一个新的复合图层,它会被GPU独立执行transform操作,跟其他图层互不影响,所以不会引起重排重绘。

此时,你也许会问浏览器什么时候会创建一个独立的复合图层呢?事实上一般是在以下几种情况下:

因为GPU进程会为其开启一个新的复合图层,不会影响默认复合图层(就是普通文档流),所以并不会影响周边的 DOM 结构,而属性的改变也会交给 GPU 处理,不会进行重排。使 GPU 进程开启一个新的复合图层的方式还有 3D 动画,过渡动画,以及 opacity 属性,还有一些标签,这些都可以创建新的复合图层。这些方式叫做硬件加速方式。你可以想象成新的复合图层和默认复合图层是两幅画,相互独立,不会彼此影响。降低重排的方式:要么减少次数,要么降低影响范围,创建新的复合图层就是第二种优化方式。绝对布局虽然脱离了文档流,但不会创建新的复合图层,因此当绝对布局改变时,不会影响普通文档流的 render tree,但是依然会绘制整个默认复合图层,对普通文档流是有影响的。普通文档流就是默认复合图层,不要介意我交换使用它们如果你要使用硬件加速方式降低重排的影响,请不要过度使用,创建新的复合图层是有额外消耗的,比如更多的内存消耗,并且在使用硬件加速方式时,配合 z-index 一起使用,尽可能使新的复合图层的元素层级等级最高。

(1)transform

(2)opacity

(3)filter

(1)内存。如果GPU加载了大量的纹理,那么很容易就会发生内存问题,这一点在移动端尤为明显。

(2)使用GPU渲染会影响字体的抗锯齿效果。这是因为GPU和CPU具有不同的渲染机制,即使最终硬件加速停止了,文本还是会在动画期间显示的很模糊。

1、transform会使用GPU硬件加速,性能更好,position + top/left会触发大量的重排重绘,性能影响较大。

2、硬件加速的工作原理是创建一个新的复合图层,然后使用合成线程进行渲染

3、3D和2D动画的区别,2D动画会在动画开始和动画结束时触发2次重新渲染

4、使用了GPU可以优化动画小故宫但是不要滥用,会有内存问题

5、理解强制触发硬件加速的transform技巧,使用对GPU友好的CSS属性

参考文章: https://zhuanlanzhihucom/p/78230297

el-scrollbar是elementui自带的页面滚动条,如果用页面滚动条,我们发现在ie浏览器下卡顿很明显,但是用el-scrollbar滚动页面就会感觉会流畅很多,因为页面滚动会引发重排重绘,但是el-scrollbar是用transform不会引起,所以用el-scrollbar会感觉流畅很多,转订单去掉overflow:hidden就会流畅是因为这个样式会覆盖el-scrollbar的样式,

给树的父节点添加双击展开事件的方法如下:

1 首先,需要获取到树的父节点元素,可以通过 DOM 操作或者使用相关的 JavaScript 框架来获取。

2 然后,给父节点元素绑定一个双击事件的监听器,可以使用 addEventListener() 方法或者相关框架提供的事件绑定方法。

3 在双击事件的监听器中,通过操作树的展开或折叠方法来实现节点的展开或折叠功能。具体操作方法可以根据使用的树组件或框架的不同而有所差异,例如使用 jQuery Treeview 插件时,可以使用 toggle() 方法来切换节点的展开状态。

解释原因:

给树的父节点添加双击展开事件的原因是为了提供更友好的用户交互体验,使用户能够更方便地展开或折叠树的节点。通过双击父节点来展开或折叠子节点,可以减少用户的操作步骤,提高操作效率。

拓展内容:

除了双击展开事件,还可以考虑其他交互方式,例如单击加号或减号图标来展开或折叠节点,或者使用鼠标右键菜单来进行操作。根据具体需求和用户习惯,可以选择合适的交互方式来实现节点的展开和折叠功能。另外,还可以对展开和折叠过程进行动画效果的添加,以增加用户的视觉享受。

Web前端加载的方式多种多样,其所产生的HTTP请求也各异,这里我们就来列举CSS控制前端HTTP请求的各种情况示例,需要的朋友可以参考下

的http请求,有很多种情况,那么究竟什么情况下面不会发生请求呢?下面我用案例一一列举一下,希望对你深入了解http请求有所帮助。

1 隐藏

<img src="haoroomsjpg" style="display: none" />http请求如下:

结论:只有Opera不产生请求。 注意:用visibility: hidden隐藏时,在Opera下也会产生请求。

2 重复

<img src="haoroomsjpg" />

<img src="haoroomsjpg" />http请求如下:

结论:所有浏览器都只产生一次请求 。

3 重复背景

<style type="text/css">

test1 { background: url(haoroomsjpg) }

test2 { background: url(haoroomsjpg) }

</style>

<p class="test1">test1</p>

<p class="test2">test2</p>http请求如下:

结论:所有浏览器都只产生一次请求。

4 不存在的元素的背景

<style type="text/css">

test1 { background: url(haoroomsjpg) }

test2 { background: url(http2jpg) } / 页面中没有class为test2的元素 /

</style>

<p class="test1">test1</p>http请求如下:

结论:背景仅在应用的元素在页面中存在时,才会产生请求。这对CSS框架来说,很有意义。

5 隐藏元素的背景

<style type="text/css">

test1 { background: url(haoroomsjpg); display: none; }

test2 { background: url(http2jpg); visibility: hidden; }

</style>

<p class="test1">test1</p>http请求如下:

结论:Opera和Firefox对于用display: none隐藏的元素背景,不会产生HTTP请求。仅当这些元素非display: none时,才会请求背景。

6 多重背景

<style type="text/css">

test1 { background: url(haoroomsjpg); }

test1 { background: url(http2jpg); }

</style>

<p class="test1">test1</p>上面这段代码的http请求,只会请求http2jpg这一张,原因是test1的class把上面的给覆盖掉了,所有只请求后面的一张!

假如用css3多张背景的写法:

<style type="text/css">

test1 { background-image:url("haoroomsjpg"),url("http2jpg"); }

</style>

<p class="test1">test1</p>那么http请求如下:

webkit引擎浏览器对背景图都请求,是因为支持CSS3中的多背景图。

7 hover的背景加载

<style type="text/css">

atest1 { background: url(haoroomsjpg); }

atest1:hover { background: url(http2jpg); }

</style>

<a href="#" class="test1">test1</a>http请求如下:

结论:触发hover时,才会请求hover状态下的背景。不触发的话,只请求默认的背景。

8 JS里innerHTML中的

<script type="text/javascript">

var el = documentcreateElement('p');

elinnerHTML = '<img src="haoroomsjpg" />';

//documentbodyappendChild(el);

</script>http请求如下:

结论:只有Opera不会马上请求。

注意:当添加到DOM树上时,Opera才会发送请求。

9 预加载

最常用的是JS方案:

<script type="text/javascript">

new Image()src = 'haoroomsjpg';

new Image()src = 'http2jpg';

</script>在无JS支持的环境下,可以采用隐藏元素来预加载:

<img src="haoroomscomjpg" style="visibility: hidden; height: 0; width: 0" />总结

1、对于隐藏和隐藏元素的背景,Opera不会产生请求。

2、对于隐藏元素的背景,Firefox也不会产生请求。

3、对于尚未插入DOM树的img元素,Opera不会产生请求。

4、基于webkit引擎的Safari和Chrome,支持多背景图。

5、其它情景,所有主流浏览器保持一致。

希望上面的http请求对您有所帮助,大家可以相互留言交流!

这里给你列了CSS适用的一张表。

class选择器 对应的样式 适用控件

fr-texteditor 文本区域边框,字样(大小,颜色,字体等) 文本、文本域、下拉框、下拉复选框、树、日期

fr-texteditor-focus 获取焦点后的文本框的边框、字样 文本、文本域、下拉框、下拉复选框、树、日期

fr-combo-list-item 下拉项的边框、字样 下拉框、下拉复选框

fr-combo-selected 获得焦点的下拉项的字样,边框、背景色 下拉框、下拉复选框

fr-checkbox-control 全选/反选的背景、字样、边框 下拉复选框

fr-list-bwrap 列表控件的背景色 列表

fr-list-bwrap li 字样 列表

fr-list-node-over 鼠标移动上去的列表项背景色,字体颜色 列表

fr-list-node-selected 被选中的列表项的背景色,字体颜色 列表

fr-tree-body 树列表的样式(背景色、字体等) 树

fr-tree-no-lines fr-tree-elbow-plus 加号图标样式 树

fr-tree-node-collapsed fr-tree-node-icon 未展开的文件夹图标样式 树

fr-tree-no-lines fr-tree-elbow-minus 减号图标样式 树

fr-tree-node-expanded fr-tree-node-icon 已展开的文件夹图标样式 树

fr-tree-node-leaf fr-tree-node-icon 子节点图标样式 树

fr-calendar thead fr-date-top 标题行的背景颜色 日期

fr-calendar thead headrow 年月选择行的背景颜色

fr-calendar thead daynames 星期行的背景颜色

fr-calendar tfoot footrow 功能按钮行的背景颜色

fr-calendar thead hilite 置鼠标移动到日期头按钮上时的背景色,边框,字体颜色;

fr-calendar thead active 鼠标点击日期头按钮时的背景色

fr-calendar tfoot hilite 鼠标标移动到日期尾按钮上时的背景色,边框,字体颜色

fr-calendar tbody tdactive 鼠标点击日期主体按钮时的背景色

fr-calendar tbody tdselected 当前选中天的背景色,字体颜色,大小,边框;

fr-calendar tbody tdtoday 设置今天的字体颜色,大小,边框。

具体CSS的编写,你可以去看FineReport的帮助文档

在div里给它加上一个类,给新加的类写样式。

在CSS中,继承是一种非常自然的行为,我们甚至不需要考虑是否能够这样去做,但是继承也有其局限性。

首先,有些属性是不能继承的。这没有任何原因,只是因为它就是这么设置的。举个例子来说:border属性,大家都知道,border属性是用来设置元素的边框的,它就没有继承性。如下图所示,如果继承了边框属性,那么文档看起来就会很奇怪,除非采取另外的措施关掉边框的继承属性。

多数边框类属性,比如象Padding(补白),Margin(边界),背景和边框的属性都是不能继承的。

扩展资料

CSS中的样式覆盖原则:

规则一:由于继承而发生样式冲突时,最近祖先获胜(最近原则)。

strong分别从body和p中继承了color属性,但是由于p在继承树上离strong更近,因此strong中的文字最终继承p的蓝色。

规则二:继承的样式和直接指定的样式冲突时,直接指定的样式获胜(最直接原则)。

strong {color:red;} 

那么根据规则二,strong中的文字最终显示为红色。

规则三:直接指定的样式发生冲突时,样式权值高者获胜。

样式的权值取决于样式的选择器,权值定义如下表。

css选择器 权值 

标签选择器 1 

类选择器 10 

ID选择器 100 

内联样式 1000 

伪元素(:first-child等) 1 

伪类(:link等) 10 

可以看到,内联样式的权值>>ID选择器>>类选择器>>标签选择器,除此以外,后代选择器的权值为每项权值之和,比如”#nav current a”的权值为100 + 10 + 1 = 111。

1、先给一个例子,下面再做详细讲解

我钟意网页树树

--这个例子是从左向左滚动

2、各参数详解:

a) 。它表示速度,值越大速度越快。如果没有它,默认为6,建议设为1~3比较好。

b) width和height,表示滚动区域的大小,width是宽度,height是高度。特别是在做垂直滚动的时候,一定要设height的值。

c) direction。表示滚动的方向,默认为从右向左:←←←。可选的值有right、down、up。滚动方向分别为:right表示→→→,up表示↑,down表示↓。

d) scrollDelay,这也是用来控制速度的,默认为90,值越大,速度越慢。通常scrollDelay是不需要设置的。

e) behavior。用它来控制属性,默认为循环滚动,可选的值有alternate(交替滚动)、slide(幻灯片效果,指的是滚动一次,然后停止滚动)

3、根据需要设置对应的参数,就可以实现滚动啦,把想要滚动的div标签包含在marquee标签里面。

介绍 本文将介绍如何一步一步制作出一些3D效果的云彩,会用到一些高级的属性,主要是如何通过CSS的3D变换效果来实现,如果你想了解更多,这地方是个不错的开始。

静态效果图

本教程将会分成几个部分,每一部分都会有详细的步骤让你理解HTML,CSS和Javascript都是如何工作的,每一步都有衔接,以及一个链接来测试单个部分的代码效果。教程里的代码是最终demo的简化版,但是主要区别在每一部分都有说明。

1新建一个世界和视角 2向我们创建的世界里添加对象 3往我们的对象上添加层 4让3D效果运行起来 5最后总结 1新建一个世界和视角 首先,我们需要两个div元素: viewport 和 world。剩下的部分将会在后面动态的加入。

viewport 包含了整一个屏幕和一个摄影机。由于在CSS 3D变换中没有摄影机本身,就假想你在通过一个透明的玻璃屏幕来看屏幕里的视野,你也可以改变看视野的方向。我们将会把所有对象都放在里面,然后对他们进行变换。

world 是一个用来固定所有对象的 div 盒子。 旋转,转化或者放大都变换都会改变我们的元素。为简单起见,我将不使用CSS属性前缀,而是使用浏览器前缀(-webkit,-moz,-0,-ms等等)。

这就是我们需要的所有盒子模型:

下面是我们定义的两个CSS样式,这里非常重要的是要将 world div 放在 viewport div里面,否则将无法渲染场景。要记住你将旋转一个放置在文档里的元素,像其他2D元素那样。

#viewport{ bottom:0; left:0; overflow:hidden; perspective:400; position:absolute; right:0; top:0;}#world{ height: 512px; left: 50%; margin-left: -256px; margin-top: -256px; position: absolute; top: 50%; transform-style: preserve-3d; width: 512px;} 现在写一些代码来初始化我们的对象,绑定 mousemove 事件以及定义 updateView() 函数。

/ Defining our variables world and viewport are DOM elements, worldXAngle and worldYAngle are floats that hold the world rotations, d is an int that defines the distance of the world from the camera /var world = documentgetElementById( 'world' ), viewport = documentgetElementById( 'viewport' ), worldXAngle = 0, worldYAngle = 0, d = 0;/ Event listener to transform mouse position into angles from -180 to 180 degress, both vertically and horizontally/windowaddEventListener( 'mousemove', function( e ) { worldYAngle = -( 5 - ( eclientX / windowinnerWidth ) ) 180; worldXAngle = ( 5 - ( eclientY / windowinnerHeight ) ) 180; updateView();} );/ Changes the transform property of world to be translated in the Z axis by d pixels, rotated in the X axis by worldXAngle degrees and rotated in the Y axis by worldYAngle degrees/function updateView() { worldstyletransform = 'translateZ( ' + d + 'px ) \ rotateX( ' + worldXAngle + 'deg) \ rotateY( ' + worldYAngle + 'deg)';} world 是红色的,viewport 有背景色来模拟天空,mousewheel滚轮事件来监听摄影机的远近距离。移动鼠标来观察红色的 div 是如何改变方向的。

这是这一部分的演示链接

2向我们创建的世界里添加对象 现在我们开始添加真正的3D内容。我们加入一些新的 div 放置在 world 空间里。有必要添加几个绝对位置的 div 作为 world 的子节点,但是用3D变换来替代 left 和 top, 他们默认会出现在 world 的中央位置。width 和 height属性无关紧要,因为这些新的容器是放置那些真实云的层。如果正式应用里最好将他们居中(通过设置 margin-left 和 margin-top 属性 来设置 width 和 height 一半的负数值)。

cloudBase { height: 20px; left: 256px; margin-left: -10px; margin-top: -10px; position: absolute; top: 256px; width: 20px;} 我们添加 generate() 和 createCloud() 方法来充实 world。注意 random_{var} 不是真实的变量值,而是一个代码占位符,应该返回一个给定范围内的随机数。

/ objects is an array of cloud bases layers is an array of cloud layers/ var objects = [], layers = [];/ Clears the DOM of previous clouds bases and generates a new set of cloud bases/ function generate() { objects = []; layers = []; if ( worldhasChildNodes() ) { while ( worldchildNodeslength >= 1 ) { worldremoveChild( worldfirstChild ); } } for( var j = 0; j

点我来观察这部分的演示

3往我们的对象上添加层 现在有趣的事情开始发生了,我们添加了几个绝对位置的“云层” div 盒子来表示云,这些盒子将会用来装载云的贴图。

cloudLayer { height: 256px; left: 50%; margin-left: -128px; margin-top: -128px; position: absolute; top: 50%; width: 256px;} 旧的 createCloud() 函数做了一些改动,添加了云层的随机数。

/ Creates a single cloud base and adds several cloud layers Each cloud layer has random position ( x, y, z ), rotation (a) and rotation speed (s) layers[] keeps track of those divs/function createCloud() { var div = documentcreateElement( 'div' ); divclassName = 'cloudBase'; var t = 'translateX( ' + random_x + 'px ) \ translateY( ' + random_y + 'px ) \ translateZ( ' + random_z + 'px )'; divstyletransform = t; worldappendChild( div ); for( var j = 0; j 云层就是那些蓝色带有一点白色边边的部分,看起来相当有层次感呐。移动鼠标来观察下每一层的位置是怎样的以及如何旋转的。

4让3D效果运行起来 接下来就是见证奇迹的时刻!我们用 layers[] 来为世界里每一个单独的云层建立一个引用。我们用 worldXangle 和 worldYAngle 来表示整个空间的选择变换。

如果我们将每个层都设置成相反的旋转,这会在viewport里重新调整他们:我们就有一个布告板了。因为我们旋转world先是X方向然后是Y方向,我们需要反着顺序来旋转每一个层,首先是Y方向再是X方向,变换的顺序是非常重要的,如果你没有正确的设置顺序,元素的方向就都会不对了。

/ Iterate layers[], update the rotation and apply the inverse transformation currently applied to the world Notice the order in which rotations are applied/function update (){ for( var j = 0; j 点我来见证神奇的效果

最后总结 为了达到最后的效果,只需要将用来调试的那些颜色去掉,把云层 div 用一个 img 贴上云的。注意得是带有alpha通道的PNG格式,要不没效果。

点我看看最后的效果

点我看看最后版本

当然,你可以随意换其他你想要的:烟雾痕迹,等离子体云,绿叶,飞行的面包机等等。只要把 backgroud-image 更改下就好了。混合不同比例的纹理材质会有神奇的效果。

随机的添加元素是可以的,但是你也可以创建有序的结构,比如树,鸭子形状的云或者复杂的大爆炸等。可以尝试一些3D曲线,创建固定的云的运行轨迹,创造一个多人游戏来猜3D云的形状等等,充满着无限可能。

NOTE:文中的代码都是简化了的哦,如果想一步一步实际操作的话最好保存下示例效果的链接页面来查看源码。

本文译自 https://wwwclicktoreleasecom/blog/how-to-make-clouds-with-css-3d#涉及到一些3D透视等专业词汇翻译有误敬请见谅,欢迎指正。

<!DOCTYPE html>

<html>

<head>

    <style>

        div

        {

            width:100px;

            height:100px;

            background:red;

            position:absolute;

            animation:myfirst 5s;

            -webkit-animation:myfirst 5s;

            animation-fill-mode: forwards;

        }

        @-webkit-keyframes myfirst / Safari and Chrome /

        {

            0%   {background:red; left:500px; bottom:50px;}

            25%  {background:red; left:500px;height:130px;bottom:50px;}

            50%  {background:red; left:500px; height:160px;bottom:50px;}

            75%  {background:red; left:500px;height:190px; bottom:50px;}

            100% {background:red; left:500px; height:210px;bottom:50px;}

        }

    </style>

</head>

<body>

<div></div>

</body>

</html>

这只是个演示的demo,方法就是这样,animation-fill-mode: forwards;这一句给你解释下,这句就是当动画完成时,动画会停留在最后一帧。其他代码都比较简单,不懂随时问我。

希望能够帮助到你,望采纳!

浅析CSS的性能优化

下面我们来看一个动画效果(类似平时页面滚动功能),在该动画是让一个球沿着某种路径移动。最简单的方式就是实时调整它们的left和top属性...
点击下载
热门文章
    确认删除?
    回到顶部