Hi FlutterFlow community! ๐
I've been working on an audiobook app and encountered an interesting architectural decision point that I'd like to share and get your thoughts on. I've explored different approaches and would love to hear your experiences and recommendations.
The Context
I'm building an app where the homepage displays a list of episode cards. Each EpisodeCard
component needs basic information like:
Title
Thumbnail URL
Category
Episode ID
When a user clicks on an episode, they navigate to an Episode Overview screen with more details, and from there, they can go to the player screen:
Cards <-> Overview <-> Audio Player
The Architectural Question
I've identified several approaches to handling the data flow and component architecture, each with their own trade-offs. Let me walk you through my thinking process.
Approach 1: "All Data as Parameters"
EpisodeCard(
id: episode.id,
title: episode.title,
thumbnailURL: episode.thumbnailURL,
category: episode.category,
description: episode.description,
audioURL: episode.audioURL,
// ... all other fields
)
Pros:
Single query
Data immediately available for navigation between pages
No loading states needed
Cons:
Higher memory usage per card (potentially overloading RAM usage and affecting performance)
Many fields stored but potentially never used
Approach 2: "Essential Parameters Only"
EpisodeCard(
id: episode.id,
title: episode.title,
thumbnailURL: episode.thumbnailURL,
category: episode.category
)
Pros:
Lower memory footprint
Only stores what's needed
Still uses single query
Clean component interface
Passes some data between pages as parameters like Thumbnail or Title
Cons:
Needs additional query when viewing details
Requires loading state management for details (not big deal IMO)
Approach 3: "ID-Only with Component Query"
EpisodeCard(
episodeId: episode.id
)
// Component internally queries its own data
Pros:
Very clean component interface
Component is self-contained
Minimal data passing
Sharing an specific episode, should be easier, as you'd only need to pass the episode ID
Cons:
Multiple queries (N+1 problem) (First, query the list of Episodes ID's -> Then, Query each episode data at the component level)
Potential performance impact: No data is passed between screens, needs to query all data in each screen.
Approach 4: "Database Views + ID-Only Component"
Using optimized Supabase views for different purposes:
List view (IDs, categories, length)
Card view (display data only: Title, Thumbnail, Category and Length)
Detail view (all data)
Pros:
All from approach 3 + lighter and more optimizd queries that get only the required data.
My Current Conclusion
After analyzing these approaches, I'm leaning towards a hybrid solution combining Approach 2 (Small amount of parameters) with Approach 4 (Database Views, Query Missing Fields From Episode ID Parameter)
Database Efficiency:
Single query per screen/section/list
Views can be optimized for each use case
Minimal data transfer
Clean Architecture:
Components only receive data they need
Clear separation of concerns
Simple, maintainable code
Performance:
Balanced memory usage
No N+1 query problem
Fast initial load
However, the ID-Only Parameter Approach (3 & 4) sounds appealing because of the simplicity and composability of it + I think this approach would complicate sharing specific episodes?
Implementation Details
I'm thinking of structuring the database views like this:
-- Card view
CREATE VIEW episode_card_view AS
SELECT id, title, image_url, category
FROM episodes;
-- Detail view
CREATE VIEW episode_detail_view AS
SELECT *
FROM episodes;
Questions for the Community
Has anyone implemented something similar? What approaches did you try?
Are there any performance implications I'm missing?
How do you handle the trade-off between component complexity and data efficiency?
Are there other approaches I haven't considered?
For those with production apps, how do these patterns scale with larger datasets?
Looking forward to hearing your experiences and insights!