Plugin Performance - ArunPrakashG/native-launcher GitHub Wiki

Plugin Performance Monitoring

Native Launcher includes built-in performance monitoring for dynamic plugins to help identify and debug slow-loading plugins.

Overview

When you load external plugins, Native Launcher automatically tracks:

  • Load time - How long it takes to load and initialize each plugin
  • Memory usage - Approximate memory footprint (file size)
  • Success/failure status - Whether the plugin loaded successfully
  • Error details - Specific error messages if loading failed

Performance Thresholds

Status Load Time Action
✅ Normal <10ms No issues
⚠️ Slow 10-50ms Logged to console
🔴 Very Slow >50ms UI warning displayed

UI Warnings

If any plugins take longer than 50ms to load, you'll see a warning banner at the top of the launcher:

┌──────────────────────────────────────────┐
│ ⚠️ 2 slow plugins detected (>50ms load) │
├──────────────────────────────────────────┤
│ [Search input]                           │
│ ...                                      │

This helps you identify problematic plugins that might be affecting startup performance.

Viewing Plugin Metrics

Console Logs (Info Level)

Run the launcher with logging enabled:

RUST_LOG=info native-launcher

You'll see detailed metrics for each plugin:

INFO  Loading plugin from: ~/.config/native-launcher/plugins/example.so
INFO  Loaded plugin 'Example' (priority: 200, load_time: 2.3ms, size: 418 KB)
INFO  Successfully loaded plugin: Example

Aggregate Statistics

After loading all plugins, you'll see summary statistics:

INFO  Loaded 3 dynamic plugins
INFO  Plugin metrics: total_load_time=15.4ms, avg_load_time=5.1ms, total_memory=1.2 MB

Slow Plugin Warnings

If any plugins are slow, you'll see warnings:

WARN  Detected 2 slow plugins (>50ms load time):
WARN    - my_plugin.so took 87.3ms
WARN    - another_plugin.so took 52.1ms

Debug Mode

For more detailed information, enable debug logging:

RUST_LOG=debug native-launcher

This shows:

  • Plugin discovery process
  • Directory scanning
  • Individual load attempts
  • Detailed error messages
  • All metric calculations

Plugin Metrics Data

Each plugin's metrics include:

Field Description
load_time Time taken to load the plugin (in milliseconds)
memory_bytes Plugin file size (approximate memory usage)
path Full path to the plugin file
success Whether the plugin loaded successfully
error Error message if loading failed

Understanding Slow Plugins

Why might a plugin be slow?

  1. Large file size - Plugin has many dependencies compiled in
  2. Initialization logic - Plugin does heavy work during load
  3. External API calls - Plugin makes network requests on startup
  4. File I/O - Plugin reads large configuration files
  5. Dependency resolution - Plugin loads many system libraries

What to do about slow plugins?

  1. Disable the plugin - Remove from plugins directory temporarily
  2. Contact developer - Report performance issue on plugin's repository
  3. Optimize plugin - If you wrote it, see optimization tips below
  4. Check system - Slow disk I/O can affect all plugins

Optimizing Plugin Load Time

For Plugin Developers

If your plugin is slow to load, try these optimizations:

1. Lazy Initialization

Don't do heavy work in plugin functions that are called during load:

// ❌ Bad: Heavy work during load
#[no_mangle]
pub extern "C" fn plugin_get_name() -> CStringSlice {
    let data = fetch_from_api(); // Slow!
    process_data(data);
    CStringSlice::from_string("My Plugin")
}

// ✅ Good: Defer work until needed
#[no_mangle]
pub extern "C" fn plugin_get_name() -> CStringSlice {
    CStringSlice::from_string("My Plugin")
}

#[no_mangle]
pub extern "C" fn plugin_search(...) -> CResultArray {
    // Lazy load data here, on first search
    let data = get_or_fetch_data();
    // ...
}

2. Reduce Dependencies

Minimize external dependencies in your Cargo.toml:

