is there way to fake `visibilitychange` event?

126 views
Skip to first unread message

Adnan Khan

unread,
Nov 10, 2025, 6:03:00 AMNov 10
to Chromium Extensions
I'm developing extension for my personal use, trying to scrape a page but in background tab.
Problem is that the page won't load fully unless I make it active.
Since `visibilitychange` is read-only and most of the solutions on stack overflow are also outdated. I wonder if there is any API access or method to mimic the page active event on that tab?


woxxom

unread,
Nov 11, 2025, 1:53:54 AMNov 11
to Chromium Extensions, Adnan Khan
You'll need to run your code in the MAIN world of the page by declaring "world": "MAIN" and "run_at": "document_start" for the content script. The script will use Object.defineProperty to override `visibilityState` (value) and `onvisibilitychange` (getter and setter) properties on `document`, also use `Proxy` to override `document.addEventListener` if that's what the webpage is using or `EventTarget.prototype.addEventListener` if you don't know for sure. The Proxy's `apply` handler will do nothing if the first argument is "visibilitychange", otherwise it'll call the inherited addEventListener.

There is also the problem of the browser itself pausing the timers in backgrounded tabs, so you'll have to override `setTimeout`, `setInterval`, `clearTimeout`, `clearInterval` on `window` to make them send a message to the extension, which will call the corresponding function in its background script and send a message back when done. Since there may be tons of such messages, use chrome.runtime.connect to establish a long-lived communication channel.

Adnan Khan

unread,
Nov 11, 2025, 6:39:00 AMNov 11
to Chromium Extensions, woxxom, Adnan Khan

Thanks, one thing to add to the original issue is that.

Suppose I visit website "XYZ" in a pinned tab(background), it will only load basic skeleton but not entire data unlike other websites. If I make that tab active, it will start rendering, in API calls `imitator` I see `requestAnimationFrame` being used.
Is this something that I can solve from extension?
I would like the page to know that its actually active somehow so that the tab can load fully and I can scrape some data of it.

Thanks!

woxxom

unread,
Nov 11, 2025, 7:33:57 AMNov 11
to Chromium Extensions, Adnan Khan, woxxom
Yeah, you can override it either via extension messaging or a dummy MessageChannel to imitate the delay:

{
  let id = 0;
  const queue = {__proto__: null};
  const { port1, port2 } = new MessageChannel();
  port2.onmessage = evt => {
    const id = evt.data;
    const fn = queue[id];
    delete queue[id];
    fn(performance.now());
  };
  window.requestAnimationFrame = fn => (queue[++id] = fn, port1.postMessage(id), id);
}

Adnan Khan

unread,
Nov 11, 2025, 10:51:01 AMNov 11
to Chromium Extensions, woxxom, Adnan Khan
Thanks,

It didnt work, the website still didn't load complete data until I made that tab active.

To re-give context, my sole purpose of extension is to mimic that the tab is active while it is being in background so that the page can load everything fine.

woxxom

unread,
Nov 11, 2025, 10:54:11 AMNov 11
to Chromium Extensions, Adnan Khan, woxxom
Assuming you did all of the above suggestions, there are other things sites may be checking like document.hasFocus() or `blur` event, so you'll probably have to debug it in devtools to find where it's stalled.
Reply all
Reply to author
Forward
0 new messages