加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 资源网站 > 资源 > 正文

html – 为什么过渡框阴影导致整页重绘?

发布时间:2020-12-14 22:32:11 所属栏目:资源 来源:网络整理
导读:当我在一个带有动画盒子阴影的元素上盘旋时,我注意到我的页面已经滞后了.使用Chrome的Devtools,我注意到当我在元素上盘旋时整个页面都被重新绘制.重绘时间为40毫秒,约为3帧.过渡持续约半秒,因此在半秒内有明显的滞后. 如何将重绘限制为仅具有框阴影的区域?
当我在一个带有动画盒子阴影的元素上盘旋时,我注意到我的页面已经滞后了.使用Chrome的Devtools,我注意到当我在元素上盘旋时整个页面都被重新绘制.重绘时间为40毫秒,约为3帧.过渡持续约半秒,因此在半秒内有明显的滞后.

如何将重绘限制为仅具有框阴影的区域?

这是一个演示:http://jsfiddle.net/8sa41xfL/

html,body{
    height:100%;
}

#test{
    background:red;
    height:100px;
    width:200px;
    transition:box-shadow 0.5s;
}

#test:hover{
    box-shadow:0 0 3px 3px rgba(0,0.3);
}
<div id=test></div>

transform:translateZ(0)在我的页面上不起作用,但它适用于小提琴.除了变换还有另一种解决方法:translateZ(0)?

解决方法

正如在皮埃尔的答案框中链接的线程中所提到的,阴影涂漆很昂贵.解释为什么它很昂贵需要深入了解渲染的工作方式,而我没有足够的知识来完全解释它.但是这个答案试图解释为什么整个页面被重新绘制以及各种可能的方法来避免它.

根据CSS Triggers website:

Changing box-shadow does not trigger any geometry changes,which is good. But since it is a visual property,it will cause painting to occur. Painting is typically a super expensive operation,so you should be cautious.

Once any pixels have been painted the page will be composited together.

为什么每次都要重新粉刷整个页面?

以下文章解释了绘画在高层次上的实际运作方式:

> HTML5 Rocks – How Browsers Work – Painting
> The Chromium Project – GPU accelerated rendering in Chrome

基于这些文章,我们可以看到DOM树中生成可视输出的每个节点都被视为RenderObject,并且每个RenderObject直接或间接地是RenderLayer的一部分.每当发生更改时,渲染器(或渲染对象)都会使其屏幕上的矩形(或RenderLayer)无效并触发重绘.

在这种情况下,似乎整个页面都被重新绘制,因为#test元素不保证创建单独的RenderLayer(基于Chromium Project文章中提到的标准),因此成为根渲染层的一部分.因为它是根渲染层的一部分,所以每次需要重绘时整个页面都会重新绘制.

以下代码段证明上述断言是正确的.在这里,我添加了一个#cover元素(带有定位)来包含#test元素.现在,由于#cover元素具有显式定位,它会在根层上方创建一个额外的层,而#test将成为此中间层的一部分.现在,我们可以看到box-shadow转换只重绘了这个中间层而不是整个页面.

html,body {
  height: 100%;
}
#cover {
  position: relative;
}
#test {
  background: red;
  height: 100px;
  width: 200px;
  transition: box-shadow 0.5s;
}
#test:hover {
  box-shadow: 0 0 3px 3px rgba(0,0.3);
}
<div id=cover>
  <div id=test></div>
</div>

解决办法是什么?

有各种CSS属性可以用来解决这个问题,但它们似乎都指向高级别的相同点 – 也就是说,为#test元素创建一个单独的渲染层.

以下是为#test元素创建单独渲染层的几个可能选项:

>通过添加显式位置属性 – 这与Pierre的答案中描述的选项相同,但绝对定位不是唯一的选择.即使是相对定位也能解决它.

html,body {
  height: 100%;
}
#test {
  position: relative;
  background: red;
  height: 100px;
  width: 200px;
  transition: box-shadow 0.5s;
}
#test:hover {
  box-shadow: 0 0 3px 3px rgba(0,0.3);
}
<div id=test></div>

>通过添加透明度(不透明度) – 浏览器似乎甚至可以处理不透明度:0.99作为添加透明度,它非常有用,因为添加它不会导致任何视觉差异.

html,body {
  height: 100%;
}
#test {
  background: red;
  height: 100px;
  width: 200px;
  opacity: 0.99;
  transition: box-shadow 0.5s;
}
#test:hover {
  box-shadow: 0 0 3px 3px rgba(0,0.3);
}
<div id=test></div>

>通过添加虚拟CSS过滤器 – 我们可以添加一个过滤器:blur(0px),因为它什么都不做.

html,body {
  height: 100%;
}
#test {
  background: red;
  height: 100px;
  width: 200px;
  -webkit-filter: blur(0px);
  filter: blur(0px);
  transition: box-shadow 0.5s;
}
#test:hover {
  box-shadow: 0 0 3px 3px rgba(0,0.3);
}
<div id=test></div>

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读