• Resizing
    • 10K elements
      • Without virtual-content (terrible)
      • With virtual-content (not terrible)
    • 100K elements
      • Without virtual-content (terrible)
      • With virtual-content (terrible)
  • Scrolling
    • 10K elements
      • Scroll by 50px
        • Without virtual-content (smooth)
        • With virtual-content (not terrible but 50ms/frame)
      • Scroll by several pages
        • Without virtual-content (smooth)
        • With virtual-content (completely blank!)
        • With virtual-content and forced-layouts (not blank but low FPS)
    • 100K elements
      • Without virtual-content (smooth)
      • With virtual-content (terrible)
  • Binary slot tree prototype

    This is a new approach where a tree of slots is maintained. The elements are assigned to locked slots in this tree, except for the visible elements. These are temporarily assigned to the special visible-slot. This slot is inserted into the tree adjacent to a locked slot and all of its ancestors are unlocked. When we want to make a different set of elements visible, we reassign all the elements back to their "natural" locked slots, move the visible slot to the right place in the tree and assign the newly visible elements to it, unlocking all of it's current ancestors (and relocking it's previous ancestors). Because this assigns all of the visible elements to a single slot, it should avoid the problems of the previous tree approach, e.g. breaking margin-collapsing. However we can no longer rely on the layout engine to size the empty space above/below the visible content.

    This is not a scroller, it's a proof-of-concept for benchmarking. It cannot handle updates and does not manage spacer divs above/below the unlocked content. It simply cycles through groups of elements, revealing chunks of 10 as fast as frame rate allows.

    Particularly interesting are 3 things that seem unexpectedly slow. They all seem like O(n) effects that we should fix.

    • insertBefore (used to move the visible slot from one location to another) seems very expensive given that we are just moving it around a tree. https://crbug.com/971930
    • slot.assignedNodes() seems very expensive given that it returns 10 elements in these demos. It appears to go as O(n) in the number of children of element, not the number of nodes assigned to this slot. https://crbug.com/971588
    • Recalc style seems slow, 15ms for 43 elements (in the 100K case). Something is over-invalidating? Or maybe we can tweak the styles of the custom elements. https://crbug.com/971588

    • 10K elements
      • Using element.slot (60 FPS)
      • Using imperative slot assignment (15 FPS)
    • 100K elements
      • Using element.slot 5 FPS (insertNode=15ms, assignedNodes=30ms, recalc style=10ms and maybe a lot of https://crbug.com/968928)
  • Revealing tree prototype

    This is a new approach where a tree of slots is maintained. Each elements is assigned to 1 slot. When elements should be visible, all of their ancestors are unlocked. All other elements in the tree remain locked. We can no longer rely on the layout engine to size the empty space above/below the visible content.

    This is not a scroller, it's a proof-of-concept for benchmarking. It cannot handle updates and does not manage spacer divs above/below the unlocked content. It simply cycles through groups of elements, revealing chunks of 10 as fast as frame rate allows.

    It has quite slow setup due to O(n^2) effects in adding many slots (https://crbug.com/985652). Otherwise, it seems quite performant.

    • 10K elements
      • Using element.slot (60 FPS)
      • Using imperative slot assignment (60 FPS)
      • With a resize animation (60 FPS)
    • 100K elements
      • Using imperative slot assignment (60 FPS) (takes a very long time to initialize)
      • With a resize animation (20-30 FPS) (takes a very long time to initialize). A plain DIV with 100k elements gets 0.04 FPS!!!!
  • Existing surprising jank
    • 100K elements under a counter - the counter is in a fixed-size DIV but changing the content incurs a massive cost from the 100K elements below it even if they are in a scroller with strict containment (some scenarios are better than others). This is orthogonal to virtual content etc. https://crbug.com/969683
      • With strict on both (long layout, layer tree)
      • Without strict (very long layout, layer tree and paint)
      • Scroller with strict on both (long layout, layer tree)
      • Scroller without strict (very long layout, layer tree and paint)
    • Style cost for custom-element is O(all children) when any slots change - https://crbug.com/971588

      All except 20 elements are not assigned to any slot, 2 groups of 10 elements swap between the first and second slot. Style recalc and assignedNodes seem O(n) in the number of elements, not in the number of elements that have changed.

      • 100K elements - assignedNodes=6ms, recalcStyle=10ms
      • 500K elements - assignedNodes=30ms, recalcStyle=45ms
    • insertBefore is slow with slots - https://crbug.com/971930

      SlotAssignment::FindHostChildBySlotName iterates over all children.

      • 10K elements - insertBefore=1.3ms
      • 100K elements - insertBefore=12ms
      • 500K elements - insertBefore=47ms