【问题标题】:Changing transform css style causes Recalculate Style / Update Layer Tree更改变换 css 样式会导致重新计算样式/更新图层树
【发布时间】:2020-08-11 16:47:48
【问题描述】:

this example,我正在做我的(滚动)转换,希望只接触合成器,但是,在 Chrome 中检查它,重新计算样式和更新层树报告为紫色(意味着昂贵的操作) .

在此示例中,除了合成器/gpu 转换之外,我如何防止任何其他工作?

	const scroller = document.querySelector('scroller');
	const width = scroller.offsetWidth;
	const scrollWidth = scroller.scrollWidth;
	const elements = document.querySelectorAll('scrolled-item');
	scroller.addEventListener('scroll', () => {
		const scroll = scroller.scrollLeft;
		const ratio = (scroll + width) / scrollWidth;
		requestAnimationFrame(() => {
			elements.forEach(el => {
				el.firstChild.style.transform = `rotateZ(${ratio * 360}deg) rotateX(${ratio * 360}deg) scaleX(${1 - ratio})`;
			})
		})
	});
	scroller {
		display: block;
		width: 80%;
		margin-left: 10%;
		margin-top: 20%;
		overflow: auto;
		white-space: nowrap;
		font-size: 0;
		background: silver
	}
	scrolled-item {
		position: relative;
		display: inline-block;
		margin-left: 10px;
		margin-right: 10px;
		width: 40px;
		height: 40px;

	}
	scrolled-item gymnastics {
		display: block;
		position: absolute;
		top: 0; right: 0; bottom: 0; left: 0;
		background: gray;
		z-index: 1;
	}
	scrolled-item div {
		position: relative;
		text-align: center;
		font-size: 14px;
		z-index: 2;
	}
<scroller>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
	<scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
</scroller>

【问题讨论】:

  • 也许改用css变量?
  • @MisterJojo 这不是我用例的选项。我正在对视口中的每个元素应用不同的转换。
  • 这不是问题 css 变量也适用于媒体查询
  • @MisterJojo 澄清一下,这是基于元素相对于视口的位置的不同转换。媒体查询对此无能为力。
  • 你解决了吗@daniel?我们有完全相同的问题(由于滚动样式重新计算,转换失效导致重排)

标签: javascript css performance animation css-animations


【解决方案1】:

我不知道你在用视口做什么,我认为这不会成为使用 css 变量的障碍。

与此同时,这是我的想法,我没有回答有关性能的问题,但我认为这个答案在运行时比你以前的代码更快

const scroller    = document.querySelector('scroller')
  ,   element0    = scroller.querySelector('scrolled-item')
  ,   off_width   = scroller.offsetWidth
  ,   scrollWidth = scroller.scrollWidth
  ;
for (let i=0;i<58;i++)
  {
  scroller.appendChild (element0.cloneNode(true))
  }
scroller.onscroll=()=>
  {
  let scroll = scroller.scrollLeft 
    , ratio  = (scroll + off_width) / scrollWidth
    , ratioDeg = Math.fround(ratio * 360) 
    ;
  scroller.style.setProperty('--turnXZ', ratioDeg + 'deg')
  scroller.style.setProperty('--scalX', (1 - ratio))
  }
scroller {
  display: block;
  width: 80%;
  height: 70px;
  margin-left: 10%;
  margin-top: 20%;
  overflow: auto;
  white-space: nowrap;
  font-size: 0;
  background: silver;
  --turnXZ : 0deg;
  --scalX  : 1;
}
scrolled-item {
  position: relative;
  display: inline-block;
  margin-left: 10px;
  margin-right: 10px;
  width: 40px;
  height: 40px;
}
scrolled-item gymnastics {
  display: block;
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background: rgba(50, 47, 209, 0.658);
  z-index: 1;
  transform: scaleX(var(--scalX)) rotateX(var(--turnXZ) ) rotateZ(var(--turnXZ) );
}
scrolled-item div {
  position: relative;
  text-align: center;
  font-size: 14px;
  z-index: 2;
}
<scroller>
  <scrolled-item><gymnastics></gymnastics><div>do</div></scrolled-item>
</scroller>

【讨论】:

猜你喜欢
  • 2014-09-28
  • 1970-01-01
  • 2017-03-01
  • 2018-08-27
  • 2013-11-02
  • 1970-01-01
  • 2018-04-07
  • 1970-01-01
  • 2012-08-07
相关资源
最近更新 更多