Files
2025-11-30 09:03:44 +08:00

13 KiB

Performance Analysis Workflows

Advanced tools for JavaScript execution, performance tracing, device emulation, and automation utilities.

Tools in This Group

evaluate_script

Executes JavaScript code in the page context and returns JSON-serializable results.

Required: --function FUNCTION_STRING Optional: --args JSON_ARRAY

# Simple extraction
node scripts/evaluate_script.js --function "() => document.title"

# With parameters
node scripts/evaluate_script.js --function "(x, y) => x + y" --args '[5, 3]'

# Complex extraction
node scripts/evaluate_script.js --function "() => Array.from(document.querySelectorAll('h2')).map(h => h.textContent)"

wait_for

Waits for specific text to appear on the page (for dynamic content loading).

Required: --text TEXT Optional: --timeout MILLISECONDS

# Wait up to 10 seconds
node scripts/wait_for.js --text "Loading complete" --timeout 10000

# Wait for error message
node scripts/wait_for.js --text "Error" --timeout 5000

handle_dialog

Handles browser dialogs (alert, confirm, prompt).

Required: --action [accept|dismiss] Optional: --promptText TEXT

# Accept alert
node scripts/handle_dialog.js --action accept

# Dismiss confirm
node scripts/handle_dialog.js --action dismiss

# Accept prompt with text
node scripts/handle_dialog.js --action accept --promptText "User input"

emulate

Emulates network conditions and CPU throttling.

Optional: --networkConditions JSON, --cpuThrottlingRate NUMBER

# Slow 3G network
node scripts/emulate.js --networkConditions '{"downloadThroughput":50000,"uploadThroughput":50000,"latency":2000}'

# 4x CPU throttling
node scripts/emulate.js --cpuThrottlingRate 4

# Both
node scripts/emulate.js --networkConditions '{"downloadThroughput":100000,"uploadThroughput":50000,"latency":100}' --cpuThrottlingRate 2

performance_start_trace

Starts recording performance trace for Core Web Vitals and performance insights.

Required: --reload [true|false], --autoStop [true|false]

# Start tracing with page reload
node scripts/performance_start_trace.js --reload true --autoStop false

# Start tracing without reload
node scripts/performance_start_trace.js --reload false --autoStop true

performance_stop_trace

Stops the active performance trace and returns results.

node scripts/performance_stop_trace.js

Output includes:

  • Core Web Vitals: LCP, FID, CLS scores
  • Performance insights and recommendations
  • Insight set IDs for detailed analysis

performance_analyze_insight

Gets detailed information about a specific performance insight.

Required: --insightSetId SET_ID, --insightName INSIGHT_NAME

node scripts/performance_analyze_insight.js --insightSetId set_abc123 --insightName LargestContentfulPaint

Workflows

Workflow: Extract Structured Data

Scrape data from pages using JavaScript:

  • Open page: node scripts/new_page.js --url https://example.com/products
  • Wait for load: node scripts/wait_for.js --text "Products" --timeout 10000
  • Extract product titles:
node scripts/evaluate_script.js --function "() => Array.from(document.querySelectorAll('.product-title')).map(el => el.textContent)"
  • Extract product prices:
node scripts/evaluate_script.js --function "() => Array.from(document.querySelectorAll('.product-price')).map(el => el.textContent)"
  • Extract complete product data:
node scripts/evaluate_script.js --function "() => Array.from(document.querySelectorAll('.product')).map(p => ({title: p.querySelector('.title').textContent, price: p.querySelector('.price').textContent, id: p.dataset.id}))"

Expected Output: Structured JSON data extracted from page, ready for processing.

Workflow: Comprehensive Performance Analysis

Measure page performance and Core Web Vitals:

  • Open page: node scripts/new_page.js --url https://example.com/landing
  • Start trace with reload: node scripts/performance_start_trace.js --reload true --autoStop false
  • Wait for page load: node scripts/wait_for.js --text "Get Started" --timeout 20000
  • Interact with page: node scripts/click.js --uid button_cta
  • Wait for interaction: node scripts/wait_for.js --text "Form" --timeout 5000
  • Stop trace: node scripts/performance_stop_trace.js
  • Review output for:
    • LCP (Largest Contentful Paint) - should be < 2.5s
    • FID (First Input Delay) - should be < 100ms
    • CLS (Cumulative Layout Shift) - should be < 0.1
    • Performance insights list
  • Analyze specific insight: node scripts/performance_analyze_insight.js --insightSetId <set-id> --insightName LargestContentfulPaint

