Caching
Phlex is impressively fast, rendering HTML at approximately 1.4 GB/s per core on a MacBook Pro (M3 Max) without performance degradation as you extract more components. Despite this performance, there are still scenarios where view caching can provide additional benefits.
Cache the data layer first
Before implementing view caching, consider caching at the data layer. View caching becomes increasingly complex as you add more state and dynamic content to your components. Whenever possible, cache expensive database queries, API calls, or computational results rather than the rendered HTML output.
This approach offers several advantages:
- Simpler cache invalidation logic
- Better cache hit rates across different views
- Reduced complexity in your component code
- More predictable performance characteristics
Caching Phlex views
🔓 Unlock content
Pre-order this course to unlock this video, source code, and content. You'll also get to work with Brad to fine tune the course cirriculum.
▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓
Fragment caching
▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓
class Components::ExpensiveWidget < ▓▓▓▓▓▓▓▓▓▓::▓▓▓▓
def ▓▓▓▓▓▓▓▓▓▓(▓▓▓▓)
▓▓▓▓▓ = ▓▓▓▓
end
def ▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓(▓▓▓▓▓) do
▓▓▓(class: "widget") do
▓▓ { "Welcome, #{▓▓▓▓▓.▓▓▓▓}!" }
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
end
end
end
private
def ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓ ▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓
▓▓ do
▓▓▓▓▓.▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓.▓▓▓▓ do |▓▓▓▓▓▓▓▓|
▓▓ { ▓▓▓▓▓▓▓▓.▓▓▓▓▓▓▓ }
end
end
end
end
Cache keys and dependencies
▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓
class Components::UserDashboard < ▓▓▓▓▓▓▓▓▓▓::▓▓▓▓
def ▓▓▓▓▓▓▓▓▓▓(▓▓▓▓)
▓▓▓▓▓ = ▓▓▓▓
end
def ▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓([▓▓▓▓▓, ▓▓▓▓▓.▓▓▓▓▓.▓▓▓▓▓▓▓(:updated_at)]) do
▓▓▓(class: "dashboard") do
▓▓ { "#{▓▓▓▓▓.▓▓▓▓}'s Dashboard" }
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
end
end
end
end
Conditional caching
▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓
class Components::WeatherWidget < ▓▓▓▓▓▓▓▓▓▓::▓▓▓▓
def ▓▓▓▓▓▓▓▓▓▓(▓▓▓▓▓▓▓▓)
▓▓▓▓▓▓▓▓▓ = ▓▓▓▓▓▓▓▓
end
def ▓▓▓▓▓▓▓▓▓▓▓▓▓
if ▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓(▓▓▓▓▓▓▓▓▓, expires_in: 15.▓▓▓▓▓▓▓) do
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
end
else
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
end
end
private
def ▓▓▓▓▓▓▓▓▓▓▓▓▓
▓ ▓▓▓▓ ▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓ ▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓.▓▓▓▓&.▓▓▓▓▓▓▓▓▓▓▓▓▓▓
end
def ▓▓▓▓▓▓▓▓▓
"weather_widget/#{▓▓▓▓▓▓▓▓▓}/#{▓▓▓▓.▓▓▓▓▓▓▓.▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓}"
end
def ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓(class: "weather") do
▓ ▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓
end
end
end
Best practices for caching
- ▓▓▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓
- ▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓
- ▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓ ▓▓ ▓▓▓▓ ▓▓▓▓▓ ▓▓▓
- ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓
- ▓▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓ ▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓ ▓▓▓▓▓▓▓ ▓▓▓▓▓