Javascript 浏览器中的滚动位置(scrollTop)硬件是否加速?
我最初的猜测是答案是否定的,因为这里提供了证据: 我可以定性地注意到,“硬件加速”版本在我的电脑上滚动更平滑。我运行一个120Hz的监视器。这表明第二种方法更快、更有效 对于HTML元素,例如Javascript 浏览器中的滚动位置(scrollTop)硬件是否加速?,javascript,performance,html,css,gpu,Javascript,Performance,Html,Css,Gpu,我最初的猜测是答案是否定的,因为这里提供了证据: 我可以定性地注意到,“硬件加速”版本在我的电脑上滚动更平滑。我运行一个120Hz的监视器。这表明第二种方法更快、更有效 对于HTML元素,例如 <div id="a" style="overflow-y: hidden; height: 100px"> Content <em>which exceeds 100px in height</em> <img src='lolcat.png'
<div id="a" style="overflow-y: hidden; height: 100px">
Content <em>which exceeds 100px in height</em>
<img src='lolcat.png' alt='lolcat'/>
</div>
其中,我没有设置document.getElementById('a')
的scrollTop
属性,而是将CCS3-webkit/moz/ms/o-transform
属性设置为具有相应负Y轴像素值的3D值
使用CSS3进行滚动的最有效方法是什么?特别是,我如何构造DOM,以获得最直接的滚动实现(滚动元素时不会导致内部内容的重新绘制)
更新:我一直在为Chrome使用一个非常好的平滑滚动插件,它似乎使用JS来分配页面上的scrollTop偏移量来实现滚动渲染,这似乎表明如果不是硬件加速,如果没有大量CPU使用,性能就无法真正跟上屏幕刷新率(120Hz)。尽管如此,这种猜测仍然极不科学。在这一点上,我的结论是,浏览器有自由在合理范围内加速他们选择的任何东西,因此答案可能是响亮的。根据您提到的页面,硬件加速取决于浏览器是否支持硬件加速 带包装器的Div可以被硬件加速。(如果浏览器支持它) 因此,我认为您嵌套两个div的想法将创建一个更容易实现您想要的方法。但要回答您的问题,
scrollTop
是支持硬件加速的浏览器中唯一的硬件加速
溢出:滚动代码>或溢出-x:滚动
溢出:CSS属性比scrollTop
更有效,因为scrollTop
是一个jQuery标记,它使用JavaScript。所以使用scrollTop
不是CSS,而是JavaScript。另外,使用CSS也是实现水平滚动的最直接的方法,因为它不需要导入jQuery库或启用JavaScript
我完全同意你的说法,通过使用两个div
标记和CSS而不是使用jQuery/JavaScript,获得你描述的行为的机会要大得多
除非您希望能够自动滚动到另一个位置,否则在使用scrollTop
时,您可以使用按钮或链接有效地滚动到不同的位置
$(document).ready(function() {
$('a[href=#top]').click(function(){
$('html, body').animate({scrollTop:0}, 'slow');
return false;
});
});
此jQuery代码使用
scrollTop
使所有
动画化滚动到顶部,而不仅仅是跳跃。当使用CSS滚动时,您不会得到这些动画滚动。此外,通过设置多个div
标记的ID并编辑上述代码以满足您的需要,您可以使用此方法水平或垂直滚动到不同的点。这是来自。document.getElementById(“a”)。scrollTop
更高效,因为它已经存在了更长的时间。浏览器已经有超过10年的时间来优化它。scrollTop
不是硬件加速的。我发现,即使在移动设备上也能产生平滑滚动的最好方法是强制css3硬件加速并结合转换
我假设您有jQuery,所以为了清晰起见,我使用该语法,我所做的只是设置css属性和其他基本调用
var $body = $('body');
function scrollTop(scrollPosition) {
// account for the current scroll position
var scrollDiff = $body.scrollTop() - scrollPosition;
// use css transition
$body.css('transition', '.5s');
// translate3d forces hardware acceleration, second param is 'y'
$body.css('transform', 'translate3d(0, ' + scrollDiff + 'px, 0)');
// revert back to native scrollTop
$body.bind('transitionend webkitTransitionEnd', function(event) {
$body
.scrollTop(scrollPosition)
.css({'transition': '', 'transform': ''})
.unbind(event);
});
}
注意:我确实注意到
transitionend
事件在移动设备上并不总是可靠的;这使得代码中的“恢复到本机scrollTop”部分出现故障。我认为最好的方法是更进一步,在不使用scrollTop的情况下实现自己的scrollbar。translate3d()
的第二个参数除以容器的高度将是滚动条在轨迹栏中的位置(百分比)。这并没有解释在所有支持硬件加速的浏览器中,使用scrollTop
滚动与使用嵌套转换元素相比效率较低。这只会在移动平台上起到显著的作用(这就限制了我们真正使用webkit)。@StevenLu我编辑了我的答案,以便更好地回答这个问题。谢谢你向我指出这一点!我的经验是相反的,至少在Android上的WebView是这样。更改scrollTop
会更改DOM,这非常缓慢,因为它需要重新绘制所有受影响的分幅。另一方面,更改css(transform)
,除了在(已经存在的)硬件层上更改转换之外,不需要任何工作。@ephmient我相信这就是我所说的。使用scrollTop
需要JavaScript,并且比仅使用CSS要慢。你说得对,更改CSS只需要更改转换就可以了
var $body = $('body');
function scrollTop(scrollPosition) {
// account for the current scroll position
var scrollDiff = $body.scrollTop() - scrollPosition;
// use css transition
$body.css('transition', '.5s');
// translate3d forces hardware acceleration, second param is 'y'
$body.css('transform', 'translate3d(0, ' + scrollDiff + 'px, 0)');
// revert back to native scrollTop
$body.bind('transitionend webkitTransitionEnd', function(event) {
$body
.scrollTop(scrollPosition)
.css({'transition': '', 'transform': ''})
.unbind(event);
});
}