perf, fix: Avoid tight tick loop before page loads

https://github.com/lightpanda-io/browser/pull/2999 fixed a spin loop when the
page had no i/o but had tasks, something we'd expect to see at page-load end.
But it introduced a similar spin loop as what it fixed on page-start, before the
page has anything to do.

Specifically, 2999 preventing i/o pollings when tasks were waiting. But, the
code doesn't run tasks until there's a "runnable" task. On Frame start, we
register a background task. Net result is that, for the first 200ms, everything
is fine, but then the task is due, so we don't poll, but we also don't run the
tasks, repeating a tick(0) loop.

The solution is simply to disable the 2999 optimization when there's no
runnable page.
This commit is contained in:
Karl Seguin
2026-07-23 20:10:40 +08:00
parent 0d77c501db
commit 542d9a333b

View File

@@ -217,7 +217,9 @@ fn _tick(self: *Runner, comptime is_cdp: bool, timeout_ms: u32, conditions: []Wa
return .{ .ok = 0 };
}
if (hasRunnablePage(session)) {
const has_runnable_page = hasRunnablePage(session);
if (has_runnable_page) {
try browser.runMacrotasks();
}
@@ -295,12 +297,18 @@ fn _tick(self: *Runner, comptime is_cdp: bool, timeout_ms: u32, conditions: []Wa
}
if ((comptime is_cdp) or want_http_tick) {
var ms_to_wait = @min(timeout_ms, browser.msToNextTask() orelse 200);
if (browser.hasBackgroundTasks()) {
// background work will queue more to do soon — don't block long
// for a client message; loop back and run macrotasks instead.
ms_to_wait = @min(ms_to_wait, 10);
}
const ms_to_next_task = blk: {
if (has_runnable_page == false) {
break :blk 200;
}
if (browser.hasBackgroundTasks()) {
// msToNextTask could be less than this, but 10ms drift is ok
break :blk 10;
}
break :blk browser.msToNextTask() orelse 200;
};
const ms_to_wait = @min(timeout_ms, ms_to_next_task);
const waited = try http_client.tick(@intCast(ms_to_wait));
// If the HttpClient didn't wait/poll then it has nothing to do, and we