"Этот сайт, похоже, использует эффект позиционирования, связанный с прокруткой. Это может плохо работать с асинхронным панорамированием"

Мне было предоставлено это необычное предупреждение от Firefox. Эффект позиционирования, на который он ссылается, является div я вращаю как фактор высоты прокрутки. У меня никогда не было никаких проблем с этим, но разве это меня беспокоит? Есть ли в любом случае такие эффекты без этого предупреждения? JavaScript, который демонстрирует эту проблему:

//Rotate gears in about section
    $('.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 - текущая высота прокрутки

Ответы

Ответ 1

Предупреждение, я думаю, продолжает:

... см. https://developer.mozilla.org/docs/Mozilla/Performance/ScrollLinkedEffects для получения дополнительной информации и присоединиться к обсуждению связанных инструментов и функций!

Но в случае, если эта страница неясна, вот ее суть.

Идея "асинхронного панорамирования" такова: при прокрутке страницы браузер вызывает ваш обработчик scroll, но он также асинхронно рисует страницу в новой точке прокрутки. Это делается для того, чтобы прокрутка выглядела отзывчивой (@60 FPS), даже когда основной поток занят больше 16 мс.

Это означает, что эффекты, выполняемые вашим обработчиком, не гарантируются в синхронизации с текущей полосой прокрутки. Т.е. прокрутка гладкая, но ваши divs вращаются с меньшим FPS - появляются janky, non-smooth. Обновление, пропустило эффект transition в вашем примере - само вращение также будет плавным, но оно может начаться позже, чем начнется прокрутка страницы.

Я не думаю, что вы можете реализовать точный эффект, который у вас есть с имеющимися в настоящее время технологиями, без этой проблемы.

пример

(Обратите внимание, что для просмотра 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>

Ответ 2

Я знаю, что этот вопрос был задан некоторое время назад, однако проблема с производительностью все еще существует. Ниже представлено альтернативное решение, которое не зависит от прослушивателя событий прокрутки. Это сводит к минимуму зависание и задержку, вызванные отдельной прокруткой, распространенной среди веб-браузеров, обновление 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 или использование методов element.classList.add() и element.classList.remove(), ограниченных событием window.onscroll.

Примечание. Будьте осторожны с использованием css-переходов, где длина перехода длиннее интервала, в котором стиль CSS будет обновляться скриптом (например, с изменениями на основе прокрутки). Браузеры на основе Webkit и EdgeHTML будут вести себя непредсказуемыми способами, обычно оставаясь в исходном положении до тех пор, пока элемент перестанет обновляться сценарием. Если это не эффект, который вы намеревались, в этом случае он не работает так же в firefox.

Servo Webrender, интегрированный в Firefox, решит эти проблемы до некоторой степени (или, по крайней мере, значительно улучшит производительность). Хотя для совместимости с другими браузерами все еще останутся.

Ответ 3

лучшее решение - это переключатель и таймер я выставляю здесь ответ, чтобы решить ту же ошибку, когда вы используете "на прокрутке", Я предлагаю вам адаптировать мой сценарий к вашим потребностям!fooobar.com/info/15715333/...