Chrome使用固定位置元素进行慢速滚动

Ada*_*dam 41 html css google-chrome

在我的顶部有一个固定的DIV,3个固定的标签和底部的固定div(这将在登录时显示 - 将来).

我在Chrome上的滚动性能很差 - FF和IE都很好.

我已准备好一些关于Chrome,固定定位和滚动的问题报告,想看看是否有人有任何建议?我真的想在他们的位置修复这些元素,但我也希望在Chrome中有良好的滚动性能.

关于修复的任何想法?

注意:放大chrome时更加明显......

更新:我已阅读其他人有类似问题并更新了此Chrome问题,后来又合并到136555,据称自Chrome 26以来已修复.

cor*_*ulu 84

问题以及如何监控它

这是因为Chrome由于某些原因决定在固定面板越过它时需要重新编码和调整任何图像的大小.你可以很好地看到这一点

右键单击 检查时间线➔按 ⏺录制

►返回页面并上下拖动滚动条(鼠标滚轮滚动效果不佳)

编辑(2016年9月1日):自发布此消息后,Chrome添加了新功能以帮助监控:

右键单击 检查渲染(底部标签)

      ☑滚动性能问题
      ☑油漆闪烁
      ☑FPS仪表(不太重要,但可能是有用的)

这将帮助您准确识别哪些元素需要在卷轴上重新绘制并在屏幕上清晰地突出显示.

这似乎只是Chrome用于确定是否需要重新绘制较低元素的方法的问题.

更糟糕的是,您甚至无法通过在可滚动div上方创建div来避免使用该position:fixed属性.这实际上会产生同样的效果.几乎Chrome都说如果页面上的任何内容都必须在图像上绘制(即使在iframe,div或其他任何内容中),请重新绘制该图像.因此,尽管您正在滚动它的div/frame,问题仍然存在.

.

Easy Hack解决方案

但我确实发现了一个黑客来解决这个似乎没什么缺点的问题.

通过将以下内容添加到固定元素中

/* Edit (9/1/2016): Seems translate3d works better than translatez(0) on some devices */
-webkit-transform: translate3d(0, 0, 0);
Run Code Online (Sandbox Code Playgroud)

某些浏览器可能需要这样来防止闪烁

-webkit-backface-visibility: hidden;
-webkit-perspective: 1000;
Run Code Online (Sandbox Code Playgroud)

这会将固定元素放在其自己的合成层中,并强制浏览器使用GPU加速.

编辑: albb向我指出了一个潜在的问题 ; 使用时 ,所有后代 元素将固定到该合成图层而不是整个页面.transformposition:fixed

.

替代方案

或者,您可以在滚动时隐藏顶部导航,然后将其重新导入.下面是一个可以在stackoverflow.com的标题或者像theverge.com这样的网站上工作的例子,如果粘贴在DevTools> Console中(或者在这个页面的URL栏中手动输入" javascript: "并粘贴在下面的代码之后)点击进入):

/* Inject some CSS to fix the header to the top and hide it
 * when adding a 'header.hidden' class name. */
var css= document.createElement("style");
css.type = 'text/css'; 
css.innerHTML = 'header { transition: top .20s !important; }';
css.innerHTML += 'header.hideOnScroll { top: -55px !important; }';
css.innerHTML += 'header { top: 0 !important; position: fixed !important; }';
document.head.appendChild(css);

var header = document.querySelector("header");
var reinsertId = null; /* will be null if header is not hidden */

window.onscroll = function() {
    if(!reinsertId) { 
      /* Hides header on scroll */
      header.classList.add("hideOnScroll");
      setTimeout(function() { header.style.visibility = "hidden"; }, 250);
    } else {
      /* Resets the re-insert timeout function */
      clearTimeout(reinsertId);
    }
    /* Re-insert timeout function */
    reinsertId = setTimeout(function(){
      header.classList.remove("hideOnScroll");
      header.style.visibility = "visible";
      reinsertId = null;
    }, 1500);
};
Run Code Online (Sandbox Code Playgroud)

  • “ -webkit-transform”的一个缺点是“位置:固定;”。后代会将其用作容器,而不是屏幕。https://bugs.webkit.org/show_bug.cgi?id=110478将这些元素移出,一切正常。 (2认同)

Mag*_*ork 17

@Corylulu的第一个解决方案有效,但不完全(仍然有点断断续续,但更少).我还必须添加-webkit-backface-visibility: hidden;固定元素,以免口吃.

所以对我来说,当在页面上使用固定元素时,以下工作就像一个魅力,以防止在Chrome中向下滚动:

-webkit-transform: translateZ(0);
-webkit-backface-visibility: hidden;
Run Code Online (Sandbox Code Playgroud)

编辑:Webkit变换和webkit-backface-visibility都会导致模糊的字体和图像.因此,请确保仅在悬停状态下同时应用这两种状态.


BBe*_*eta 5

将此规则添加到固定元素,

will-change: transform;
Run Code Online (Sandbox Code Playgroud)

阅读关于从溶液这里,
并了解将改变物业在这里.


Ale*_*ust 1

有多种方法可以加速这个前端,尝试使用PageSpeed Insights Chrome 插件来获取一些想法。就我个人而言,我建议在Twitter 的 Bootstrap等框架之上使用相同的设计重建此前端,但如果您想了解此前端的一些细节:

  • 正如你所说,标题栏的定位导致 CSS 渲染花费最多时间(CSS 压力测试结果)。去掉其中的大图像,并将其替换为 1 像素宽的背景图像。您还不必要地调整了徽标等图像(以及此标题中的所有其他图像)的大小,请替换为实际大小的版本
  • 通过优化所有内容图像,您可以节省传输的大量字节