[Webkit-unassigned] [Bug 261692] New: DOM mutation and changing scrollTop updates the UI in 2 passes causing glitches

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Mon Sep 18 12:23:35 PDT 2023


https://bugs.webkit.org/show_bug.cgi?id=261692

            Bug ID: 261692
           Summary: DOM mutation and changing scrollTop updates the UI in
                    2 passes causing glitches
           Product: WebKit
           Version: WebKit Nightly Build
          Hardware: Unspecified
                OS: Unspecified
            Status: NEW
          Severity: Normal
          Priority: P2
         Component: Layout and Rendering
          Assignee: webkit-unassigned at lists.webkit.org
          Reporter: martinbooth at fb.com
                CC: bfulgham at webkit.org, simon.fraser at apple.com,
                    zalan at apple.com

Created attachment 467743

  --> https://bugs.webkit.org/attachment.cgi?id=467743&action=review

Screen recording of the issue

A pretty common pattern is to load more content as a user scrolls up or down, and to do that when a user scrolls up, it's necessary to apply a "correction" to the scroll position when inserting new content so that it appears to the user that it is in the same place

In other browsers, it's possible to insert new dom content and change the scrollTop so that the user does not see these 2 actions happening separately, but with safari/webkit the new scroll position is rendered first, followed by the new content (despite the javascript actually doing these things the other way round)


The following is a repro of the issue.. as you scroll up, more content is loaded, but the screen jumps around


<html>
<style>
  body {
    padding: 0;
    margin: 0
  }

  #scrollarea {
    height: 100%;
    border: 1px solid black;
    width: 100%;
    position: absolute;
    overflow: scroll;
    overflow-anchor: none;
  }

  .row {
    padding: 5px;
    margin: 5px;
  }
</style>



<body>
  <div id="scrollarea"></div>
  <script>
    const text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam elit mi, mattis dictum placerat vel, lacinia nec metus. Etiam eu nunc ut sapien tempus luctus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque eget libero ligula, nec blandit metus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam elit mi, mattis dictum placerat vel, lacinia nec metus. Etiam eu nunc ut sapien tempus luctus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque eget libero ligula, nec blandit metus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam elit mi, mattis dictum placerat vel, lacinia nec metus. Etiam eu nunc ut sapien tempus luctus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque eget libero ligula, nec blandit metus.'
    const scrollarea = document.getElementById('scrollarea');
    const colours = ["red", "blue", "yellow", "purple", "gray", "orange", "green"];

    ensureContainerFull(scrollarea);

    function isSufficientContentLoadedAbove({
      clientHeight,
      scrollTop,
    }) {
      return scrollTop > clientHeight * 2;
    }

    function addMoreAbove() {
      const currentHeight = scrollarea.scrollHeight;
      const div = document.createElement('div');
      div.setAttribute('class', 'row');
      div.innerText = text.split(' ').slice(0, Math.random() * text.split(' ').length).join(' ')
      div.style.backgroundColor = colours[Math.floor(Math.random() * 7)]
      scrollarea.prepend(div);
      const newHeight = scrollarea.scrollHeight;
      scrollarea.scrollTop += (newHeight - currentHeight);
      ensureContainerFull(scrollarea);
    }

    function ensureContainerFull(scrollarea) {
      const { clientHeight, scrollTop } = scrollarea;
      if (!isSufficientContentLoadedAbove({ clientHeight, scrollTop })) {
        addMoreAbove()
      }
    }
    scrollarea.onscroll = () => ensureContainerFull(scrollarea)
  </script>
</body>
</html>

-- 
You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-unassigned/attachments/20230918/8bb13c72/attachment-0001.htm>


More information about the webkit-unassigned mailing list