Bug: ...Performance degradation during long-running agent tasks due to repeated DOM serialization, browser state fetching, and growing message history
Browser Use Version
0.13.10
Bug Description, Steps to Reproduce, Screenshots
Description
During long-running browser automation tasks, browser-use performance gradually degrades due to repeated full DOM processing, increasing message history size, and unnecessary browser state synchronization.
After analyzing the repository architecture and execution pipeline, the main bottlenecks appear to be:
Full DOM traversal and serialization on every agent step Growing LLM message history causing increasing prompt construction overhead Repeated CDP/browser state queries even when the page state has not changed Large numbers of temporary Python object allocations during DOM serialization
The current execution flow is approximately:
Agent Loop | +--> Observe Browser State | +--> Extract DOM | +--> Serialize DOM | +--> Build LLM Context | +--> LLM Inference | +--> Execute Action | +--> Repeat
For large websites or long-running tasks, the cost increases significantly.
Identified Performance Issues
- Full DOM serialization every step
Current behavior:
DOM Tree | v Traverse all nodes | v Serialize all elements
Complexity:
O(N)
where:
N = total DOM nodes
Problem:
Even when only a few nodes change, the whole DOM is processed again.
Example:
DOM size: 50,000 nodes
Changed nodes: 20 nodes
Current work:
50,000 node processing operations
Expected:
20 node updates
Suggested improvement:
Implement incremental DOM diffing using browser mutation tracking.
Expected complexity improvement:
O(N) -> O(K)
K = changed nodes 2. Message history continuously grows
Current behavior:
messages=[ step1, step2, step3, ... stepN ]
Long tasks create:
Larger prompts Higher token usage More memory allocation Longer serialization time
Current complexity:
O(N)
Suggested improvement:
Use:
Recent important messages + compressed summary + current browser state
Expected:
O(W)
W = fixed context window 3. Repeated browser state fetching
Current behavior:
Each step may repeatedly request:
get_page() get_dom() get_attributes() get_visibility()
even when the browser state has not changed.
Suggested improvement:
Add browser state caching:
BrowserStateCache
- DOM snapshot
- Active page
- Viewport
- Timestamp
Invalidate cache only after:
Navigation Click Input DOM mutation 4. DOM serializer allocation overhead
Current implementation creates many temporary objects:
dictionaries lists strings intermediate representations
Although complexity remains:
O(N)
the constant overhead is high due to:
Python memory allocation garbage collection string copying
Suggested improvements:
Object reuse Generator-based processing Reduce temporary allocations Improve string construction Steps to Reproduce Scenario 1: Large DOM Website Open a webpage containing a large DOM tree (>50,000 nodes) Run a browser-use agent task requiring multiple iterations Observe increasing latency after each step
Measure:
Agent step latency DOM extraction time CPU usage Memory usage Token usage Scenario 2: Long Running Task Run an automation task requiring >200 agent steps Monitor: Prompt size Memory consumption Execution latency
Expected observation:
Performance decreases as the task continues.
Failing Python Code
from browser_use import Agent
from browser_use import Browser
import asyncio
async def main():
browser = Browser()
agent = Agent(
task="""
Perform a long browser automation task.
Navigate through multiple pages,
inspect many elements,
and complete the workflow.
""",
browser=browser,
)
await agent.run()
asyncio.run(main())LLM Model
No response
Operating System & Browser Versions
No response
Full DEBUG Log Output
Source: browser-use/browser-use