Skip to content

script: Add check for IntersectionObserver to not connect to the same document multiple times.#42366

Merged
mrobinson merged 6 commits intoservo:mainfrom
Narfinger:intersection-observer-fix
Feb 6, 2026
Merged

script: Add check for IntersectionObserver to not connect to the same document multiple times.#42366
mrobinson merged 6 commits intoservo:mainfrom
Narfinger:intersection-observer-fix

Conversation

@Narfinger
Copy link
Copy Markdown
Contributor

Previous IntersectionObserver had only connect_to_owner_unchecked method. We replace this with a checked method to not add the same IntersectionObserver to the same document multiple times.

This should improve performance as the same IntersectionObserver was tested multiple times.

Signed-off-by: Narfinger [email protected]

Testing: Compilation and println statements to see if we do not add us again to the document.

@Narfinger Narfinger requested a review from gterzian as a code owner February 5, 2026 13:41
@servo-highfive servo-highfive added the S-awaiting-review There is new code that needs to be reviewed. label Feb 5, 2026
@Narfinger Narfinger added the T-linux-wpt Do a try run of the WPT label Feb 5, 2026
@github-actions github-actions bot removed the T-linux-wpt Do a try run of the WPT label Feb 5, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 5, 2026

🔨 Triggering try run (#21714510427) for Linux (WPT)

@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 5, 2026

Test results for linux-wpt from try job (#21714510427):

Flaky unexpected result (31)
  • OK /IndexedDB/idbfactory-open-error-properties.any.html
    • PASS [expected FAIL] subtest: Properties of error event from failed open()
  • OK /IndexedDB/idbfactory-open-error-properties.any.worker.html
    • PASS [expected FAIL] subtest: Properties of error event from failed open()
  • CRASH [expected OK] /_mozilla/mozilla/preserve_wrapper_callback.html
  • CRASH [expected PASS] /_mozilla/shadow-dom/move-element-with-ua-shadow-tree-crash.html (#39473)
  • OK /_webgl/conformance/textures/misc/texture-upload-size.html (#21770)
    • FAIL [expected PASS] subtest: WebGL test #45

      assert_true: Texture was smaller than the expected size 2x2 expected true got false
      

    • FAIL [expected PASS] subtest: WebGL test #47

      assert_true: getError expected: INVALID_VALUE. Was NO_ERROR : when calling texSubImage2D with the same texture upload with offset 1, 1 expected true got false
      

    • FAIL [expected PASS] subtest: WebGL test #49

      assert_true: Texture was smaller than the expected size 2x2 expected true got false
      

    • FAIL [expected PASS] subtest: WebGL test #51

      assert_true: getError expected: INVALID_VALUE. Was NO_ERROR : when calling texSubImage2D with the same texture upload with offset 1, 1 expected true got false
      

    • PASS [expected FAIL] subtest: WebGL test #53
    • PASS [expected FAIL] subtest: WebGL test #55
    • PASS [expected FAIL] subtest: WebGL test #57
    • PASS [expected FAIL] subtest: WebGL test #59
    • FAIL [expected PASS] subtest: WebGL test #61

      assert_true: Texture was smaller than the expected size 2x2 expected true got false
      

    • FAIL [expected PASS] subtest: WebGL test #63

      assert_true: getError expected: INVALID_VALUE. Was NO_ERROR : when calling texSubImage2D with the same texture upload with offset 1, 1 expected true got false
      

    • And 6 more unexpected results...
  • TIMEOUT /content-security-policy/inheritance/location-reload.html (#38983)
    • FAIL [expected PASS] subtest: location.reload() of empty iframe.

      assert_equals: Image should be blocked by CSP after reload. expected "img blocked" but got "img loaded"
      

  • FAIL [expected PASS] /css/css-backgrounds/background-size-042.html
  • OK /html/browsers/browsing-the-web/navigating-across-documents/005.html (#27062)
    • PASS [expected FAIL] subtest: Link with onclick navigation and href navigation
  • OK /html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/load-pageshow-events-window-open.html (#28691)
    • PASS [expected FAIL] subtest: load event does not fire on window.open('about:blank')
  • OK /html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-same-origin.window.html (#29049)
    • PASS [expected FAIL] subtest: Same-origin navigation started from unload handler must be ignored
  • OK /html/browsers/history/the-history-interface/traverse_the_history_3.html (#21383)
    • PASS [expected FAIL] subtest: Multiple history traversals, last would be aborted
  • OK /html/browsers/history/the-history-interface/traverse_the_history_4.html (#21383)
    • PASS [expected FAIL] subtest: Multiple history traversals, last would be aborted
  • OK /html/browsers/history/the-history-interface/traverse_the_history_5.html (#21383)
    • PASS [expected FAIL] subtest: Multiple history traversals, last would be aborted
  • OK [expected TIMEOUT] /html/semantics/embedded-content/media-elements/src_object_blob.html (#40340)
    • PASS [expected TIMEOUT] subtest: HTMLMediaElement.srcObject blob
  • OK /html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-nav-location-assign.html (#32863)
    • FAIL [expected PASS] subtest: Navigating iframe loading='lazy' before it is loaded: location.assign

      uncaught exception: Error: assert_equals: expected "http://web-platform.test:8000/html/semantics/embedded-content/the-iframe-element/support/blank.htm?nav" but got "http://web-platform.test:8000/html/semantics/embedded-content/the-iframe-element/support/blank.htm?src"
      

  • TIMEOUT [expected OK] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_navigate_other_frame_popup.sub.html (#39702)
    • TIMEOUT [expected FAIL] subtest: Sandboxed iframe can not navigate other frame's popup

      Test timed out
      

  • OK /html/semantics/forms/form-submission-0/jsurl-form-submit.tentative.html (#36489)
    • PASS [expected FAIL] subtest: Verifies that form submissions scheduled inside javascript: urls take precedence over the javascript: url's return value.
  • TIMEOUT [expected OK] /html/user-activation/navigation-state-reset-sameorigin.html
    • TIMEOUT [expected PASS] subtest: Post-navigation state reset.

      Test timed out
      

  • CRASH [expected OK] /html/webappapis/system-state-and-capabilities/the-navigator-object/secure_context.html
  • OK /html/webappapis/user-prompts/print-during-unload.html (#35944)
    • FAIL [expected PASS] subtest: print() during unload

      assert_array_equals: expected property 1 to be "destination" but got "error: window.print is not a function" (expected array ["start", "destination"] got ["start", "error: window.print is not a function"])
      

  • OK /preload/prefetch-document.html (#37210)
    • FAIL [expected PASS] subtest: different-site document prefetch with 'as=document' should not be consumed

      assert_equals: expected 2 but got 1
      

  • ERROR [expected OK] /resource-timing/cors-preflight.any.html (#28694)
  • OK [expected CRASH] /resource-timing/render-blocking-status-link.html (#41664)
  • OK /touch-events/single-tap-when-touchend-listener-use-sync-xhr.html (#41175)
    • PASS [expected FAIL] subtest: Click event should be fired when touchend opens synchronous XHR
  • TIMEOUT /trusted-types/trusted-types-navigation.html?06-10 (#37920)
    • PASS [expected FAIL] subtest: Navigate a frame via anchor with javascript:-urls in report-only mode.
  • TIMEOUT /trusted-types/trusted-types-navigation.html?31-35 (#38034)
    • TIMEOUT [expected PASS] subtest: Navigate a frame via form-submission with javascript:-urls in report-only mode.

      Test timed out
      

    • NOTRUN [expected TIMEOUT] subtest: Navigate a frame via form-submission with javascript:-urls w/ default policy in report-only mode.
  • OK /visual-viewport/resize-event-order.html (#41981)
    • PASS [expected FAIL] subtest: Popup: DOMWindow resize fired before VisualViewport.
  • TIMEOUT [expected OK] /webdriver/tests/classic/element_click/scroll_into_view.py
  • OK [expected ERROR] /webxr/render_state_update.https.html (#27535)
  • CRASH [expected OK] /workers/Worker_ErrorEvent_bubbles_cancelable.htm
  • ERROR [expected OK] /workers/baseurl/alpha/sharedworker-in-worker.html (#21315)
Stable unexpected results that are known to be intermittent (30)
  • OK /IndexedDB/idbcursor-continuePrimaryKey-exceptions.any.html (#39277)
    • FAIL [expected PASS] subtest: IDBCursor continuePrimaryKey() on object store cursor

      assert_throws_dom: continuePrimaryKey() should throw if source is not an index function "function() {
              cursor.continuePrimaryKey(2, 2);
            }" threw object "TypeError: cursor.continuePrimaryKey is not a function" that is not a DOMException InvalidAccessError: property "code" is equal to undefined, expected 15
      

  • OK /IndexedDB/idbcursor-continuePrimaryKey-exceptions.any.worker.html (#39277)
    • FAIL [expected PASS] subtest: IDBCursor continuePrimaryKey() on object store cursor

      assert_throws_dom: continuePrimaryKey() should throw if source is not an index function "function() {
              cursor.continuePrimaryKey(2, 2);
            }" threw object "TypeError: cursor.continuePrimaryKey is not a function" that is not a DOMException InvalidAccessError: property "code" is equal to undefined, expected 15
      

  • OK /IndexedDB/idbobjectstore_getAll.any.html (#39276)
    • PASS [expected FAIL] subtest: Get all values with transaction.commit()
  • OK /IndexedDB/idbobjectstore_getAll.any.worker.html (#39400)
    • PASS [expected FAIL] subtest: Get all values with transaction.commit()
  • OK /IndexedDB/idbrequest-onupgradeneeded.any.html (#38895)
    • PASS [expected FAIL] subtest: transaction oncomplete ordering relative to open request onsuccess
  • OK /IndexedDB/idbrequest-onupgradeneeded.any.worker.html (#38971)
    • PASS [expected FAIL] subtest: transaction oncomplete ordering relative to open request onsuccess
  • OK /IndexedDB/key-conversion-exceptions.any.html (#39305)
    • FAIL [expected PASS] subtest: IDBCursor continue() method with throwing/invalid keys

      assert_throws_exactly: key conversion with throwing getter should rethrow function "() => {
            receiver[method](key);
          }" threw object "TypeError: receiver[method] is not a function" but we expected it to throw object "getter: throwing from getter"
      

    • FAIL [expected PASS] subtest: IDBCursor update() method with throwing/invalid keys

      assert_throws_exactly: throwing getter should rethrow during clone function "() => {
            cursor.update(value);
          }" threw object "TypeError: cursor.update is not a function" but we expected it to throw object "getter: throwing from getter"
      

  • OK /IndexedDB/key-conversion-exceptions.any.worker.html (#39284)
    • FAIL [expected PASS] subtest: IDBCursor continue() method with throwing/invalid keys

      assert_throws_exactly: key conversion with throwing getter should rethrow function "() => {
            receiver[method](key);
          }" threw object "TypeError: receiver[method] is not a function" but we expected it to throw object "getter: throwing from getter"
      

    • FAIL [expected PASS] subtest: IDBCursor update() method with throwing/invalid keys

      assert_throws_exactly: throwing getter should rethrow during clone function "() => {
            cursor.update(value);
          }" threw object "TypeError: cursor.update is not a function" but we expected it to throw object "getter: throwing from getter"
      

  • OK /_mozilla/mozilla/getBoundingClientRect.html (#39668)
    • FAIL [expected PASS] subtest: getBoundingClientRect 1

      assert_equals: expected 62 but got 60.35
      

  • FAIL [expected PASS] /_mozilla/mozilla/sslfail.html (#10760)
  • TIMEOUT [expected OK] /_mozilla/mozilla/window_resize_event.html (#36741)
    • TIMEOUT [expected PASS] subtest: Popup onresize event fires after resizeTo

      Test timed out
      

  • OK /css/css-cascade/layer-cssom-order-reverse.html (#36094)
    • PASS [expected FAIL] subtest: Delete layer invalidates @font-face
  • OK /css/css-cascade/layer-font-face-override.html (#35935)
    • PASS [expected FAIL] subtest: @font-face override update with appended sheet 1
  • OK /css/css-fonts/generic-family-keywords-001.html (#37467)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted generic(fangsong)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted generic(kai)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted generic(khmer-mul)
  • OK /css/cssom-view/offsetTopLeft-border-box.html (#40826)
    • PASS [expected FAIL] subtest: container: 0
    • PASS [expected FAIL] subtest: container: 1
  • OK /custom-elements/form-associated/ElementInternals-setFormValue.html (#29174)
    • PASS [expected FAIL] subtest: Single value - empty name exists
    • PASS [expected FAIL] subtest: Single value - Non-empty name exists
    • PASS [expected FAIL] subtest: Null value should submit nothing
    • PASS [expected FAIL] subtest: Multiple values - name content attribute is ignored
    • PASS [expected FAIL] subtest: setFormValue with an empty FormData should submit nothing
    • PASS [expected FAIL] subtest: Newline normalization - \r\n in name (urlencoded)
    • PASS [expected FAIL] subtest: Newline normalization - \n in value (formdata)
    • PASS [expected FAIL] subtest: Newline normalization - \r\n in value (urlencoded)
    • PASS [expected FAIL] subtest: Newline normalization - \r\n in value (formdata)
    • PASS [expected FAIL] subtest: Newline normalization - \r\n in filename (urlencoded)
    • And 5 more unexpected results...
  • ERROR [expected OK] /fetch/fetch-later/quota/same-origin-iframe/multiple-iframes.https.window.html (#35176)
  • OK /fetch/metadata/generated/css-font-face.https.sub.tentative.html (#32732)
    • FAIL [expected PASS] subtest: sec-fetch-mode

      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

    • PASS [expected FAIL] subtest: sec-fetch-dest
  • OK /fetch/metadata/generated/css-font-face.sub.tentative.html (#34624)
    • FAIL [expected PASS] subtest: sec-fetch-storage-access - Not sent to non-trustworthy same-site destination

      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

    • FAIL [expected PASS] subtest: sec-fetch-storage-access - Not sent to non-trustworthy cross-site destination

      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

  • TIMEOUT /fetch/metadata/generated/css-images.sub.tentative.html (#29047)
    • FAIL [expected PASS] subtest: content sec-fetch-site - HTTPS downgrade-upgrade

      assert_unreached: Reached unreachable code
      

  • ERROR /fetch/metadata/generated/serviceworker.https.sub.html (#36247)
    • FAIL [expected PASS] subtest: sec-fetch-site - Same origin, no options - registration

      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

  • OK [expected TIMEOUT] /html/interaction/focus/the-autofocus-attribute/supported-elements.html (#24145)
    • PASS [expected TIMEOUT] subtest: Non-HTMLElement should not support autofocus
    • FAIL [expected NOTRUN] subtest: Host element with delegatesFocus should support autofocus

      assert_equals: expected Element node <div autofocus=""></div> but got Element node <body><div autofocus=""></div></body>
      

    • FAIL [expected NOTRUN] subtest: Host element with delegatesFocus including no focusable descendants should be skipped

      assert_equals: expected Element node <input autofocus=""></input> but got Element node <body><div autofocus=""></div><input autofocus=""></body>
      

    • FAIL [expected NOTRUN] subtest: Area element should support autofocus

      promise_test: Unhandled rejection with value: object "TypeError: can't access property "appendChild", w.document.querySelector(...) is null"
      

  • OK [expected TIMEOUT] /html/interaction/focus/the-autofocus-attribute/update-the-rendering.html (#24145)
    • FAIL [expected TIMEOUT] subtest: "Flush autofocus candidates" should be happen before a scroll event and animation frame callbacks

      assert_array_equals: animationFrame lengths differ, expected array ["autofocus", "scroll", "animationFrame"] length 3, got ["animationFrame"] length 1
      

  • OK /html/semantics/forms/form-submission-0/multipart-formdata.window.html (#28725)
    • PASS [expected FAIL] subtest: multipart/form-data: Basic File test (formdata event)
    • PASS [expected FAIL] subtest: multipart/form-data: 0x00 in name (normal form)
    • PASS [expected FAIL] subtest: multipart/form-data: 0x00 in name (formdata event)
    • PASS [expected FAIL] subtest: multipart/form-data: 0x00 in value (normal form)
    • PASS [expected FAIL] subtest: multipart/form-data: 0x00 in value (formdata event)
    • PASS [expected FAIL] subtest: multipart/form-data: 0x00 in filename (normal form)
    • PASS [expected FAIL] subtest: multipart/form-data: 0x00 in filename (formdata event)
    • PASS [expected FAIL] subtest: multipart/form-data: \n in value (normal form)
    • PASS [expected FAIL] subtest: multipart/form-data: \n in value (formdata event)
    • PASS [expected FAIL] subtest: multipart/form-data: \r\n in value (normal form)
    • And 19 more unexpected results...
  • OK /html/semantics/forms/form-submission-0/text-plain.window.html (#28687)
    • PASS [expected FAIL] subtest: text/plain: Basic File test (formdata event)
    • PASS [expected FAIL] subtest: text/plain: 0x00 in name (normal form)
    • PASS [expected FAIL] subtest: text/plain: 0x00 in name (formdata event)
    • PASS [expected FAIL] subtest: text/plain: 0x00 in value (normal form)
    • PASS [expected FAIL] subtest: text/plain: 0x00 in value (formdata event)
    • PASS [expected FAIL] subtest: text/plain: 0x00 in filename (normal form)
    • PASS [expected FAIL] subtest: text/plain: 0x00 in filename (formdata event)
    • PASS [expected FAIL] subtest: text/plain: \r\n in name (normal form)
    • PASS [expected FAIL] subtest: text/plain: \r\n in name (formdata event)
    • PASS [expected FAIL] subtest: text/plain: \r\n in value (normal form)
    • And 25 more unexpected results...
  • OK /html/semantics/forms/form-submission-0/urlencoded2.window.html (#28687)
    • PASS [expected FAIL] subtest: application/x-www-form-urlencoded: Basic File test (formdata event)
    • PASS [expected FAIL] subtest: application/x-www-form-urlencoded: 0x00 in name (normal form)
    • PASS [expected FAIL] subtest: application/x-www-form-urlencoded: 0x00 in name (formdata event)
    • PASS [expected FAIL] subtest: application/x-www-form-urlencoded: 0x00 in value (normal form)
    • PASS [expected FAIL] subtest: application/x-www-form-urlencoded: 0x00 in value (formdata event)
    • PASS [expected FAIL] subtest: application/x-www-form-urlencoded: 0x00 in filename (normal form)
    • PASS [expected FAIL] subtest: application/x-www-form-urlencoded: 0x00 in filename (formdata event)
    • PASS [expected FAIL] subtest: application/x-www-form-urlencoded: \r\n in name (normal form)
    • PASS [expected FAIL] subtest: application/x-www-form-urlencoded: \r\n in name (formdata event)
    • PASS [expected FAIL] subtest: application/x-www-form-urlencoded: \r\n in value (normal form)
    • And 31 more unexpected results...
  • OK /navigation-timing/test-navigation-type-reload.html (#33334)
    • FAIL [expected PASS] subtest: Reload domComplete > Original domComplete

      assert_true: Reload domComplete > Original domComplete expected true got false
      

    • PASS [expected FAIL] subtest: Reload domContentLoadedEventStart > Original domContentLoadedEventStart
    • PASS [expected FAIL] subtest: Reload fetchStart > Original fetchStart
    • FAIL [expected PASS] subtest: Reload loadEventEnd > Original loadEventEnd

      assert_true: Reload loadEventEnd > Original loadEventEnd expected true got false
      

    • FAIL [expected PASS] subtest: Reload loadEventStart > Original loadEventStart

      assert_true: Reload loadEventStart > Original loadEventStart expected true got false
      

  • OK /resource-timing/test_resource_timing.html (#25720)
    • PASS [expected FAIL] subtest: window.performance.getEntriesByName() and window.performance.getEntriesByNameType() return same data (iframe)
    • FAIL [expected NOTRUN] subtest: PerformanceEntry has correct name, initiatorType, startTime, and duration (link)

      assert_equals: expected 9.770000000000003 but got 9.76
      

  • OK /resource-timing/test_resource_timing.https.html (#25216)
    • PASS [expected FAIL] subtest: window.performance.getEntriesByName() and window.performance.getEntriesByNameType() return same data (iframe)
    • FAIL [expected PASS] subtest: PerformanceEntry has correct name, initiatorType, startTime, and duration (img)

      assert_equals: expected 9.580000000000002 but got 9.58
      

  • OK /service-workers/service-worker/fetch-event.https.html (#36234)
    • PASS [expected FAIL] subtest: Service Worker falls back to network in fetch event with POST form

@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 5, 2026

✨ Try run (#21714510427) succeeded.

Copy link
Copy Markdown
Member

@mrobinson mrobinson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good with some wording nits:

@servo-highfive servo-highfive added S-awaiting-review There is new code that needs to be reviewed. and removed S-awaiting-review There is new code that needs to be reviewed. labels Feb 5, 2026
@servo-highfive servo-highfive removed the S-awaiting-review There is new code that needs to be reviewed. label Feb 6, 2026
@Narfinger Narfinger force-pushed the intersection-observer-fix branch from 0854f5e to e673bf2 Compare February 6, 2026 10:27
@servo-highfive servo-highfive added the S-awaiting-review There is new code that needs to be reviewed. label Feb 6, 2026
Narfinger and others added 6 commits February 6, 2026 11:28
Co-authored-by: Martin Robinson <[email protected]>
Signed-off-by: Narfinger <[email protected]>
Co-authored-by: Martin Robinson <[email protected]>
Signed-off-by: Narfinger <[email protected]>
Co-authored-by: Martin Robinson <[email protected]>
Signed-off-by: Narfinger <[email protected]>
Co-authored-by: Martin Robinson <[email protected]>
Signed-off-by: Narfinger <[email protected]>
Signed-off-by: Narfinger <[email protected]>
@mrobinson mrobinson added this pull request to the merge queue Feb 6, 2026
@servo-highfive servo-highfive added the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Feb 6, 2026
Merged via the queue into servo:main with commit 4e85b99 Feb 6, 2026
32 checks passed
@servo-highfive servo-highfive removed the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Feb 6, 2026
@Narfinger Narfinger deleted the intersection-observer-fix branch February 6, 2026 13:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-awaiting-review There is new code that needs to be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants