[Webkit-unassigned] [Bug 281920] New: Page freezes with many DOM manipulations and complex :has() selectors present

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Tue Oct 22 14:24:42 PDT 2024


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

            Bug ID: 281920
           Summary: Page freezes with many DOM manipulations and complex
                    :has() selectors present
           Product: WebKit
           Version: Safari 18
          Hardware: Unspecified
                OS: Unspecified
            Status: NEW
          Severity: Blocker
          Priority: P2
         Component: Layout and Rendering
          Assignee: webkit-unassigned at lists.webkit.org
          Reporter: kizmarh at ya.ru
                CC: bfulgham at webkit.org, simon.fraser at apple.com,
                    zalan at apple.com

Created attachment 473012

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

A screenshot of a page with clipped text, below is the top part of the Activity Monitor window that shows https://kizu.dev process with 100% CPU load.

I published a new article that explores some of the uses of `:has()` as well as potential cases for `sibling-index()` and `sibling-count()`. The article ended up being long, with many demos and code snippets.

Here it is: https://kizu.dev/tree-counting-and-random/

Long story short: opening this page in Safari lead to a full page freeze, with CPU keeping on 100% for minutes.

I pin-pointed the issue: There is syntax highlighting via Prism.js that happens when the page loads. Before syntax highlighting, the page contained 3125 elements (counting what document.querySelectorAll('*') matches). After Prism.js highlighting, where it adds all the tokens into the `<pre><code>` blocks, it bumps up to 6481 elements.

Apparently, this was enough for Safari to freeze. For now I pushed a very quick fix to that disables the syntax highlighting only on this page, and only for browsers that do not support `requestIdleCallback` (which is, for now, enough for the stable Safari, so people could at least read the article; will probably later use a different detection method).

Though, in Safari TP the page still can freeze on load (I guess, there is an experimental `requestIdleCallback` implementation?)

In stable Safari, I am able to reproduce the freeze if I go to https://kizu.dev/tree-counting-and-random/, open console, and run

    console.time(); Prism.highlightAll(); console.timeEnd();

If the page was fully loaded, sometimes it works, but ends up taking ~3 seconds.

In most other times, especially if you'd refresh the page with the console open and run it, the page freezes completely.

My guess: each DOM change leads to full selectors list invalidation, which with the page using really complex `:has()` selectors, leads to the freeze.

I'll try to find time to reproduce this outside of my site's article, but wanted to report this anyway today, so it would be on your radar. I'm putting the priority as “Blocker”, as it was, in fact, a blocker for my article to be readable (and still is), and I can imagine that it might be possible to create a malicious CSS that would contain just a few `:has()` selectors that could freeze any complex-enough website.

I'm attaching a screenshot from Safari TP with the page frozen (can be seen by trimmed text), and an Activity Monitor opened showing 100% for my website. I managed to reproduce this on two different MacBooks, and one iPhone.

-- 
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/20241022/26219234/attachment.htm>


More information about the webkit-unassigned mailing list