symfony / ux

Symfony UX initiative: a JavaScript ecosystem for Symfony
https://ux.symfony.com/
MIT License
859 stars 315 forks source link

[TwigComponent] Cached component #761

Open GromNaN opened 1 year ago

GromNaN commented 1 year ago

I would like to combine the features of a TwigComponent and the Twig cache extension.

My use-cache is a marketing slot that requires a DB or API call to fetch the data. This have to be displayed identically on all the pages of the website so I want to cache it.

The current approach if I want to cache the result of a twig component is to use the cache tag:

{% cache "marketing-slot-#{slug}-#{color}" ttl(300) %}
    {{ component('marketing-slot', { slug, color }) }}
{% endcache %}

What can be improved:

Proposition 1: the cache policy is part of the options

{{ component('marketing-slot', { slug, color, cache: { ttl: 300 } }) }}

Proposition 2: add a new helper

{{ cached_component('marketing-slot', { slug, color }, { ttl: 300 } }) }}

Proposition 3: define the cache policy in the PHP class

With an annotation

#[AsTwigComponent(cache: { ttl: 300 }]
class MarketingSlot {}

Already possible alternatives:

Alternative 1: Use the cache in the PHP class

This have to be implemented in all the components that needs cache.

#[AsTwigComponent()]
class MarketingSlot {
    public string $slug;
    public string $color;

    public function __construct(
        private CacheInterface $cache,
        private Repository $repo,
    ) {}

    public function getSlot(): array
    {
        return $this->cache->get('marketing-slot-'.$this->slug, fn () => $this->repo->find($this->slug));
    }
}

Alternative 2: Use ESI

WebMamba commented 1 year ago

I like the idea @GromNaN! My worried is with the embedded component: should we propagate the cache through the child component? If yes or no I think the approach gonna be different.

The second question is: Is it something we want for the live component as well?

I think my favorite approach is the 3 one. I don't think the view should be aware of the cache strategy, and it had too much-unrelated complexity to the front.

GromNaN commented 1 year ago

Yes, configuring the cache on the PHP side seems better. The cache would contain the output HTML, so subcomponents would be in this cache and not called when the cache is used. (this is the case for the cache tag actually).

kbond commented 1 year ago

Interesting! Proposition 1 or 2 seems like the best method as 3 would always cache which might not be desired?

For live components, on initial render, the cache would be used but then, on-interaction, we'd ignore the cache?

A future feature for live components is to optionally make them lazy - they wouldn't load until after the page is rendered. Here we'd likely want to use http cache.

carsonbot commented 7 months ago

Thank you for this suggestion. There has not been a lot of activity here for a while. Would you still like to see this feature?

carsonbot commented 6 months ago

Could I get a reply or should I close this?

carsonbot commented 6 months ago

Hey,

I didn't hear anything so I'm going to close it. Feel free to comment if this is still relevant, I can always reopen!

carsonbot commented 6 days ago

Thank you for this suggestion. There has not been a lot of activity here for a while. Would you still like to see this feature? Every feature is developed by the community. Perhaps someone would like to try? You can read how to contribute to get started.