This issue has been created
 
 
XWiki WebSocket Integration / cid:jira-generated-image-avatar-5ac45afc-1273-40f5-8181-14fd186e9c46 WEBSOCKET-12 Open

WebSocket disconnects in background tabs due to Chrome's "Intensive Wake Up Throttling"

 
View issue   ·   Add comment
 

Issue created

 
cid:jira-generated-image-avatar-dbbd1394-034f-493f-8290-e203b9e10be5 Martin created this issue on 21/Jan/26 11:32
 
Summary: WebSocket disconnects in background tabs due to Chrome's "Intensive Wake Up Throttling"
Issue Type: cid:jira-generated-image-avatar-5ac45afc-1273-40f5-8181-14fd186e9c46 Bug
Assignee: Unassigned
Attachments: image-2026-01-21-11-15-56-976.png
Created: 21/Jan/26 11:32
Priority: cid:jira-generated-image-static-major-3d45f4a9-f7f3-4670-93b7-8cf3b5132e54 Major
Reporter: Martin
Description:

Overview

We are observing recurring WebSocket disconnections in XWiki (Netflux) when the browser tab has been in the background for more than 5 minutes. This interrupts collaborative editing sessions.

Root Cause Analysis:

Modern versions of Google Chrome enable "IntensiveWakeUpThrottlingEnabled" by default. This feature throttles Javascript timers (setTimeout / setInterval) in background tabs (hidden for >5 minutes) to run only once per minute (60 seconds).

In netflux-client.js, the keep-alive logic is defined as follows:

// How much lag before we send a ping
var MAX_LAG_BEFORE_PING = 15000;

// How much of a lag we accept before we will drop the socket
var MAX_LAG_BEFORE_DISCONNECT = 60000;

// ...

ctx.pingInterval = setInterval(function () {
    if (now() - ctx.timeOfLastPingReceived < MAX_LAG_BEFORE_PING) { return; }
    
    // THE ISSUE:
    if (now() - ctx.timeOfLastMsgReceived > MAX_LAG_BEFORE_DISCONNECT) {
        closeWebsocket(ctx);
    }
    // ...
}, PING_CYCLE);

The Race Condition

Chrome throttles the setInterval execution to exactly 60,000ms (1 minute).

The code checks if the last message was received more than MAX_LAG_BEFORE_DISCONNECT (60,000ms) ago.

Because the throttled interval fires slightly after 60s (e.g., at 60,005ms or due to slight execution delays), the condition diff > 60000 evaluates to true.

The WebSocket is closed immediately, even though the connection might still be valid.

Evidence

Below is a screenshot from the Chrome Developer Tools showing the WebSocket traffic. You can see the Pings occur normally at first, but once throttling kicks in, the interval stretches to ~60s, leading to the disconnect.

44517_image-2026-01-21-11-15-56-976.png

 

Steps to Reproduce

Open an XWiki document with Realtime editing enabled in Chrome.

Open a new tab and focus it (leaving the XWiki tab in the background).

Wait for at least 5 minutes (triggering Chrome's intensive throttling).

Observe that the WebSocket connection drops shortly after.

Proposed Solution

To accommodate browser throttling policies, the disconnect threshold should be higher than the browser's minimum throttle interval (60s).

I suggest increasing MAX_LAG_BEFORE_DISCONNECT to 80,000 (80 seconds) or higher. This provides a safety buffer for the throttled interval to execute and send a ping before the disconnect logic triggers.

// Proposed change in netflux-client.js
var MAX_LAG_BEFORE_DISCONNECT = 80000; // Increased from 60000 to handle Chrome background throttling