Performance
Optimize your Appivo applications for speed and efficiency
Performance Guide
Learn how to optimize your Appivo applications for the best user experience.
Performance Overview
There are four places to tune performance — data, the UI, rules, and the network. This guide walks each in turn.
Application performance depends on:
| Factor | Impact |
|---|---|
| Data queries | How efficiently data is retrieved |
| UI complexity | Number and complexity of widgets |
| Rule execution | How much processing occurs |
| Network latency | Distance and connection speed |
| Asset size | Images and file downloads |
Data Performance
Pagination
Always paginate large data sets:
DataGrid: Orders
Data Source: Order model
Pagination: Enabled
Page Size: 25
Benefits:
- Faster initial load
- Less memory usage
- Better user experience
- Reduced server load
Filtering at the Source
Apply filters in the data query, not in the UI:
Good: Filter in the data binding
DataGrid: Active Customers
Filter: status = "Active"
Avoid: Loading all records then filtering
DataGrid: Customers
Post-filter: Hide inactive rows
Index Your Data
For frequently queried attributes, configure indexes:
| Attribute Type | When to Index |
|---|---|
| Foreign keys | Always |
| Status fields | Frequently filtered |
| Date fields | Date range queries |
| Search fields | Text searches |
Limit Retrieved Attributes
Only request the attributes you need:
DataGrid: Customer List
Columns: name, email, status
Don't load all 50 attributes when displaying only 3.
UI Performance
Widget Efficiency
Minimize Widget Count
Each widget adds overhead:
- Use DataGrid instead of individual row widgets
- Combine labels where possible
- Remove hidden widgets that are never shown
Simplify Complex Views
Break complex views into:
- Tabbed sections (load on demand)
- Detail views (navigate to see more)
- Modal dialogs (load when opened)
Image Optimization
Use Appropriate Sizes
| Context | Recommended Size |
|---|---|
| Thumbnails | 100x100 px |
| List images | 200x200 px |
| Detail images | 600x400 px |
| Full screen | 1200x800 px max |
Image Best Practices
- Compress images before upload
- Use appropriate file formats (JPEG for photos, PNG for graphics)
- Implement lazy loading for below-the-fold images
- Use image thumbnails in lists
Conditional Loading
Load content only when needed:
- TabContainer: Customer Details
- Tab: Overview (loads immediately)
- Tab: Orders (loads when clicked)
- Tab: History (loads when clicked)
- Tab: Documents (loads when clicked)
Rule Performance
Efficient Scripts
Minimize Database Operations
// Inefficient: Multiple queries
for (const item of items) {
const product = await context.getRecord('Product', item.product_id);
// process...
}
// Better: Single batch query
const productIds = items.map(i => i.product_id);
const products = await context.find('Product', {
filter: { id: { $in: productIds } }
});
Cache Repeated Lookups
// Cache configuration values
const taxRate = context.getConfig('tax_rate');
const currency = context.getConfig('currency');
// Use cached values in loop
for (const item of items) {
item.tax = item.price * taxRate;
}
Rule Triggers
Be Specific with Triggers
Rule: Update Order Total
Type: DATA
Trigger: Order line_items modified
Don't trigger on every Order change if you only need line item changes.
Avoid Cascading Updates
Design rules to prevent update loops:
Rule A updates Model X
Model X update triggers Rule B
Rule B updates Model X (loop!)
Use conditions to prevent re-triggering:
if (context.record.total !== calculatedTotal) {
context.record.total = calculatedTotal;
// Only updates if actually changed
}
Scheduled Rules
For heavy processing, use scheduled rules:
| Use Case | Schedule |
|---|---|
| Daily reports | Once per day, off-peak |
| Data sync | Every hour |
| Cleanup | Weekly |
Avoid running heavy processes on every data change.
Long-Running and Bulk Jobs
When you need to operate on thousands or millions of records, don't try to fit the work into a single action. Use Distributed Execution to fan the work out across all your workers — the platform will track progress, retry transient failures, and run a wrap-up action when everything is done.
Network Performance
Minimize API Calls
Batch operations where possible:
// Instead of:
await context.createRecord('OrderLine', item1);
await context.createRecord('OrderLine', item2);
await context.createRecord('OrderLine', item3);
// Consider bulk operations when available
Webhook Optimization
For external integrations:
| Setting | Recommendation |
|---|---|
| Timeout | Set appropriate limits |
| Retries | Enable with backoff |
| Payload | Send only needed data |
| Async | Use for non-blocking operations |
Offline Support
For mobile apps, configure offline caching:
Offline Models:
- Product (read-only cache)
- Customer (sync on connect)
Cache Strategy: Sync when connected
Monitoring Performance
Built-in Monitoring
Appivo provides performance insights:
| Metric | Description |
|---|---|
| Page load time | Time to display view |
| Query duration | Database query time |
| Rule execution | Script processing time |
| API response | External call latency |
Identifying Bottlenecks
Common performance issues:
- Slow page load
- Too many widgets
- Large unoptimized images
- Loading too much data
- Slow data operations
- Missing indexes
- Complex queries
- Large record counts
- Slow rules
- Inefficient scripts
- Multiple database calls
- External API delays
Performance Testing
Test with realistic data:
| Test | Approach |
|---|---|
| Data volume | Test with expected record counts |
| Concurrent users | Simulate multiple active users |
| Network conditions | Test on slow connections |
| Device variety | Test on mobile and desktop |
Best Practices Summary
Data
- Always paginate lists (25-50 items per page)
- Filter at the query level
- Index frequently searched fields
- Only retrieve needed attributes
User Interface
- Minimize widget count
- Use lazy loading for tabs and modals
- Optimize images for their display size
- Test on mobile devices
Rules and Actions
- Batch database operations
- Cache repeated lookups
- Use specific triggers
- Schedule heavy processing
Network
- Minimize API calls
- Configure appropriate timeouts
- Enable offline support where needed
- Monitor external dependencies
Common Optimizations
Slow List View
Problem: DataGrid takes long to load
Solutions:
- Enable pagination
- Reduce visible columns
- Add filters to limit data
- Check for missing indexes
Slow Form Save
Problem: Saving records takes long
Solutions:
- Review triggered rules
- Check for cascading updates
- Simplify validation logic
- Move heavy processing to async rules
Slow Dashboard
Problem: Dashboard loads slowly
Solutions:
- Reduce widget count
- Use summary/aggregated data
- Cache calculated values
- Load charts on demand
Next Steps
- Data Modeling - Efficient data design
- Rules and Actions - Optimize automation
- Distributed Execution - Run big jobs reliably in the background
- User Interfaces - Efficient UI design