"This site appears to use a scroll-linked positioning effect. This may not work well with asynchron



Firefox给了我这个不寻常的警告。它所指的定位效果是作为滚动高度因子的div I旋转。我从来没有遇到过任何问题,但这是我应该关心的事情吗?如果没有这个警告,会有这样的影响吗?演示这个问题的JavaScript是:

$('.gear').css({
   'transition': 'transform 1s ease-out',
   '-webkit-transform': 'rotate(' + Math.round(wScroll / 2) + 'deg)',
   '-moz-transform': 'rotate(' + Math.round(wScroll / 2) + 'deg)',
   '-ms-transform': 'rotate(' + Math.round(wScroll / 2) + 'deg)',
   'transform': 'rotate(' + Math.round(wScroll / 2) + 'deg)',
});
  • wScroll是当前滚动高度

我认为,警告继续说:

看见https://developer.mozilla.org/docs/Mozilla/Performance/ScrollLinkedEffects了解更多详细信息,并加入有关相关工具和功能的讨论!

2021年更新:文档已移至https://firefox-source-docs.mozilla.org/performance/scroll-linked_effects.html)

但如果这个页面不清楚,下面是它的要点

";"异步平移";是这样的吗:当页面滚动时,浏览器会调用scroll处理程序,但它也会异步地在新的滚动点绘制页面。这样做是为了使滚动显示响应性(@60 FPS),即使主线程繁忙超过16ms。

这意味着处理程序实现的效果不能保证与当前滚动位置同步。也就是说,滚动是平滑的,但

你的div以较小的FPS旋转——看起来janky,不平滑 Update,错过了示例中的transition效果——旋转本身也会很平滑,但它可能会在页面开始滚动之前开始。

我认为,如果没有这个问题,你就无法实现目前可用技术的确切效果。

示例

(请注意,要查看APZ的运行情况,您需要在启用APZ的情况下运行Firefox版本。特别是,这需要Firefox以多进程("e10s")模式运行,而此时该模式仍不在发布版本中。)

window.onscroll = function() {
  var wScroll = document.documentElement.scrollTop;
  document.getElementById("gear-css").style.transform = 'rotate(' + Math.round(wScroll / 2) + 'deg)';
  document.getElementById("gear-js") .style.transform = 'rotate(' + Math.round(wScroll / 2) + 'deg)';
  document.getElementById("gear-js").textContent = leftPad(wScroll+'', '0', 4);
  setTimeout(slowdown(500), 0);
};
function leftPad(s, ch, maxLen) { return ch.repeat(maxLen - s.length) + s; }
function slowdown(timeMs) {
  return function() {
    var start = Date.now();
    var j = "";
    for (var i = 0; (Date.now() - start < timeMs); i++)
      j = j+(start+"")*i;
  }
}

window.onload = function() {
  for (let i = 0; i < 15; i++) {
    var p = document.createElement("p");
    p.innerText = `Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
          tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
          quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
          consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
          cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
          proident, sunt in culpa qui officia deserunt mollit anim id est laborum.`;
    document.documentElement.appendChild(p);
  }
}
#gear-css, #gear-js {
  border: solid black 1px;
}
#gear-css {
  transition: transform 1s ease-out
}
<div style="position: fixed; top: 0; right: 0; padding: 3em;">
  <div id="gear-css">ooo</div>
  <div id="gear-js">ooo</div>
</div>

我知道这个问题是不久前提出的,但是性能问题仍然存在。下面是一个不依赖滚动事件侦听器的替代解决方案。这最大限度地减少了由web浏览器中常见的单独滚动线程引起的jank和滞后,定期更新css,而不是在滚动窗口时更新。这意味着开发控制台警告将不会显示。我个人不会太担心警告或使用滚动事件处理小事情,比如转动齿轮或更改css类,然而,如果用户体验直接依赖于效果,它会破坏页面的可用性。

var gear;
var lastPosition;
var refreshRate = 60; // fps; reduce for less overhead
var animation = "rotate(*deg)"; // css style to apply [Wildcard is *]
var link = 0.5; //what to multiply the scrollTop by
function replace(){
    if(lastPosition != document.body.scrollTop){ // Prevents unnecessary recursion
        lastPosition = document.body.scrollTop; // updates the last position to current
        gear.style.transform = animation.replace("*", Math.round(lastPosition * link)); // applies new style to the gear
    }
}
function setup(){
    lastPosition = document.body.scrollTop;
    gear = document.querySelector(".gear");
    setInterval(replace, 1000 / refreshRate); // 1000 / 60 = 16.666... Invokes function "replace" to update for each frame
}
window.addEventListener("DOMContentLoaded", setup);

一个工作示例可以在我的GitHub上使用。我已经在Firefox、Chrome和Edge上测试过了。

避免警告的其他选择是使用css粘性元素或使用限制到window.oncroll事件的element.classList.add()和element.classList.remove()方法。

注意:如果转换的长度大于脚本更新css样式的间隔(例如滚动基于事件的更改),请小心使用css转换。基于Webkit的浏览器和EdgeHTML会以意想不到的方式出现这种情况,通常会停留在初始位置,直到脚本停止更新元素。除非这是你想要的效果,否则在这种情况下,它在firefox中的工作方式就不一样了。

当Servo Webrender集成到Firefox中时,将在一定程度上解决这些问题(或者至少显著提高性能)。尽管仍将有其他浏览器与保持兼容性。

最好的解决方案是一个开关和一个定时器我在这里展示了当你使用"滚动"时解决相同错误的答案,我建议你根据你的需要改编我的剧本!https://stackoverflow.com/a/57641938/5781320

相关内容

最新更新