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

时间:2012-08-17 23:35:07

标签: javascript performance html5 css3 gpu

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

https://github.com/inuyaksa/jquery.nicescroll/wiki/Native-scroll-vs-Hardware-accelerated-one

我可以定性地注意到“硬件加速”版本在我的计算机上滚动得更顺畅。我运行一个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>

我认为实现3D硬件加速布局的一种简单方法是渲染div的整个高度,然后将此输出作为整个高度的纹理加载,然后用于渲染实际的纹理坐标div一次只能显示100px。

我的问题与scrollTop属性在理论上应如何做到这一点有关,但似乎目前通过使用TWO元素获得我描述的行为的可能性要大得多:

<div id="a" style="overflow-y: hidden; height: 100px; position: relative">
    <div style="position: relative">
        Content <em>which exceeds 100px in height</em>
        <img src='lolcat.png' alt='lolcat'/>
    </div>
</div>

我没有设置scrollTop的{​​{1}}属性,而是将CCS3 document.getElementById('a')属性设置为具有相应负Y轴像素值的3D值。

使用CSS3进行滚动的最有效方法是什么?特别是,我如何构建我的DOM以最有可能获得最直接的滚动实现(不会导致重新绘制)滚动元素时的内部内容)?

更新:我一直在为Chrome使用一个非常漂亮的平滑滚动插件,它似乎使用JS在页面上分配scrollTop偏移来实现滚动渲染,这似乎表明如果这不是硬件加速,在没有大量CPU使用的情况下,性能无法真正跟上屏幕刷新率(120Hz)。尽管如此,这种猜测仍然极不科学。我在这一点上得出的结论是,浏览器可以自由地加速他们在合理范围内选择的任何内容,因此答案是响亮的也许

3 个答案:

答案 0 :(得分:5)

根据您提到的页面,硬件加速取决于浏览器是否支持硬件加速。

  

Div with wrapper可以加速。 (如果浏览器支持它)

所以我认为你嵌套两个div的想法将创造一种更容易实现你想要的方式。但要回答您的问题,scrollTop仅在支持硬件加速的浏览器中进行硬件加速。

  1. Firefox 4.0 beta 5 支持硬件加速。
  2. IE 9 beta 支持硬件加速。
  3. Chrome 6 + 支持硬件加速合成
  4. Safari和Opera尚未支持硬件加速。

    这是根据2010年的这一页。http://www.webmonkey.com/2010/09/a-guide-to-hardware-acceleration-in-modern-browsers/

    根据http://arstechnica.com/information-technology/2012/06/opera-12-arrives-with-webcam-apis-and-experimental-webgl-support/ Opera 12 支持硬件加速。

    根据TechCrunch,适用于Windows的Safari 5 支持硬件加速。

    根据Apple Safari的网站, Safari 6 支持硬件加速。

    抱歉!我有TechCrunch文章和Safari网站的链接,但我只能使用两个超链接。

    修改

    为了更好地回答这个问题,我补充说。 使用CSS3进行滚动的最有效方法是overflow: scroll;overflow-x: scroll; overflow: CSS属性比scrollTop更高效的CSS,因为{{ 1}}是一个jQuery标记,它使用JavaScript。所以使用scrollTop不是CSS,它是JavaScript。此外,使用CSS也是实现水平滚动的最简单方法,因为它不需要导入jQuery库或启用JavaScript。

    我完全同意你的观点,即通过使用两个scrollTop标签和CSS而不是使用jQuery / JavaScript,获得所描述的行为的可能性要大得多。

    除非,您希望能够自动滚动到其他位置,使用div时,您可以使用按钮或链接有效滚动到其他位置。

    scrollTop

    这个使用$(document).ready(function() { $('a[href=#top]').click(function(){ $('html, body').animate({scrollTop:0}, 'slow'); return false; }); }); 的jQuery代码使所有scrollTop动画滚动到顶部,而不仅仅是跳跃。使用CSS滚动时,您不会获得这些动画卷轴。此外,您可以使用此方法通过设置多个<a href="#top">top</a>标记的ID并编辑上述代码来水平或垂直滚动​​到不同的点以满足您的需要。这来自http://www.electrictoolbox.com/jquery-scroll-top/

答案 1 :(得分:3)

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。 translate3d()的第二个参数除以容器的高度将是滚动条在轨迹栏方面的位置(百分比)。

答案 2 :(得分:0)

document.getElementById("a").scrollTop效率更高,因为它已存在更长时间。浏览器已经有超过10年的时间来优化它。