Expected Output: Full performance profile, CWV scores, actionable insights for optimization.

Workflow: Test Under Network Constraints

Simulate slow connections:

  • Set up slow 3G: node scripts/emulate.js --networkConditions '{"downloadThroughput":50000,"uploadThroughput":50000,"latency":2000}'
  • Open page: node scripts/new_page.js --url https://example.com --timeout 60000
  • Start performance trace: node scripts/performance_start_trace.js --reload true --autoStop false
  • Wait for load: node scripts/wait_for.js --text "Content" --timeout 60000
  • Stop trace: node scripts/performance_stop_trace.js
  • Review load times: Check trace output for timing metrics
  • Screenshot loaded state: node scripts/take_screenshot.js --filePath slow_3g_loaded.png
  • Reset to fast network: node scripts/emulate.js --networkConditions '{"downloadThroughput":10000000,"uploadThroughput":10000000,"latency":10}'

Expected Output: Page behavior under slow network documented, performance impact measured.

Workflow: CPU Throttling Test

Test performance on low-powered devices:

  • Apply 4x throttling: node scripts/emulate.js --cpuThrottlingRate 4
  • Open app: node scripts/new_page.js --url https://example.com/app
  • Start trace: node scripts/performance_start_trace.js --reload true --autoStop false
  • Interact with heavy UI: node scripts/click.js --uid button_render_chart
  • Wait for render: node scripts/wait_for.js --text "Chart loaded" --timeout 30000
  • Stop trace: node scripts/performance_stop_trace.js
  • Check JavaScript execution time in trace output
  • Remove throttling: node scripts/emulate.js --cpuThrottlingRate 1
  • Repeat test for comparison

Expected Output: Performance comparison between throttled and normal CPU, bottlenecks identified.

Workflow: Handle Dynamic Content Loading

Work with lazy-loaded content:

  • Open page: node scripts/new_page.js --url https://example.com/infinite-scroll
  • Wait for initial load: node scripts/wait_for.js --text "Item 1" --timeout 5000
  • Scroll to bottom: node scripts/evaluate_script.js --function "() => window.scrollTo(0, document.body.scrollHeight)"
  • Wait for more items: node scripts/wait_for.js --text "Item 20" --timeout 10000
  • Take snapshot: node scripts/take_snapshot.js
  • Scroll again: node scripts/evaluate_script.js --function "() => window.scrollTo(0, document.body.scrollHeight)"
  • Wait for more: node scripts/wait_for.js --text "Item 40" --timeout 10000
  • Extract all items:
node scripts/evaluate_script.js --function "() => Array.from(document.querySelectorAll('.item')).length"

Expected Output: All lazy-loaded content triggered and captured, full list extracted.

Workflow: Automated Dialog Handling

Automate flows with browser dialogs:

  • Open page: node scripts/new_page.js --url https://example.com/confirm-action
  • Click delete button: node scripts/click.js --uid button_delete
  • Handle confirm dialog: node scripts/handle_dialog.js --action accept
  • Wait for deletion: node scripts/wait_for.js --text "Deleted successfully" --timeout 5000
  • Verify: node scripts/take_snapshot.js

For prompt dialog:

# Click button that opens prompt
node scripts/click.js --uid button_rename

# Enter new name and accept
node scripts/handle_dialog.js --action accept --promptText "New Name"

# Verify change
node scripts/wait_for.js --text "New Name" --timeout 3000

Expected Output: Browser dialogs handled automatically, flow completes without manual intervention.

Workflow: Custom Metrics Collection

Collect custom performance metrics:

  • Open page: node scripts/new_page.js --url https://example.com/dashboard
  • Wait for load: node scripts/wait_for.js --text "Dashboard" --timeout 10000
  • Get page load time:
node scripts/evaluate_script.js --function "() => performance.timing.loadEventEnd - performance.timing.navigationStart"
  • Get resource count:
node scripts/evaluate_script.js --function "() => performance.getEntriesByType('resource').length"
  • Get memory usage (if available):
node scripts/evaluate_script.js --function "() => performance.memory ? performance.memory.usedJSHeapSize : null"
  • Get paint timings:
