Performance Optimization
This guide provides performance optimization strategies for AuroraView, including first-paint optimization, IPC performance improvements, and best practices.
Problem Analysis
First Paint White Screen
Symptoms:
- Noticeable white screen after window appears
- Users wait 500ms-1s before seeing content
- Application feels slow and unresponsive
Breakdown:
Total Load Time = WebView Init + HTML Parse + CSS Compute + JS Execute + First Render
(200-300ms) (50-100ms) (30-80ms) (100-200ms) (100-200ms)
= 480-880ms| Phase | Time | Description |
|---|---|---|
| WebView Init | 200-300ms | WebView2/WebKit initialization (biggest bottleneck) |
| HTML Parse | 50-100ms | DOM tree construction |
| CSS Compute | 30-80ms | Style calculation and application |
| JS Execute | 100-200ms | Script loading and initialization |
| First Render | 100-200ms | Layout, paint, and composite |
Optimization Strategies
1. Loading Page (Immediate)
Principle: Show a lightweight loading page first, then async load actual content.
python
from auroraview import WebView
# Create WebView
webview = WebView(
title="My App",
width=800,
height=600,
)
# Load lightweight loading page first
webview.load_html("""
<!DOCTYPE html>
<html>
<head>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
margin: 0;
}
.spinner {
width: 60px;
height: 60px;
border: 4px solid rgba(255, 255, 255, 0.3);
border-top-color: white;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
</style>
</head>
<body>
<div class="spinner"></div>
</body>
</html>
""")
# Show window (immediately shows loading)
webview.show_async()
# Async load actual content
import threading
def load_content():
import time
time.sleep(0.1) # Simulate load time
webview.load_html(ACTUAL_CONTENT)
threading.Thread(target=load_content).start()Results:
- ✅ Users see loading animation immediately (100-200ms)
- ✅ Perceived performance improves 60-80%
- ✅ Actual load time unchanged, but better experience
2. Performance Monitoring
HTML Side:
html
<script>
// Performance monitoring
window.auroraViewPerf = {
start: performance.now(),
marks: {}
};
// DOM ready
document.addEventListener('DOMContentLoaded', () => {
window.auroraViewPerf.marks.domReady = performance.now();
console.log('DOM ready:',
window.auroraViewPerf.marks.domReady - window.auroraViewPerf.start, 'ms');
});
// Fully loaded
window.addEventListener('load', () => {
window.auroraViewPerf.marks.loaded = performance.now();
console.log('Fully loaded:',
window.auroraViewPerf.marks.loaded - window.auroraViewPerf.start, 'ms');
// Notify Python
auroraview.send_event('first_paint', {
time: window.auroraViewPerf.marks.loaded - window.auroraViewPerf.start
});
});
</script>Python Side:
python
@webview.on("first_paint")
def handle_first_paint(data):
print(f"✅ First paint: {data.get('time', 0):.2f} ms")3. HTML Optimization
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 1. Inline critical CSS (avoid extra requests) -->
<style>
/* Only include above-the-fold styles */
body { margin: 0; font-family: sans-serif; }
.container { max-width: 1200px; margin: 0 auto; }
</style>
<!-- 2. Preload critical resources -->
<link rel="preload" href="critical.css" as="style">
<link rel="preload" href="critical.js" as="script">
</head>
<body>
<!-- 3. Above-the-fold content first -->
<div class="container">
<h1>Welcome</h1>
<!-- Visible content -->
</div>
<!-- 4. Lazy load non-critical content -->
<div id="lazy-content"></div>
<!-- 5. Scripts at bottom -->
<script>
// Critical JavaScript
</script>
<!-- 6. Defer non-critical scripts -->
<script>
window.addEventListener('load', () => {
const script = document.createElement('script');
script.src = 'non-critical.js';
document.body.appendChild(script);
});
</script>
</body>
</html>4. IPC Performance Optimization
Enable Batch Processing:
python
# Enable batching
webview.enable_batching(max_size=10, max_age_ms=16)
@webview.on("event", batching=True)
def handle_event_batch(batch):
# Process multiple messages at once
for message in batch:
process_data(message['data'])Benefits:
- ✅ GIL lock count reduced 90%
- ✅ Throughput increased 5-10x
- ✅ Slight latency increase (16ms)
5. Resource Optimization
Image Optimization:
html
<!-- Use WebP format -->
<img src="image.webp" alt="Image">
<!-- Lazy loading -->
<img src="image.jpg" loading="lazy" alt="Image">
<!-- Responsive images -->
<img srcset="small.jpg 480w, medium.jpg 800w, large.jpg 1200w"
sizes="(max-width: 600px) 480px, (max-width: 1000px) 800px, 1200px"
src="medium.jpg" alt="Image">CSS Optimization:
html
<!-- Inline critical CSS -->
<style>
/* Above-the-fold styles */
</style>
<!-- Async load non-critical CSS -->
<link rel="preload" href="non-critical.css" as="style"
onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="non-critical.css"></noscript>JavaScript Optimization:
javascript
// Code splitting
const module = await import('./heavy-module.js');
// Debounce
function debounce(func, wait) {
let timeout;
return function(...args) {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), wait);
};
}
// Throttle
function throttle(func, limit) {
let inThrottle;
return function(...args) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}Performance Benchmarks
Test Environment
- OS: Windows 11
- CPU: Intel i7-12700K
- RAM: 32GB
- WebView: WebView2 (Edge 120)
Results
| Metric | Before | After | Improvement |
|---|---|---|---|
| WebView Init | 250ms | 250ms | 0% |
| First Paint | 800ms | 200ms | 75% ⬆️ |
| DOM Ready | 150ms | 100ms | 33% ⬆️ |
| Fully Loaded | 500ms | 350ms | 30% ⬆️ |
| IPC Throughput | 1000 msg/s | 8000 msg/s | 700% ⬆️ |
User Perception
| Metric | Before | After |
|---|---|---|
| White Screen Time | 800ms | 200ms |
| Time to Interactive | 1000ms | 400ms |
| User Satisfaction | 60% | 90% |
Best Practices
Development
python
# Enable performance monitoring
webview = WebView(
title="My App",
dev_tools=True, # Enable DevTools
)
# Listen for performance events
@webview.on("first_paint")
def handle_first_paint(data):
print(f"First paint: {data.get('time', 0):.2f} ms")Production
python
# Disable DevTools
webview = WebView(
title="My App",
dev_tools=False,
)
# Enable batching
webview.enable_batching(max_size=10, max_age_ms=16)DCC Integration
python
# Use embedded mode
webview = WebView.create(
"Maya Tool",
parent=maya_hwnd,
mode="owner",
)
# Use scriptJob for event processing
def process_events():
webview.process_events()
cmds.scriptJob(event=["idle", process_events])Performance Checklist
First Paint
- [ ] Use loading page
- [ ] Inline critical CSS
- [ ] Defer non-critical resources
- [ ] Optimize image size and format
- [ ] Use performance monitoring
IPC Performance
- [ ] Enable message batching
- [ ] Reduce GIL lock time
- [ ] Use async processing
- [ ] Avoid frequent small messages
Resource Optimization
- [ ] Compress HTML/CSS/JavaScript
- [ ] Use WebP images
- [ ] Enable lazy loading
- [ ] Code splitting
Runtime Performance
- [ ] Use debounce and throttle
- [ ] Avoid frequent DOM operations
- [ ] Use requestAnimationFrame
- [ ] Optimize event listeners
Troubleshooting
Problem: First paint still slow
Check:
- Using loading page?
- HTML too large?
- Too many external resources?
- JavaScript blocking render?
Solution:
- Use loading page
- Reduce HTML size
- Inline critical resources
- Defer JavaScript
Problem: Poor IPC performance
Check:
- Batching enabled?
- Messages too frequent?
- Too many small messages?
Solution:
- Enable batching
- Combine messages
- Use throttling
Problem: High memory usage
Check:
- Memory leaks?
- Too much cached data?
- Uncleaned event listeners?
Solution:
- Use DevTools to check memory
- Clean up unused data
- Remove event listeners
Summary
Immediate (High Priority)
- ✅ Add loading page
- ✅ Implement performance monitoring
- ✅ Optimize HTML structure
Short-term (Medium Priority)
- 🔄 Enable IPC batching
- 🔄 Optimize resource loading
- 🔄 Implement lazy loading
Expected Results
- ✅ First paint time reduced 75%
- ✅ IPC throughput increased 700%
- ✅ User satisfaction increased 50%
- ✅ Overall performance improved 40-60%
