matomo icon indicating copy to clipboard operation
matomo copied to clipboard

Beforeunloadhandler blocks UI

Open mgrubinger opened this issue 1 year ago • 4 comments

Context

I have investigated the cause for slow INP on some of our pages and discovered that links which also send a matomo event via onclick=_paq.push(['trackEvent' ... (simplified) delay the navigation to the next page for at least 100ms.

This significantly slows users perceived performance of the site and negatively impacts INP score.

Screenshot of beforeonload event in chrome performance measurement: 100msdelay

Related issues:

  • https://github.com/matomo-org/matomo/issues/6641
  • https://github.com/matomo-org/matomo/issues/20165
  • https://github.com/matomo-org/matomo/issues/13681

The cause for this delay seems to be https://github.com/matomo-org/matomo/blob/5.x-dev/js/piwik.js#L522 where the main thread is deliberately blocked by a do/while loop.

Expected Behavior

The navigation event should not be blocked.

Current Behavior

All links that also have an onclick event handler sending a matomo event are delayed by 100ms due to the do/while loop in https://github.com/matomo-org/matomo/blob/5.x-dev/js/piwik.js#L522 (or L520 in 4.x-dev)

The do/while loop executes ~5500 times on my macbook pro 15 (intel), with simulated 4x CPU slowdown ~1500 times.

Possible Solution

In my experiments, the beacon/ping request was sent even when removing the do/while loop. From what I gathered in the linked issues (above) the forced delay by occupying the main thread with a loop should not be required any more when sendBeacon is used?

Screenshot of beforeunload event after removing the do/while loop withoutvondelay

Steps to Reproduce (for Bugs)

  1. create a link with an onclick event handler (either as attribute or addEventListener('click') that sends a matomo event: _paq.push(['trackEvent', 'sidebarnavigation', 'click', 'Settings'); or similar on a website with matomo tracking acitvated
  2. open chrome dev tools, select performance panel
  3. click record in performace panel
  4. click link
  5. stop record in performance panel
  6. you should see that the beforeunload handler takes ~100ms due to the do/while loop in L522

Your Environment

  • Matomo Version: 4.14.2
  • PHP Version: 7.4.33
  • Server Operating System: Debian bookworm
  • Additionally installed plugins:
  • Browser: Google Chrome 117.0.5938.92
  • Operating System: macos

mgrubinger avatar Sep 25 '23 12:09 mgrubinger