[dependencies]
# Only include what you actually need
# Avoid heavy dependencies like tokio if you don't need async

Use cargo tree to see your dependency tree:

cargo tree --edges normal --target x86_64-unknown-linux-gnu

3. Optimize Compilation

Use these settings in your plugin's Cargo.toml:

[profile.release]
opt-level = "z"     # Optimize for size
lto = true          # Link-time optimization
codegen-units = 1   # Better optimization
strip = true        # Remove debug symbols
panic = "abort"     # Smaller binary

4. Async vs Sync

Avoid async runtime overhead if you don't need it:

// ❌ Heavy: Includes full async runtime
use reqwest::Client;

// ✅ Lighter: Blocking client
use reqwest::blocking::Client;

5. Profile Your Plugin

Measure where time is spent:

cargo build --release
time ./target/release/libmy_plugin.so  # If it's a binary
# Or use profiling tools like perf, valgrind

Performance Targets

Native Launcher aims for:

  • <100ms total startup time
  • <10ms per plugin load time
  • <30MB total memory footprint

Your plugin should contribute minimally to these targets:

  • <5ms load time - Excellent
  • ⚠️ 5-10ms load time - Acceptable
  • 🔴 >10ms load time - Needs optimization

Benchmarking

Compare Plugin Sizes

ls -lh ~/.config/native-launcher/plugins/
# Look for unusually large files (>1MB is heavy)

Test Load Time

Time individual plugin loads by removing all but one:

# Backup plugins
mv ~/.config/native-launcher/plugins ~/.config/native-launcher/plugins.backup

# Test one plugin
mkdir -p ~/.config/native-launcher/plugins
cp plugins.backup/my_plugin.so ~/.config/native-launcher/plugins/

# Run and check metrics
RUST_LOG=info native-launcher

Startup Time Impact

Measure total startup time:

# Without plugins
mv ~/.config/native-launcher/plugins ~/.config/native-launcher/plugins.disabled
time native-launcher

# With plugins
mv ~/.config/native-launcher/plugins.disabled ~/.config/native-launcher/plugins
time native-launcher

Compare the difference to see plugin overhead.

Troubleshooting

Plugin shows as slow but I can't optimize it

Solution: Disable the plugin if it's not critical:

# Move plugin out of plugins directory
mv ~/.config/native-launcher/plugins/slow_plugin.so ~/disabled_plugins/

All plugins show as slow

Possible causes:

  1. Slow disk I/O (check with iostat -x 1)
  2. System under heavy load (check with top or htop)
  3. Running on slow storage (SD card, network drive)

Solutions:

  • Move plugins to faster storage (SSD)
  • Close resource-intensive applications
  • Check system health

Plugin fails to load with error

Check the error message in logs:

RUST_LOG=debug native-launcher 2>&1 | grep -A5 "Failed to load"

Common errors:

  • Missing dependencies - Install required system libraries
  • ABI mismatch - Rebuild plugin with correct ABI version
  • Permission denied - Check file permissions (chmod +x plugin.so)

Reporting Issues

When reporting slow plugin issues, include:

  1. Plugin name and version
  2. Load time from logs
  3. File size (ls -lh plugin.so)
  4. System specs (CPU, RAM, storage type)
  5. Full logs with RUST_LOG=debug

Example report:

Plugin: example-plugin v1.0.0
Load time: 87.3ms (very slow)
File size: 2.1 MB
System: Intel i5, 8GB RAM, NVMe SSD
Logs: [attach full debug logs]

Future Enhancements

Planned features:

  • Plugin manager UI - Enable/disable plugins from launcher
  • Performance history - Track metrics over time
  • Search latency tracking - Monitor plugin search performance
  • Auto-disable - Automatically disable plugins >100ms
  • Detailed metrics view - Show all plugins with load times
  • Memory profiling - Track actual runtime memory usage

Resources


Need help optimizing a slow plugin? Ask in GitHub Discussions!