Javascript 浏览器中的滚动位置(scrollTop)硬件是否加速?

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'

我最初的猜测是答案是否定的,因为这里提供了证据:

我可以定性地注意到,“硬件加速”版本在我的电脑上滚动更平滑。我运行一个120Hz的监视器。这表明第二种方法更快、更有效

对于HTML元素,例如

<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
是支持硬件加速的浏览器中唯一的硬件加速

  • Firefox 4.0 beta 5支持硬件加速
  • IE 9 beta版支持硬件加速
  • 铬6+支持HW加速合成
  • Safari和Opera尚未支持硬件加速

    这是根据2010年的这一页

    根据,Opera 12支持硬件加速

    根据TechCrunch,Safari5 for Windows支持硬件加速

    根据苹果Safari的网站,Safari6支持硬件加速

    对不起!我有TechCrunch文章和Safari网站的链接,但我只能使用两个超链接

    编辑:

    为了更好地回答这个问题,我补充了这个问题使用CSS3进行滚动的最有效方法是
    溢出:滚动
    溢出-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);
        });
    }