node scripts/evaluate_script.js --function "() => performance.getEntriesByType('paint').map(p => ({name: p.name, time: p.startTime}))"

Expected Output: Custom performance metrics collected via Performance API, specific to your needs.

Workflow: A/B Test Performance Comparison

Compare performance across variants:

  • Variant A:
    • Open: node scripts/new_page.js --url https://example.com?variant=a
    • Trace: node scripts/performance_start_trace.js --reload true --autoStop false
    • Wait: node scripts/wait_for.js --text "Content" --timeout 15000
    • Stop: node scripts/performance_stop_trace.js > variant_a_trace.txt
    • Screenshot: node scripts/take_screenshot.js --filePath variant_a.png
  • Variant B:
    • Navigate: node scripts/navigate_page.js --url https://example.com?variant=b
    • Trace: node scripts/performance_start_trace.js --reload true --autoStop false
    • Wait: node scripts/wait_for.js --text "Content" --timeout 15000
    • Stop: node scripts/performance_stop_trace.js > variant_b_trace.txt
    • Screenshot: node scripts/take_screenshot.js --filePath variant_b.png
  • Compare CWV scores from both trace files

Expected Output: Performance metrics for both variants, data-driven comparison for optimization.

Common Patterns

Pattern: Safe Script Evaluation

Always return JSON-serializable data:

# Good: Returns string
node scripts/evaluate_script.js --function "() => document.title"

# Good: Returns array of strings
node scripts/evaluate_script.js --function "() => Array.from(document.querySelectorAll('a')).map(a => a.href)"

# Bad: Returns DOM nodes (not serializable)
# node scripts/evaluate_script.js --function "() => document.querySelectorAll('a')"

Pattern: Wait Before Interaction

Always wait for dynamic content:

# 1. Trigger action
node scripts/click.js --uid button_load

# 2. Wait for content
node scripts/wait_for.js --text "Loaded" --timeout 10000

# 3. Now safe to interact
node scripts/take_snapshot.js

Pattern: Complete Performance Workflow

Standard performance analysis sequence:

# 1. Start tracing
node scripts/performance_start_trace.js --reload true --autoStop false

# 2. Let page load completely
node scripts/wait_for.js --text "Ready" --timeout 20000

# 3. Stop tracing
node scripts/performance_stop_trace.js

# 4. Analyze specific insights
node scripts/performance_analyze_insight.js --insightSetId <id> --insightName <name>

Pattern: Emulation Reset

Reset emulation to normal after testing:

# 1. Test under constraints
node scripts/emulate.js --cpuThrottlingRate 4

# ... run tests ...

# 2. Reset to normal
node scripts/emulate.js --cpuThrottlingRate 1

Troubleshooting

Problem: evaluate_script returns null or error

Solution:

  • Ensure function returns JSON-serializable values (no DOM nodes, functions, or circular references)
  • Use .map() to extract primitive values from DOM elements
  • Check browser console for JavaScript errors: list_console_messages.js --types error

Problem: wait_for times out

Solution:

  • Increase timeout: --timeout 30000 (30 seconds)
  • Verify text actually appears on page (check with take_snapshot.js)
  • Text match is exact - check spelling and case
  • Wait for network to finish if text appears after API call

Problem: Dialog not handled

Solution:

  • Dialog must be already open when you call handle_dialog.js
  • Trigger dialog first (e.g., click button), then immediately call handle_dialog.js
  • Some "dialogs" are custom HTML, not browser dialogs - use click.js instead

Problem: Performance trace shows unexpected results

Solution:

  • Ensure page fully loads before stopping trace
  • Use --reload true for consistent initial page load measurement
  • Clear browser cache if testing first-time load performance
  • Disable browser extensions that might affect performance

Problem: Emulation not working

Solution:

  • Emulation settings persist for the session
  • To remove emulation, set back to normal values
  • Network conditions JSON must be valid with all three properties
  • CPU throttling rate of 1 = normal, higher = slower

Problem: Script evaluation with args fails

Solution:

  • Args must be valid JSON array: --args '[1, 2, 3]'
  • Function must accept the correct number of parameters
  • Use single quotes around JSON, double quotes inside
  • Example: --function "(a, b) => a + b" --args '[5, 10]'