wp-graphql / wp-graphql-smart-cache
Smart Caching and Cache Invalidation for WPGraphQL
Installs: 12 786
Dependents: 1
Suggesters: 0
Security: 0
Stars: 60
Watchers: 10
Forks: 14
Open Issues: 29
Type:wordpress-plugin
Requires
- appsero/client: ^1.2
Requires (Dev)
- appsero/client: ^1.2
- automattic/vipwpcs: ^2.3
- axepress/wp-graphql-stubs: ^1.14
- codeception/module-asserts: ^1.3.1
- codeception/module-cli: ^1.1
- codeception/module-db: ^1.1
- codeception/module-filesystem: ^1.0
- codeception/module-phpbrowser: ^1.0
- codeception/module-rest: ^1.3
- codeception/module-webdriver: ^1.2
- codeception/util-universalframework: ^1.0
- lucatume/wp-browser: ^3.0
- php-webdriver/webdriver: ^1.11
- phpcompatibility/phpcompatibility-wp: *
- phpstan/extension-installer: ^1.3
- phpstan/phpstan: ^1.10
- phpunit/php-timer: ^5.0
- squizlabs/php_codesniffer: ^3.6
- szepeviktor/phpstan-wordpress: ^1.3
- wp-coding-standards/wpcs: ^2.3
- wp-graphql/wp-graphql: ^1.14
- wp-graphql/wp-graphql-testcase: *
- dev-main
- v1.3.3
- v1.3.2
- v1.3.1
- v1.3.0
- v1.2.1
- v1.2.0
- v1.1.4
- v1.1.3
- v1.1.2
- v1.1.1
- v1.1.0
- v1.0.4
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0
- v0.3.9
- v0.3.8
- v0.3.7
- v0.3.6
- v0.3.5
- v0.3.4
- v0.3.3
- v0.3.2
- v0.3.1
- v0.3.0
- v0.2.3
- v0.2.2
- v0.2.1
- v0.2.0
- v0.1.2
- v0.1.1
- v0.1.0
- dev-fix/queryid-not-outputting-keys
- dev-chore/fix-docker-commands
- dev-feat/on-demand-revalidation-webhooks
- dev-feat/rebrand
- dev-release/v1.3.2
- dev-ci/test-against-6.5
- dev-release/v1.3.1
- dev-fix/#265-improve-clarity-on-settings-page
- dev-fix/+265-improve-clarity-on-settings-page
- dev-fix/260-invalidate-menus
- dev-release/v1.3.0
- dev-fix/force-enable-query-analyzer
- dev-release/v1.2.1
- dev-feat/#263-test-wp6.4
- dev-feat/+263-test-wp6.4
- dev-release/v1.2.0
- dev-bug-mutation-should-not-cache
- dev-ci/#228-tests-failing-after-wpgraphql-1.14.5
- dev-ci/+228-tests-failing-after-wpgraphql-1.14.5
- dev-release/v1.1.3
- dev-fix/#229-disable-maps-when-object-cache-is-off
- dev-fix/+229-disable-maps-when-object-cache-is-off
- dev-bug/#225-over-purging-connections
- dev-bug/+225-over-purging-connections
- dev-release/v1.1.1
- dev-fix/#220-menus-are-considered-private-even-if-model-has-been-filtered-to-public
- dev-fix/+220-menus-are-considered-private-even-if-model-has-been-filtered-to-public
- dev-release/v1.1.0
- dev-fix/#212-over-purging-tags
- dev-fix/+212-over-purging-tags
- dev-feat/#213-graphql_purge_logs
- dev-feat/+213-graphql_purge_logs
- dev-release/v1.0.4
- dev-fix/post_exists-error
- dev-fix/#206-ignore-apple-news-meta-key
- dev-fix/+206-ignore-apple-news-meta-key
- dev-release/v1.0.2
- dev-release/v1.0.1
- dev-fix/public-visible-queries
- dev-bug/purge-all-varnish-cache
- dev-trunk
- dev-release/v1.0
- dev-fix/vendor-dir-not-deployed
- dev-feat/add-wordpress-org-deploy
- dev-release/v0.3.4
- dev-bugfix/update-min-version-constant-name
- dev-bug/#183-update-min-version-of-wpgraphql-to-check
- dev-bug/+183-update-min-version-of-wpgraphql-to-check
- dev-release/v0.3.2
- dev-feat/#177-exclude-specific-queries
- dev-feat/+177-exclude-specific-queries
- dev-fix/#176-fatal-error-for-composer-installs
- dev-fix/+176-fatal-error-for-composer-installs
- dev-bug/add-header-support-for-when-queryId-is-used
- dev-release/0.2.1
- dev-release/v0.2.0
- dev-feature/move-cache-key-generation-to-wpgraphql-core
- dev-feature/#165-async-purge
- dev-feature/+165-async-purge
- dev-fix/max-age-batch
- dev-add/comment-cache-eviction
- dev-release/v0.1.2
- dev-refactor/save-urls
- dev-fix/batch-queries
- dev-fix/purge-all-callback
- dev-bug/#154-broken-tests-for-post-invalidation
- dev-bug/+154-broken-tests-for-post-invalidation
- dev-ci/add-pr-artifact
- dev-release/v0.1.1
- dev-feature/add-extension-output-when-response-is-cached
- dev-feature/graphql-document-not-publicly-queryable
- dev-feature/rename-to-wp-graphql-smart-cache
- dev-admin/update-settings-text
- dev-feature/remove-graphiql-extension
- dev-fix/wp-cache-save-to-array
- dev-bugfix/evict-caches-after-delete-user-and-reassign
- dev-add/gh-action-zip
- dev-refactor/purge_nodes_cb
- dev-feature/tests/post-tests
- dev-update/editor-content-text
- dev-fix/list-invalidation-ids
- dev-bug/fix-apollo-client-error
- dev-feature/tests/user-tests
- dev-feature/publish-post-tests
- dev-feature/purge-lists
- dev-feature/purge-settings
- dev-feature/update-abstract-connection-callback-to-track-possible-types
- dev-feature/add-wpgraphql-testcase
- dev-feature/add-wp-graphql-testcase
- dev-feature/purge-metadata
- dev-tests/cache-storage
- dev-bug/url-encode-not-purging
- dev-feature/#49-edit-and-save-documents
- dev-feature/+49-edit-and-save-documents
- dev-feature/purge-posts-cache
- dev-feature/admin-cache-purge
- dev-feature/delete-terms-with-query
- dev-feature/object-cache
- dev-feature/graphiql-integration
- dev-feature/cache_ttl
- dev-feature/scaffold-document-editor
This package is auto-updated.
Last update: 2024-11-04 17:31:53 UTC
README
WPGraphQL Smart Cache
Do you want your API data fast or accurate? With WPGraphQL Smart Cache, you can have both.
WPGraphQL Smart Cache is a free, open-source WordPress plugin that provides support for caching and cache invalidation of WPGraphQL Queries.
To get the most out of this plugin, we recommend using GET requests with Network Caching, which requires your WordPress install to be on a supported host.
BREAKING CHANGES: We may make breaking changes in the future to improve functionality and experience. If we do, we will use semver to do so. Pay attention to release notes and upgrade notices before updating.
Video Overview
Docs π
- Overview
- Quick Start
- Features
- Extending / Customizing Functionality
- FAQ and Troubleshooting
- Known Issues
- Providing Feedback
Overview
WPGraphQL has essentially become the standard when it comes to building headless WordPress experiences.
The flexibility and tooling around GraphQL is attractive, but it can come at a cost.
Performance Issues
"The fastest code is the code which does not run" - Robert Galanakis
WPGraphQL is optimized for run-time performance by using DataLoader methods and other techniques to reduce run time execution cost, but the fact is that WPGraphQL is built on top of WordPress and respects the WordPress application layer β including actions, filters, authentication rules, and the WordPress database structure.
This means that anytime a WPGraphQL request is executed against WordPress (much like any type of request made to WordPress) there is a cost, and the cost can sometimes be problematic.
One of the fastest ways to load WordPress, is to prevent WordPress from being loaded at all!
This is no different for WPGraphQL.
Solving the Performance Issues
This is where WPGraphQL Smart Cache comes in.
WPGraphQL Smart Cache has integrations with a multiple layers of caching to provide users of WPGraphQL with both fast and accurate data managed in WordPress.
The over-simplification of WPGraphQL Smart Cache, is to capture the results of GraphQL Requests, store the response in a cache, and use the cached response for future requests instead of executing the query and all of its resolvers at each request.
π Quick Start
This quick start guide will cover the basics of Object Caching for WPGraphQL Queries and Cache Invalidation.
If you're WordPress install is on a supported host, you will benefit more from Network Caching and we recommend you head over to the Network Cache Quick Start instead of this quick-start. If you're not on a supported host, tell your host to check out our hosting guide and carry on with this Quick Start guide below.
π Quick Start Guide
- Install & Activate
- Enable WPGraphQL Object Cache
- Enable WPGraphQL Tracing (optional)
- Execute a query in GraphiQL IDE
- Execute the same query again
- Invalidate the Cache
Install & Activate
If you haven't already installed and activated the WPGraphQL Smart Cache plugin, follow the Install & Activation guide, then come back here.
Enable WPGraphQL Object Cache
With the latest versions of WPGraphQL and WPGraphQL Smart Cache installed and activated, navigate to the "WPGraphQL > Settings" page in your WordPress dashboard, then select the "Cache" tab.
From this settings page, check the "Use Object Cache" setting and click "Save Changes".
This will activate the object cache functionality for WPGraphQL Queries.
Enable WPGraphQL Tracing (optional)
While testing, you can enable "WPGraphQL Tracing" to see data about how long (in microseconds) each field in a GraphQL request takes to resolve.
To enable WPGraphQL Tracing, navigate to the "WPGraphQL > Settings" page and select the "WPGraphQL General Settings" tab.
Check the "Enable GraphQL Tracing" option, and set the "Tracing Role" to "Any". This will let us see the trace data in public requests as we test the caching functionality.
NOTE: When you're done testing, consider disabling tracing as it is intended to be a debug tool, and it does add weight to the responses client applications download from the WPGraphQL Server.
Execute a query using the GraphiQL IDE
Next, navigate to the "GraphQL > GraphiQL IDE" screen in the WordPress dashboard.
Paste the following query in the IDE.
{ posts { nodes { id title uri } } }
Execute the query by pressing the play button.
NOTE: To ensure your GraphiQL IDE is not executing as a logged in user, toggle the button to the right of the "Play" button. If a green status indicator is showing, requests will be authenticated and will bypass the cache. Public, non-authenticated requests will be served from the cache.
You should see results similar to the following screenshot:
If you inspect the response, you will notice the "graphqlSmartCache" key with a nested "graphqlObjectCache" key under the "extensions" payload.
If the value of the graphqlObjectCache
key is empty, the request was not served from cache.
If you enabled GraphQL Tracing, take a look at the `extensions.tracing" payload.
You will see a "duration" field, which is the overall time the query took to resolve (in microseconds).
Take note of this value. For me, it was: "duration": 23271,
Additionally, you will see a lot of data about each field that was resolved. You don't need any of this data, just take note of its presence.
Execute the Query Again
Execute the same query again (still as a non-authenticated request).
This time, you should observe the graphqlSmartCache.graphqlObjectCache
key will have data returned.
You should see a payload similar to the following:
{ "data": { ... }, "extensions": { ... "graphqlSmartCache": { "graphqlObjectCache": { "message": "This response was not executed at run-time but has been returned from the GraphQL Object Cache", "cacheKey": "9cc3bbab3abfcc618153b3e9a3df403c2408f1007abe35aeaec0e2d640fb1233" } } } }
This means that the request was served from the WPGraphQL Object Cache instead of executing all of the resolvers for every field.
If you enabled GraphQL Tracing, take a look at the `extensions.tracing" payload again.
This time, you should see a lower value for the duration field. For me, the value was "duration": 9933
. Nearly 3x faster!
Additionally, you will note that the resolvers
field under tracing is empty. This is because the data was returned from the object cache and no resolvers were executed!
Invalidate the Cache
Go ahead and execute the same query a few more times, and note that it continues to be served from the cache.
In order to balance "Fast" and "Accurate" data, WPGraphQL Smart Cache listens to events in WordPress, and when relevant events occur, the relevant cache(s) are evicted, and fresh data is served.
In another browser tab, navigate to the "Posts" page and "quick edit" the most recent post, adding a period to the title.
Then, back in the browser tab with the GraphiQL IDE open, execute the query again.
The query should be a "cache miss" and we should see the accurate, updated title, and the `graphqlSmartCache.graphqlObjectCache" output under "extensions" should be empty.
π Next Steps
Now that you've completed the quick start, continue on learn more about the features of the WPGraphQL Smart Cache plugin.
Features
Additional Docs
Related Links π
Known Issues
Batch Queries
There are currently some issues around Batch Queries. If you use Batch Queries in your client application, we will need more time before we have WPGraphQL Smart Cache working for you.
If you use Batch Queries in your application and would like to make use of WPGraphQL Smart Cache, let us know in the WPGraphQL Smart Cache slack channel or GitHub Discussions so we can learn more about your use cases.
Missing Invalidation Hooks
Currently, weβre missing invalidation hooks related to Settings (options).
That means cache for queries that ask for Settings (i.e General Settings, Discussion Settings, etc) will not be invalidated/evicted automatically when actions related to those things occur.
You can read more about the nuances of supporting settings here: #158
Providing Feedback
If you have feedback after using WPGraphQL Smart Cache, we would love to hear it!
Issues & Bug Reports
If you have an issue or a bug to report, the best place to do that is in the GitHub Repository: https://github.com/wp-graphql/wp-graphql-smart-cache/issues
Feature Requests
If you have an idea for a feature that feels like it would be a nice addition to the WPGraphQL Smart Cache plugin, you can let us know in the Discussion section of the GitHub Repository: https://github.com/wp-graphql/wp-graphql-smart-cache/discussions
General Discussion
For general discussion about the plugin, you can visit the WPGraphQL Slack (join here) and join the #wp-graphql-smart-cache
channel, or post in the GitHub Discussions.
Security Concerns
If you believe youβve found something in the WPGraphQL Smart Cache codebase that could be a security concern, please let us know by emailing us directly at info@wpgraphql.com.
Please do not email other bug reports, feature requests or support questions to this email address.
Privacy Policy
WPGraphQL Smart Cache uses Appsero SDK to collect some telemetry data upon user's confirmation. This helps us to troubleshoot problems faster & make product improvements.
Appsero SDK does not gather any data by default. The SDK only starts gathering basic telemetry data when a user allows it via the admin notice. We collect the data to ensure a great user experience for all our users.
Integrating Appsero SDK DOES NOT IMMEDIATELY start gathering data, without confirmation from users in any case.
Learn more about how Appsero collects and uses this data.