我有一个元素,我正在应用一些基于滚动位置的基本过渡.它在Safari和Firefox中按预期顺利运行,但在Chrome中滚动非常不稳定.
$(document).ready(function($) { var divUp = $('.fade'); var divDown = $('.fade-down'); $(window).on('scroll',function() { var st = $(this).scrollTop(); divUp.css({ 'top' : -(st/6)+"px",'opacity' : 1 - st/400 }); divDown.css({ 'opacity' : 1 - st/400 }); }); });
我单独注释掉了每个CSS属性,但Chrome无论如何都是不稳定的. top属性正在移动一个相对定位的元素.
如何在让Chrome的JS引擎满意的同时达到预期的效果?提前感谢您的任何反馈.
解决方法
你遇到了
layout thrashing.
更改元素的top属性会使当前的layout无效.通常,这会提示浏览器异步重新计算布局(即不立即重新计算).
但是,调用scrollTop forces the browser to re-layout synchronously.因为你在滚动事件处理程序中调用它,这在很短的时间内反复发生.这种DOM写入读取序列是jank的已知原因.
要提高性能,您需要防止布局颠簸.更改CSS变换(和不透明度)属性does not invalidate the browser’s layout – 它们只需要composite,这要快得多.
如果为变换设置动画:translateY而不是top,则浏览器不需要在每个动画帧上计算昂贵的计算:
divUp.css({ 'transform': 'translateY( ' + (-(st/6)) + 'px)','opacity': 1 - st/400 });
您可以通过设置CSS will-change属性来帮助浏览器优化转换:
.your-div { will-change: transform; }
进一步阅读:
> Jank free – 关于改善Web应用程序性能的文章
> CSS Triggers – 列出每个CSS属性更改时浏览器需要执行的步骤