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

Last updated