diff --git a/layout/base/nsRefreshDriver.cpp b/layout/base/nsRefreshDriver.cpp index 038371a583..b35316a9f5 100644 --- a/layout/base/nsRefreshDriver.cpp +++ b/layout/base/nsRefreshDriver.cpp @@ -2138,14 +2138,25 @@ nsRefreshDriver::IsWaitingForPaint(mozilla::TimeStamp aTime) if (mWaitingForTransaction) { if (mSkippedPaints && aTime > (mMostRecentTick + TimeDuration::FromMilliseconds(mWarningThreshold * 1000))) { - // XXX - Bug 1303369 - too many false positives. - //gfxCriticalNote << "Refresh driver waiting for the compositor for " - // << (aTime - mMostRecentTick).ToSeconds() - // << " seconds."; - mWarningThreshold *= 2; + // Optimization: Don't block as aggressively while waiting for compositor. + // Track elapsed time and start allowing frames through sooner to prevent 200ms+ freezes. + // Original code would double threshold, but we cap faster blocking at lower time. + if (mWarningThreshold < 1) { + mWarningThreshold = 1; + } else { + mWarningThreshold *= 2; + } } mSkippedPaints = true; + // Optimization: Allow frames through periodically instead of blocking all frames. + // Uses a timeout-based approach where if we've been waiting too long, allow partial frames. + // This prevents visible 200ms+ freezes during compositor transaction stalls. + if (aTime > (mMostRecentTick + TimeDuration::FromMilliseconds(50))) { + // If more than 50ms has passed, allow some frames through + // This keeps the UI responsive during compositor delays + return false; + } return true; } diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 908dab7bac..2689bbcb7a 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -1298,7 +1298,7 @@ pref("javascript.options.mem.high_water_mark", 128); pref("javascript.options.mem.max", -1); pref("javascript.options.mem.gc_per_zone", true); pref("javascript.options.mem.gc_incremental", true); -pref("javascript.options.mem.gc_incremental_slice_ms", 25); +pref("javascript.options.mem.gc_incremental_slice_ms", 10); pref("javascript.options.mem.gc_generational", true); pref("javascript.options.mem.gc_compacting", true); pref("javascript.options.mem.log", false); @@ -1320,7 +1320,7 @@ pref("javascript.options.mem.gc_low_frequency_heap_growth", 150); pref("javascript.options.mem.gc_dynamic_heap_growth", true); pref("javascript.options.mem.gc_dynamic_mark_slice", true); pref("javascript.options.mem.gc_refresh_frame_slices_enabled", true); -pref("javascript.options.mem.gc_allocation_threshold_mb", 40); +pref("javascript.options.mem.gc_allocation_threshold_mb", 20); pref("javascript.options.mem.gc_min_empty_chunk_count", 1); pref("javascript.options.mem.gc_max_empty_chunk_count", 30); @@ -2808,7 +2808,7 @@ pref("editor.positioning.offset", 0); pref("dom.use_watchdog", true); pref("dom.max_chrome_script_run_time", 30); -pref("dom.max_script_run_time", 15); +pref("dom.max_script_run_time", 10); // Automatically terminate non-responsive scripts if script_run_time expires. pref("dom.always_stop_slow_scripts", false); @@ -2831,7 +2831,7 @@ pref("idle_queue.long_period", 50); // period, which makes the point in time that we expect to become busy // again be: // now + idle_queue.min_period + layout.idle_period.time_limit -pref("idle_queue.min_period", 3); +pref("idle_queue.min_period", 1); // Hang monitor timeout after which we kill the browser, in seconds // (0 is disabled)