Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Features/better cache mgmt #135

Merged
merged 5 commits into from
Mar 17, 2024
Merged

Features/better cache mgmt #135

merged 5 commits into from
Mar 17, 2024

Conversation

Spomky
Copy link
Member

@Spomky Spomky commented Mar 17, 2024

Target branch:
Resolves issue #

  • It is a Bug fix
  • It is a New feature
  • Breaks BC
  • Includes Deprecations

@Spomky
Copy link
Member Author

Spomky commented Mar 17, 2024

This PR should solve several issues.

Support Range Requests #126

It is possible to enabled the RangeRequestsPlugin.

pwa:
    serviceworker:
        enabled: true
        src: "sw.js"
        workbox:
            page_caches:
                - match_callback: 'navigate'
                  range_requests: true

Human-readable Max Age #129

pwa:
    serviceworker:
        enabled: true
        src: "sw.js"
        workbox:
            page_caches:
                - match_callback: 'navigate'
                  max_age: 1 year

Better Match Callback Support #125

In the previous version, the bundle used regex to determine the routes. This situation is not confortable in most situations and regular expressions can become difficult to read/write.
The bundle now supports Match Callback Handlers and some of them are provided by the bundle.
Note that the key regex is not used. Please use match_callback instead.

In most situations, the users are not required to write JS callback. This list will evolve in the future.

pwa:
    serviceworker:
        enabled: true
        src: "sw.js"
        workbox:
            page_caches:
                - match_callback: 'navigate' # eq to ({request}) => request.mode === 'navigate'
                - match_callback: 'destination: image' # eq to ({request}) => request.destination === 'image'
                - match_callback: 'pathname: /foo/bar.html' # eq to ({url}) => url.pathname === '/foo/bar.html'
                - match_callback: 'pathname: /foo/bar.html' # eq to ({url}) => url.pathname === '/foo/bar.html'
                - match_callback: 'origin: example.com' # eq to ({url}) => url.origin === 'example.com'
                - match_callback: 'endsWith: .foo' # eq to ({url}) => ({url}) => url.pathname.endsWith('.foo')
                - match_callback: 'startsWith: .foo' # eq to ({url}) => ({url}) => url.pathname.startsWith('.foo')
                - match_callback: 'regex: \/foo\/bar\/.*' # eq to new RegExp('\/foo\/bar\/.*')

Default Cache Name

Page caches may have a name. If not defined, a default name will be set.

pwa:
    serviceworker:
        enabled: true
        src: "sw.js"
        workbox:
            page_caches:
                - match_callback: 'navigate' # eq to ({request}) => request.mode === 'navigate'
                - match_callback: 'destination: image' # eq to ({request}) => request.destination === 'image'
                  cache_name: 'images'

Rules Organization #132

The rules defined by the bundle are not written before those in the sw.js file.

@Spomky Spomky added the bug Something isn't working label Mar 17, 2024
@tacman
Copy link
Contributor

tacman commented Mar 17, 2024

Looks good! I think, though, that routes are going to be more comfortable for Symfony developers. That is

- match_callback: 'route: foo_bar' # eq to ({url}) => url.pathname === '/foo/bar.html'
- match_callback: 'route: article_show' # eq to ({url}) => new RegExp('\/article\/(\d+)\/.*')

Since the rules are in javascript, obviously we need to map the routes to the paths, which is what the symfony router service provides. For routes without parameters, this is pretty straightforward, with parameters a bit more complicated.

I think the way to access the regex is something like this:

// router is injected
public function __construct(private RouterInterface $router){}

public function mapRouteToRegex($routeName = 'app_homepage'): string {

 if ($route = $this->router->getRouteCollection()->get($routeName)) {
    return $route->compile()->getRegex());
}
}

I tried to get this working in the CacheWarrmer, but I had some issue and gave up. I think it had to do with priority services and making sure the routes were loaded first.

@Spomky
Copy link
Member Author

Spomky commented Mar 17, 2024

I think, though, that routes are going to be more comfortable for Symfony developers. That is

Good idea. It is now possible.

  • match_callback: 'route: article_show' # eq to ({url}) => new RegExp('/article/(\d+)/.*')

- match_callback: 'startsWith: /articles/' does exactly the same and is much more simpler to me

@Spomky Spomky force-pushed the features/better-cache-mgmt branch from 504c818 to be5d1ca Compare March 17, 2024 20:36
@Spomky Spomky merged commit ade7573 into 1.1.x Mar 17, 2024
7 checks passed
@Spomky Spomky deleted the features/better-cache-mgmt branch March 17, 2024 20:38
@tacman
Copy link
Contributor

tacman commented Mar 18, 2024

match_callback: 'startsWith: /articles/' does exactly the same and is much more simpler to me

It doesn't do the exact same thing though.

In my app, the route 'article_show' matches /article/{id}/show, the pattern /articles matches /articles/list, /articles/browse, /articles/workflow, /articles/about, which may have different caching strategies.

I think a starting_with regex is too general, symfony programmers are used to routes.

I can understand holding off on implementing it, since it is more complicated (probably building up some gnarly regex), but startWith isn't the same as matching routes.

@Spomky
Copy link
Member Author

Spomky commented Mar 18, 2024

It doesn't do the exact same thing though.

In my app, the route 'article_show' matches /article/{id}/show, the pattern /articles matches /articles/list, /articles/browse, /articles/workflow, /articles/about, which may have different caching strategies.

You are right. In this case match_callback: 'regex: /article/(\d+)/.*' is the way to go.

I can understand holding off on implementing it, since it is more complicated (probably building up some gnarly regex), but startWith isn't the same as matching routes.

Yes and this is the reason why I created an interface so that developers can add (here or in their projects) other possibilities to simplify this. I did that for route: you mentioned earlier.
I created a few number of handlers, but use cases are limitless.

@tacman
Copy link
Contributor

tacman commented Mar 18, 2024

Ah, great, I'll look into the handler, I'm sure it'll be very useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request
Projects
None yet
2 participants