=== Surge === Contributors: kovshenin Donate link: https://github.com/kovshenin/surge Tags: cache, performance, caching Requires at least: 5.7 Tested up to: 5.8.2 Requires PHP: 7.3 Stable tag: 1.0.1 License: GPLv3 or later License URI: https://www.gnu.org/licenses/gpl-3.0.en.html Surge is a very simple and fast page caching plugin for WordPress. == Description == Surge generates and serves static HTML files for your WordPress site, causing quicker requests, faster load times and a shorter time to first byte (TTFB). Surge does not require configuration, and has no options. It works out of the box on any well-configured hosting platform. Cached files are stored on disk, and automatically invalidated when your site is updated. In various load tests, Surge has shown to easily handle 1000-2500 requests per second at 100 concurrent, on a small single-core server with only 1 GB of RAM. That's over 70 times faster than a stock WordPress install. == Installation == Via the WordPress Dashboard: navigate to Plugins - Add New. In the search bar type "surge" and hit Enter. Find the Surge plugin in the search results, hit Install, then Activate. Manually: download the Surge plugin .zip file from WordPress.org. In your WordPress admin navigate to Plugins - Add New - Upload. Select the .zip file and hit Upload. Activate the plugin after upload is successful. Manually via FTP: download the Surge plugin .zip file from WordPress.org, extract the archive, make sure the directory is called "surge". Use your FTP/SFTP client to upload the "surge" directory to wp-content/plugins. Then activate the plugin in your WordPress admin from the Plugins section. Using WP-CLI: wp plugin install surge --activate == Frequently Asked Questions == = Where is the plugin configuration screen? = There isn't one. = Is my cache working? = Visit the Site Health screen under Tools in your WordPress dashboard. Common caching errors, like installation problems, etc. will appear there. Otherwise, open your site in an Incognito window to see the cached version. You could also look for the "X-Cache" header in the server response. = Why am I getting cache misses? = Below are a few common reasons: * You are logged into your WordPress site * You have a unique cookie set in your browser * A unique query parameter will also cause a cache miss, except common marketing parameters, such as utm_campaign, etc. * Request methods outside of GET and HEAD are not cached = Can I exclude page X from being cached? = Of course. If you pass a "Cache-Control: no-cache" header (or max-age=0) the request will automatically be excluded from cache. Note that most WordPress plugins will already do this where necessary. = fpassthru() has been disabled for security reasons = It seems like your hosting provider disabled the fpassthru() function, likely by mistake. This is a requirement for Surge. Please get in touch with them and kindly ask them to enable it. = How can I support Surge? = If you like Surge, consider giving us a [star on GitHub](https://github.com/kovshenin/surge) and a review on WordPress.org. == Changelog == = 1.0.1 = * Various invalidation enhancements and fixes * Remove advanced-cache.php when plugin is deactivated * Add a note about fpassthru() in FAQ * Minor fix in Site Health screen tests = 1.0.0 = * Anonymize requests to favicon.ico and robots.txt * Improve cache expiration, add cache expiration by path = 0.1.0 = * Initial release
Surge is a very simple and fast page caching plugin for WordPress.
Overview
Comments
-
Cache-Control: max-age not honored
I'm trying to cache a WP Rest API response that calls to a 3rd party API, the 3rd party API takes few seconds to query.
Surge caches the response by default, everything is fine, except if I want the Rest API to hit the 3rd party API again after the max-age expires.
Looks like Surge only checks for
no-cache
andmax-age=0
, are there any plans to support variable number of max-age likeheader( 'Cache-Control: max-age=60' );
? -
(feat): allow config values to be changed with hook 'surge/config'
The values in the config array are hardcoded. Sometimes, it could be useful to change the values.
The hook
surge/config
(but name can be changed if required), allows values to be changed. -
Add a way of disabling overwriting `WP_CACHE` value in wp-config.php
Upon install, whatever the value of
WP_CACHE
is inwp-config.php
is removed it would be good to be able to disable this behaviour, useful for cases where config is configured from env vars and plugins are installed as part of a build process for example.I'm happy to provide a PR, but just wanted to run it by you first. Would you be happy with wrapping in a conditional with a filter?
-
Warning when looping through metadata headers
Some users reported a PHP warning in foreach() in include/serve.php on line 76, which is the loop through the headers, saved in the cache metadata. It seems like in some cases, when WordPress doesn't send any headers at all, or only ones that we choose to skip:
https://github.com/kovshenin/surge/blob/main/include/cache.php#L39
The
bug$headers
variable is never defined as an array, and is thus saved asnull
in the metadata, which then causes the warning on display. -
Feature: A way to modify the cache configuration
Following up on #1 here. Unfortunately the proposed solution in that PR doesn't quite work as part of the configuration code is executed way too early for any WordPress actions or filters to be called. In this PR users are allow dot create their own configuration file, and attach it with the
WP_CACHE_CONFIG
constant in wp-config.php, for example:define( 'WP_CACHE', true ); define( 'WP_CACHE_CONFIG', __DIR__ . '/cache-config.php' );
The file itself has access to the original Surge
$config
but must return a valid configuration array. You can not unset any of the configuration keys, but you can extend them or override them. For example, if you wish to add your own ignored query variable, you would have the following config:$config['ignore_query_vars'][] = 'custom_query_var'; return $config;
You can prevent the request from being cached by setting the TTL to zero, for example:
if ( false !== stripos( $_SERVER['HTTP_USER_AGENT'], 'googlebot' ) ) { $config['ttl'] = 0; } return $config;
If you wish to cache mobile visitors in a different cache bucket, you can use the
variants
array, like so:function is_mobile() { // Your mobile check implementation return true; // or false } $config['variants']['mobile'] = is_mobile(); return $config;
Looking forward to your feedback @edwinsiebel!
enhancement -
Publishing a new post or untrashing a post does not invalidate cache correctly
Spotted by @roytanck. Publishing a new post does not invalidate the home page cache (or other related archives) because it's not been flagged with this new post ID. Untrashing a post has the same problem for the same reasons.
Reproduce:
- Make sure home is set to list latest 10 posts
- Prime the home page cache in incognito mode
- Publish a new post
- Check home page, the new post will be missing until the TTL runs out
The published post permalink will still work immediately as it's invalidated correctly by post ID, but things like "latest posts" widgets, etc. will also have a hard time picking up the new post until it expires due to TTL.
-
Allow multiple headers with the same name.
In HTTP headers it is allowed to specify the same name. In particular, it can be useful to specify links for preload:
Link: <https://example.com/other/styles.css>; rel=preload; as=style Link: </theme/styles.css>; rel=preload; as=style
Some info about multiple headers https://stackoverflow.com/questions/3241326/set-more-than-one-http-header-with-the-same-name
-
Redirect loop on / to %2F conversion in unknown query arguments
Seems like there is some code in Core that converts / to %2F in unknown query arguments performing a redirect, but the redirect is cached under the same cache key as the %2F version, resulting in a redirect loop. Ideally these requests are cached under different keys.
bug -
Fix locking when writing flags.json
Multiple concurrent requests could be attempting to write flags.json, and the current
file_put_contents()
approach will blindly overwrite whatever another request may have written at the same time.In this PR we move the
LOCK_EX
lock before we're about to read the contents of the file, and release the lock right after we've written to the file. So a concurrent request will wait for the lock to be released, before attempting to read the flags. -
get_post_type_object() can return null, causing a PHP notice
This get_post_type_object() call in some cases can return
null
when transitioning objects of unknown types (auto-draft if I had to guess), causing a PHP notice: Trying to get property 'public' of non-object.Reported on the forums here.
Should check the
bug good first issue$obj
variable prior to accessing its properties. -
Invalidation enhancements
In this PR:
- Flag requests with non-singular queries for a specific post_type
- Flag WooCommerce products to work around various caches
- Invalidate post_type caches on transition_post_status
This is work in progress, some of it related to #2.
Will also need to look at
nav_menu_items
, because those queries run withsuppress_filters
by-passing ourthe_posts
. Also a very old but still in-use functionget_pages
does its own thing, but has some filters we can hook into.cc @soulseekah
-
PHP warnings
PHP version 7.4.30 Surge version 1.0.4
This combination results in the following PHP warnings
PHP Warning: Use of undefined constant DIR - assumed 'DIR' (this will throw an Error in a future version of PHP) in /var/www/doma.in/config/application.php on line 70
PHP Warning: include(DIR/cache-config.php): failed to open stream: No such file or directory in /var/www/doma.in/content/plugins/surge/include/common.php on line 56
We are using bedrock based structure, hence the content/plugins.
-
Manipulating PHP globals
Hi!
While playing around with Surge, I noticed the plugin makes changes to PHP globals at various places:
- https://github.com/kovshenin/surge/blob/e68d4be79ab7fafe54799413962d9ea9a9150768/include/common.php#L143
- https://github.com/kovshenin/surge/blob/e68d4be79ab7fafe54799413962d9ea9a9150768/include/common.php#L115-L118
- https://github.com/kovshenin/surge/blob/e68d4be79ab7fafe54799413962d9ea9a9150768/include/common.php#L107-L108
Is it intended?
Since
key()
is called on every request, you may end up messing with third party code that relies on those globals and not only on edge cases. -
Enable cache for logged in users
Hey, first of all thanks for the excellent plugin, it works incredibly well out of the box!
I have been poking through the plugin source code and I can't seem to find the logic that disables/prevents caching for logged in users.
What I am hoping is possible is that I can create a custom config file like this Surge Configuration Example. And setup some logic to enable caching for logged in users with a certain custom role (essentially a role that only has frontend access).
If you could point me in the direction of how Surge currently identifies logged in users I'd really appreciate it.
-
Preloading pages
I'm trying out Surge on a low-traffic site and it doesn't seem like crawling is enough to negate the need for preloading. I visited the homepage, recent posts, and main-menu items periodically over the course of an hour, and frequently got cache-misses.
I bumped the TTL to a week as a workaround, but I'm worried that'll still result in a lot of misses. This type of site has ~300 posts, but isn't updated frequently, and is on shared hosting. So I'm more worried about slow load times on the long tail of older posts than I am about edge cases where the cache isn't invalidated fast enough.
-
Can't clean `php://input`
Hey ๐๐ป ย I noticed this:
https://github.com/kovshenin/surge/blob/e68d4be79ab7fafe54799413962d9ea9a9150768/include/common.php#L239
FYI, I dug into that recently for another project, and it seems like it's not possible โน๏ธ
I'd be happy to be wrong if you found something I missed, though!
Releases(1.0.4)
-
1.0.4(Apr 19, 2022)
- Add a WP-CLI command to invalidate/flush page cache
- Fix redirect loop with Core's redirect_canonical for ignore_query_vars
- Fix warnings for requests with empty headers
- Fix warnings when cron cleanup attempts to read a file that no longer exists
- Add a filter to disable writing to wp-config.php
Full Changelog: https://github.com/kovshenin/surge/compare/1.0.3...1.0.4
Source code(tar.gz)
Source code(zip)
-
1.0.3(Feb 8, 2022)
- Invalidate cache when posts_per_page is changed
- Fix redirect loop with unknown query vars caused by Core's redirect_canonical
- Ignore X-Cache and X-Powered-By headers from cache metadata
- Allow multiple headers with the same name
Source code(zip)
-
1.0.2(Jan 12, 2022)
-
1.0.1(Dec 13, 2021)
-
1.0.0(Dec 7, 2021)
-
0.1.0(Dec 4, 2021)
A Wordpress plugin that allows you to customize a news feed on your home page
=== Plugin Name === Contributors: Noora Chahine Requires at least: 4.0.1 Tested up to: 5.4 Stable tag: 5.2 License: GPLv2 or later License URI: http:/
๐๏ธ A WordPress plugin to automatically send a user to the page or post if it's the only search result available.
One Search Result A WordPress plugin to automatically send a user to the page or post if it's the only search result available. When there is only one
Free WordPress plugin to generate Admin Settings Page.
ClioWP Settings Page ClioWP Setting Page is a free WordPress Plugin which creates a sample Settings Page. This โtestโ page contains almost any type of
A WordPress plugin to suspend WordPress sites automagically. Simple and lightweight, no annoying ads and fancy settings.
Suspend WP A WordPress plugin to suspend WordPress sites automagically. Simple and lightweight, no annoying ads and fancy settings. ?? Demo (coming so
Simple WordPress plugin to learn how to understand WordPress Crons and the Action Scheduler library.
Simple WordPress plugin to learn how to understand WordPress Crons and the Action Scheduler library. Import Jamendo playlists with tracks in WordPress posts.
A one-page user-profile WordPress theme
X3P0 - Profile A one-page user-profile WordPress theme. Currently, it ships with a few patterns. More will be added. Credits patterns/artist.php - Pho
WordPress single-page theme with profile patterns.
X3P0 - Reflections A one-page user-profile WordPress theme. Really, it's just a single page. View Demo โ Recommended This theme is designed to work wi
The Pronamic WordPress Basecone plugin allows you to connect your WordPress installation to Basecone.
Pronamic WordPress Basecone The Pronamic WordPress Basecone plugin allows you to connect your WordPress installation to Basecone. Table of contents Au
WordPress plugin that lets you use Discourse as the community engine for a WordPress blog
WP Discourse Note: the wp-discourse plugin requires >= PHP-5.4.0. The WP Discourse plugin acts as an interface between your WordPress site and your Di
WordPress & TypeScript. Simple starter template for WordPress projects
WordPress & TypeScript. Simple starter template for WordPress projects that want to use TypeScript in combination with @wordpress/scripts
Beauty and simple Wordpress video player plugin. Powerfull and lite in use.
Sonic Spectre Video Player Beauty and simple Wordpress video player plugin. Powerfull and lite in use. Quick Start: Download plugin from this repo and
This WordPress Plugin Boilerplate is meant for you to develop your own plugin on.
WordPress Plugin Boilerplate This plugin boilerplate is meant for you to develop your own plugin on. Support & collaboration Features OOP plugin core
A simple platform information plugin for WordPress. Shows you environment variables, PHP settings and more.
A simple platform information plugin for WordPress. Shows you environment variables, PHP settings and more.
A curated list of Awesome WordPress Theme, Plugins and Framework development Resources and WordPress Communities.
Awesome WordPress A curated list of Awesome WordPress Theme, Plugins and Framework development Resources and WordPress Communities. Inspired by bayand
Simple Wordpress plugin that adds social share buttons
Super Fast Social Share Simple Wordpress plugin that adds social share buttons to Wordpress posts. ?? Screenshots You can either load the default css
Simple WordPress plugin demonstrating how one can sort posts within a taxonomy.
Simple WordPress plugin to demonstrate how to sort posts in a taxonomy. How to test Download the project and install it as a plugin in your WordPress
A simple scaffold used for what's needed to spin up a Composer-based WordPress plugin.
A simple scaffold used for what's needed to spin up a Composer-based WordPress plugin.
Divi Migration Tools - A simple plugin to assist in the conversion of Divi to WordPress.
Divi Migration Tools Different criteria to migrate the Divi shortcodes. Migrate the following Divi shortcodes to Gutenberg blocks ?? [et_pb_video] It
Simple WordPress plugin starter framework.
WordPress Plugin Starter This is the official WordPress plugin starter framework for Highfivery. The purpose behind it is to improve the quality of th