App Quality & Performance
Master app quality and performance for Buzzy. Learn data model efficiency, display rules optimization, and performance best practices for great user experiences.
Why Quality Matters with Buzzy
Non-technical explanation: Building an app is like cooking a meal. Even with professional kitchen equipment (Buzzy's Core Engine), you can still create a bad meal if your recipe (app design) is poor. Good ingredients arranged badly still taste bad. Similarly, even though Buzzy handles the technical infrastructure, you control the user experience through your design decisions.
While Buzzy handles the underlying code quality automatically through its professionally-maintained Core Engine, you're still responsible for your app's design quality and performance.
The cost of poor app design:
Poor app design leads to:
❌ Slow user experiences (pages take too long to load)
❌ Confusing navigation (users can't find what they need)
❌ Inefficient data structures (queries take too long)
❌ Poor user adoption (people don't use the app)
❌ Frustrated users (negative feedback, abandonment)
This guide covers:
🏗️ Data model quality (Subtables and Linked Table Fields best practices)
🎯 Display rules and actions optimization
⚡ Buzzy Functions performance tuning
📊 Performance considerations for Buzzy apps
✅ Complete app quality checklist (focused on design, not code)
Data Model Quality
1. Efficient Use of Subtables
Subtables are Buzzy's implementation of one-to-many relationships. Design them well:
Good Subtable design:
Invoices → Invoice Lines (each invoice has multiple line items)
Blog Posts → Comments (each post has multiple comments)
Projects → Tasks (each project has multiple tasks)
Organizations → Departments → Teams → Members (multiple nested levels)
Common mistakes:
Using Linked Table Fields when you should use Subtables
Loading many nested levels all at once (creates expensive queries and joins)
Not considering query performance for large Subtables
Best practices for nested Subtables:
Use Subtables for true parent-child relationships
Deep nesting is OK - you can nest more than 2-3 levels
The key: Use progressive disclosure - don't load all levels at once
Good approach: First screen shows 1-2 levels, then user drills down to see next level
Bad approach: Loading 10 items in a tree with 5+ nested levels all at once (monster queries!)
Example pattern:
Screen 1: Show Organizations list
Screen 2: Show selected Organization → Departments (1 level)
Screen 3: Show selected Department → Teams (1 level deeper)
Screen 4: Show selected Team → Members (1 level deeper)
Consider pagination for Subtables with many records
Use meaningful names for Subtable fields
Test query performance when nesting deeply - drill down progressively rather than showing everything
2. Proper Use of Linked Table Fields
Linked Table Fields enable many-to-many relationships. Use them correctly:
Good Linked Field design:
Products ↔ Categories (products in multiple categories)
Students ↔ Classes (students take multiple classes)
Articles ↔ Tags (articles have multiple tags)
Projects ↔ Team Members (members work on multiple projects)
Common mistakes:
Using Subtables when you need Linked Table Fields
Not storing additional relationship data when needed
Creating circular dependencies
Best practices:
Use Linked Table Fields for true many-to-many relationships
Consider using a junction table (Subtable + Linked Field) when you need to store relationship metadata
Use meaningful field names that indicate the relationship
Set appropriate display labels for the linked field
3. Field Validation and Formulas
Use Buzzy's built-in validation and JSONATA formulas effectively:
Field validation:
Mark required fields appropriately
Use field type validation (email format, number ranges)
Set appropriate min/max lengths for text fields
JSONATA formula examples:
Calculations:
quantity * price
Conditional logic:
user.highestRole = "admin" ? "Full Access" : "Limited Access"
Date validation:
dueDate > $now() ? "Valid" : "Date must be in future"
Best practices:
Use formulas for calculations rather than storing computed values
Validate data at the field level when possible
Use clear, readable formula expressions
Test formulas with edge cases
Learn more about Formula fields
4. Display Rules Best Practices
Display rules control when UI elements are visible in Buzzy. Use them wisely:
Good display rule patterns:
Show "Edit" button only for record owners:
viewers contains $currentUser._id
Show admin features for admins:
$currentUser.highestRole = "admin"
Show subtable when parent has data:
invoice.invoice_lines.$count() > 0
Conditional field display:
status = "approved"
Common mistakes:
Overly complex nested conditions
Not testing all user scenarios
Forgetting to test with different user roles
Using display rules for security (use Viewers fields instead)
Best practices:
Keep display rules simple and readable
Use display rules for UX, not security
Test with different user roles and data states
Document complex display rule logic
5. Actions Best Practices
Actions in Buzzy control what happens when users interact with your app:
Common action types:
Submit actions: Save form data to Datatables
Navigation actions: Move between screens
CRUD actions: Create, read, update, delete operations
Function calls: Execute Buzzy Functions
Good action patterns:
Validate before submit (use required fields)
Provide user feedback (success/error messages)
Clear navigation flows (back buttons, home navigation)
Confirmation for destructive actions (delete confirmations)
Common mistakes:
No feedback after actions complete
Confusing navigation (users get lost)
No undo for destructive operations
Missing error handling
Best practices:
Always provide user feedback
Use consistent action patterns throughout your app
Test all action paths thoroughly
Show loading states for slow operations
Performance Best Practices for Buzzy Apps
1. Data Model Performance
Efficient data relationships:
Design Subtables with performance in mind
Avoid deeply nested relationships (more than 3 levels)
Use Linked Table Fields appropriately
Consider query patterns when designing data model
Query optimization:
Use filters at the Datatable level
Implement pagination for large datasets
Limit Subtable record counts when possible
Use indexes effectively (Buzzy handles this automatically for common fields)
Example patterns:
✅ Good: Orders datatable with OrderItems subtable (1-2 levels)
❌ Bad: Company → Department → Team → Projects → Tasks (5 levels)
Best practices:
Design flat data structures when possible
Use Linked Table Fields to avoid deep nesting
Test with realistic data volumes
Monitor query performance in production
2. Screen Design Performance
Efficient screen layouts:
Limit the number of components on a single screen
Use pagination for large lists
Implement search and filter features
Load data progressively when possible
Mobile performance:
Buzzy's React Native apps include offline-first architecture
Test on actual mobile devices
Optimize images for mobile bandwidth
Consider data usage for mobile users
Best practices:
Show 20-50 items per page (not thousands)
Use infinite scroll or "Load More" buttons
Implement search for large datasets
Test with slow network connections
Optimize image sizes (compress before uploading)
3. Buzzy Functions Performance
When using Buzzy Functions (AWS Lambda), optimize for performance:
Function best practices:
Keep functions focused and small
Minimize dependencies (reduces cold start time)
Use environment variables for configuration
Implement error handling and retries
Set appropriate timeout values
Example efficient function:
export const main = async (event) => {
// Validate input quickly
if (!event.body?.email) {
return {
statusCode: 400,
body: { error: "Email required" }
};
}
// Do work
const result = await processEmail(event.body.email);
// Return promptly
return {
statusCode: 200,
body: result
};
};
Performance tips:
Cache API responses when appropriate
Use Promise.all() for parallel operations
Return errors quickly (don't waste time)
Test function performance before deploying
Learn more about Buzzy Functions
4. Caching Strategies
Where to cache:
Browser cache:
Static assets (images, CSS, JS)
API responses (for appropriate duration)
Server cache:
Database query results
External API calls
Computed values
Example:
const cache = new Map();
async function getWeatherData(city) {
const cacheKey = `weather:${city}`;
const cached = cache.get(cacheKey);
if (cached && Date.now() - cached.timestamp < 30 * 60 * 1000) {
return cached.data; // Use cache if < 30 minutes old
}
const data = await fetchWeatherFromAPI(city);
cache.set(cacheKey, {
data,
timestamp: Date.now()
});
return data;
}
Reviewing Buzzy Functions Code
When you use Buzzy Functions (AWS Lambda) for external integrations, you write minimal Lambda code. Here's what to review:
Common Issues in Buzzy Functions
1. Hard-Coded API Keys (Critical Security Issue)
❌ Never do this:
export const main = async (event) => {
const apiKey = "sk-abc123..."; // EXPOSED!
const response = await fetch(`https://api.service.com/data`, {
headers: { 'Authorization': `Bearer ${apiKey}` }
});
return { statusCode: 200, body: await response.json() };
};
✅ Always use Buzzy Constants:
export const main = async (event) => {
const apiKey = process.env.API_KEY; // From Buzzy Constants
if (!apiKey) {
return { statusCode: 500, body: { error: "API key not configured" } };
}
const response = await fetch(`https://api.service.com/data`, {
headers: { 'Authorization': `Bearer ${apiKey}` }
});
return { statusCode: 200, body: await response.json() };
};
2. Missing Error Handling
❌ Assumes everything works:
export const main = async (event) => {
const data = JSON.parse(event.body);
const result = await externalAPI(data.email); // What if email is missing?
return { statusCode: 200, body: result };
};
✅ Validates input and handles errors:
export const main = async (event) => {
// Validate input
const data = JSON.parse(event.body || '{}');
if (!data.email) {
return { statusCode: 400, body: { error: "Email required" } };
}
try {
const result = await externalAPI(data.email);
return { statusCode: 200, body: result };
} catch (error) {
console.error('API call failed:', error);
return { statusCode: 500, body: { error: "Service unavailable" } };
}
};
3. Missing Timeout Handling
Buzzy Functions have execution time limits. Handle slow operations:
export const main = async (event) => {
const timeout = 5000; // 5 seconds
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
try {
const response = await fetch(url, { signal: controller.signal });
clearTimeout(timeoutId);
return { statusCode: 200, body: await response.json() };
} catch (error) {
if (error.name === 'AbortError') {
return { statusCode: 504, body: { error: "Request timeout" } };
}
throw error;
}
};
4. Poor Response Structure
Buzzy expects consistent response formats from Functions:
✅ Good pattern:
return {
statusCode: 200,
body: {
success: true,
data: result
}
};
Learn more about Buzzy Functions best practices
Buzzy App Review Checklist
Before publishing your Buzzy app:
Data Model:
Security:
User Experience:
Functionality:
Performance:
Buzzy Functions (if applicable):
Improving Your Buzzy App Over Time
When to Redesign
Redesign when:
Data model is causing problems
Users find navigation confusing
Performance is poor with real data
Adding features is difficult due to design
Don't redesign when:
App works well for users
Performance is acceptable
Just cosmetic preferences
Time better spent on new features
Improvement Process for Buzzy Apps
1. Test current functionality (ensure you don't break what works) 2. Make one change at a time (data model first, then screens, etc.) 3. Test after each change (use Buzzy's preview mode) 4. Use Buzzy's version control (Versions tab for safe rollback)
Example: Improving a Buzzy app's data model
Before (Poor design):
Single "Orders" Datatable with text fields for items
Manual calculation of totals in display rules
Difficult to query individual items
Can't report on product popularity
After (Better design):
"Orders" Datatable with order metadata
"OrderItems" Subtable (child of Orders) for line items
Formula fields for automatic total calculations
Easy to query and report on products
Benefits of improved Buzzy data model:
Better data integrity
Automatic calculations via formulas
Easier to extend with new features
Better reporting capabilities
Follows Buzzy best practices (Subtables for 1:M relationships)
For Buzzy Functions refactoring:
Keep functions small and focused
Extract complex logic into helper functions
Use Constants for all configuration
Add comprehensive error handling
Test thoroughly before deploying
Monitoring Your Buzzy App
What to Monitor
User Experience:
How users navigate your app
Where users get stuck
Error reports from users
Feature usage patterns
Session duration
Performance:
App load times (web and mobile)
Screen navigation speed
Buzzy Function response times
Data query performance
Data Quality:
Data integrity issues
Missing required fields
Invalid data entries
Orphaned records
Monitoring Approaches
User feedback:
Built-in feedback mechanisms
User testing sessions
Support ticket analysis
Direct user conversations
Buzzy platform monitoring:
Check Buzzy Function logs
Review error reports
Monitor deployment status
Track usage statistics
Testing with real scenarios:
Test with production-like data volumes
Simulate real user workflows
Test on actual mobile devices
Test with slow network connections
Performance Optimization Process
1. Measure First
Use Buzzy's preview mode to test app speed
Test with realistic data volumes
Check on actual mobile devices
Monitor Buzzy Function execution times
2. Focus on Biggest Impact
Optimize screens users visit most
Fix slowest data queries first
Improve most complex Buzzy Functions
3. Make One Change at a Time
Test each optimization in preview
Use Buzzy's version control to rollback if needed
Document what you changed and why
4. Set Performance Goals
Screen load < 3 seconds
Buzzy Functions < 1 second
Search results < 2 seconds
Mobile app responsive and smooth
Buzzy App Organization
Datatable Organization
Good organization:
Group related Datatables logically
Use clear, descriptive names
Document complex relationships
Keep data model diagram updated
Example structure:
Users (main user table)
Organizations (multi-tenant)
Teams (within organizations)
Projects (linked to teams)
└─ Tasks (subtable of projects)
└─ Comments (subtable of projects)
Products (main products table)
Categories (linked via Linked Table Field)
Orders
└─ Order Items (subtable)
Screen Organization
Good patterns:
List → Detail → Edit flow
Clear navigation hierarchy
Consistent naming conventions
Group related screens
Example:
Project List
Project Detail
Project Edit
Project Tasks (subtable view)
Task Detail
Task Edit
Testing for Quality in Buzzy
Testing Approach
Functional testing:
Test all user workflows
Verify display rules work correctly
Confirm actions complete successfully
Test with different user roles
Data testing:
Test with empty state (no data)
Test with large datasets
Test edge cases (very long text, special characters)
Verify Subtables and Linked Fields work correctly
User testing:
Have real users try the app
Watch where they get confused
Note what they expect vs. what happens
Iterate based on feedback
Continuous Improvement
Regular activities for Buzzy apps:
Weekly:
Review user feedback
Check Buzzy Function logs
Test new features added
Monitor app performance
Monthly:
Review data model efficiency
Optimize slow screens
Update Buzzy Functions if needed
Review security settings
Quarterly:
Major UX improvements
Data model refactoring if needed
Performance optimization
User testing sessions
Next Steps
Security best practices: Compliance & Security
Understanding maintenance: Maintenance with Buzzy
Testing strategies: Testing Approaches
Building examples: Hello World App
Remember: App quality in Buzzy isn't about code quality—it's about design quality. Buzzy handles the code. You handle the data model, user experience, and business logic. Focus on making your app intuitive, performant, and valuable to users. Quality compounds over time.
Last updated