web-dev-qa-db-ja.com

「このサイトはスクロールリンクのポジショニング効果を使用しているようです。これは非同期パンニングではうまく機能しない可能性があります」

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は現在のスクロールの高さです
26
Michael Hancock

警告は次のように言っていると思います。

... https://developer.mozilla.org/docs/Mozilla/Performance/ScrollLinkedEffects を参照して、詳細を確認し、関連するツールと機能に関する議論に参加してください!

しかし、そのページが不明瞭な場合、ここに要点があります。

「非同期パン」の考え方は次のとおりです。ページがスクロールされると、ブラウザーはscrollハンドラーを呼び出しますが、同時にasynchronouslyでページをペイントしますスクロールポイント。これは、メインスレッドが16ミリ秒以上ビジーである場合でも、スクロールが応答するように見えるように(@ 60 FPS)行われます。

つまり、ハンドラーが実装する効果は、現在のスクロール位置と同期しているとは限りません。つまりスクロールはスムーズですが、 あなたのdivはより小さいFPSで回転します-janky、滑らかでないように見えます。 Update、例の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>
18
Nickolay

しばらく前にこの質問が尋ねられたことは知っていますが、パフォーマンスの問題はまだ存在しています。以下は、スクロールイベントリスナーに依存しない代替ソリューションです。これにより、Webブラウザーに共通の個別のスクロールスレッドによって引き起こされるジャンクとラグが最小限に抑えられ、ウィンドウがスクロールされるときではなく定期的に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 and Edge(works))。

警告を回避する他の代替方法は、 css sticky elements を使用するか、element.classList.add()およびelement.classList.remove()メソッドは、window.onscrollイベントにリンクされています。

注:CSSの遷移を使用する際は、遷移の長さがスクリプトによってCSSスタイルが更新される間隔よりも長いことに注意してください(例:スクロールイベントベースの変更と同様)。 WebkitベースのブラウザーとEdgeHTMLは、これに対して予期しない方法で動作し、通常、スクリプトによる要素の更新が停止するまで初期位置にとどまります。これが意図した効果でない限り、Firefoxでは同じようには機能しません。

Servo WebrenderをFirefoxに統合すると、これらの問題がある程度解決されます(または、少なくともパフォーマンスが大幅に向上します)。ただし、互換性を維持するためのブラウザは他にもあります。

3
QWERTYUIOPYOZO

最良の解決策はスイッチとタイマーです。ここで答えを公開すると、「on scroll」を使用するときに同じエラーを解決できます。スクリプトをニーズに合わせて調整することをお勧めします。 https://stackoverflow.com/a/57641938/578132

0
Constantin