Block Caching
btCacheBlockRecord
- Default: true
- BlockDeveloper setting:
block_record
- Functionality:
- When
Config::get('concrete.cache.blocks')
is enabled, block fields (usable in view as$this->set($key, $value)
) are cached in the Blocks table by bID. - Database-wise, all blocks derive from the Block table. This means that the fields from the specific block (e.g., btAutonav) are in the btCachedBlockRecord field of the parent table.
- Can save a database request. Although the default is true, it still needs to be activated in the settings.
- When
btCacheBlockOutput
- Default: false
- BlockDeveloper setting:
block_output
- Functionality:
- Set via block dialog (context menu) in CMS admin area or in Block Controller/Developer.
- Requires
Config::get('concrete.cache.blocks')
to be enabled. - Stores rendered view in the database.
- Changes to the block set the lifetime of the current OutputCache to 0, causing it to be re-cached.
Important considerations:
- Asset registration should only occur in BlockController's
registerViewAssets
function, as this is loaded separately with the cached view. - For Ajax requests with tokens, ensure cache expires before token:
php loadImagesToken: '<?= App::make(Token::class)->generate($this->controller::GET_IMAGES) ?>'
Default token validity:const VALID_HASH_TIME_THRESHOLD = 86400; // 24 hours
\ Default cache is 5 years or Lifetime (see next point). - If client URL parameters affect the BlockController view (e.g.,
?key=value
), block output cache must not be activated. These are not cached separately. This is usually an architectural issue. Consider switching to route parameters (/view/?key
) or handling the view changes directly on the client side.
Caching conditions:
($this->viewToRender == 'view' && $config->get('concrete.cache.blocks') && $this->block instanceof Block && $this->block->cacheBlockOutput() && is_object($c) && $c->isPageDraft() === false)
btCacheBlockOutputLifetime
- Default: 0 (seconds, equivalent to 5 years)
- BlockDeveloper setting:
block_output_lifetime
- Functionality:
- Set via block dialog or in Block Controller/Developer.
- If 0, lifetime is 5 years; otherwise:
php $btCachedBlockOutputExpires = time() + $lifetime;
- For Ajax tokens with 24h threshold, set
btCacheBlockOutputLifetime < 86400
.
btCacheBlockOutputOnPost
- Default: false
- BlockDeveloper setting:
block_output_on_post
- Functionality:
- Caches only on POST requests.
- Requires
btCacheBlockOutput
to be enabled. - Condition:
php $_SERVER['REQUEST_METHOD'] != 'POST' || ($this->block->cacheBlockOutputOnPost() == true)
btCacheBlockOutputForRegisteredUsers
- Default: false
- BlockDeveloper setting:
block_output_for_registered_users
- Functionality:
- Caches also for logged-in users.
- Requires
btCacheBlockOutput
to be enabled. - Condition:
php !$u->isRegistered() || ($this->block->cacheBlockOutputForRegisteredUsers())
Overrides Cache
- Config:
'concrete.cache.overrides'
- Stores file locations in ConcreteCMS using a key/value store.
- Key is a hash value of the file handler.
Full Page Caching
Settings
'concrete.cache.pages'
'concrete.cache.full_page_lifetime'
'concrete.cache.full_page_lifetime_block'
Options:
0
: Manual activation per page- blocks: Enabled if all blocks on the page allow (no block has
btCacheBlockOutput
disabled) - all: Always enabled
Implementation:
- Uses
FilePageCache
class by default, storing pages as files (not in DB). - Caching check occurs in
DefaultBooter::bootHttpSapi()
. - Cached pages bypass rendering entirely.
- Checking for inserting in cache occurs
shouldAddToCache()
Lifetime calculation:
// See getCollectionFullPageCachingLifetimeValue() in Page class
$app = Application::getFacadeApplication();
if ($this->cCacheFullPageContentOverrideLifetime == 'default') {
$lifetime = $app['config']->get('concrete.cache.lifetime');
} elseif ($this->cCacheFullPageContentOverrideLifetime == 'custom') {
$lifetime = $this->cCacheFullPageContentLifetimeCustom * 60;
} elseif ($this->cCacheFullPageContentOverrideLifetime == 'forever') {
$lifetime = 31536000; // 1 year
} else {
if ($app['config']->get('concrete.cache.full_page_lifetime') == 'custom') {
$lifetime = $app['config']->get('concrete.cache.full_page_lifetime_value') * 60;
} elseif ($app['config']->get('concrete.cache.full_page_lifetime') == 'forever') {
$lifetime = 31536000; // 1 year
} else {
$lifetime = $app['config']->get('concrete.cache.lifetime');
}
}
if (!$lifetime) {
// we have no value, which means forever, but we need a numerical value for page caching
$lifetime = 31536000;
}
Respect Block Cache Lifetime
- Important to enable for respecting block-specific lifetimes in HTTP cache-control headers.
- Note: This may reduce cache time to 300 seconds due to autonav controller.
Behind Proxy (WAF, Load Balancing)
In PageCacheRecord, we have a validate function that checks if the canonicalUrl matches the request URL. This validation may not work correctly behind a proxy, as the proxy terminates TLS, potentially preventing page retrieval from the cache. Solutions: * Configure your dashboard to accept proxy original headers: .../index.php/dashboard/system/permissions/trusted_proxies * Use a certificate between the proxy and webserver. A self-signed certificate may suffice if you can configure the proxy to accept it.
HTTP Header Cache Control
Avoid setting cache-control
in .htaccess
for HTML responses generated by the CMS. Instead, let the CMS handle it through Full Page Caching settings. For other files like images, PDFs, fonts, and JavaScript, setting cache-control in .htaccess is appropriate.
Notes
- To verify if page caching is working, check the
cache-control
field in the response header of your HTTP server request. - Be aware of potential browser caching issues:
- After logging in, the edit bar at the top may not appear immediately due to the browser showing a cached version from before login.
- Conversely, you might see the edit bar even after logging out.
- To resolve these issues, clear the browser cache or manually navigate to the dashboard (.../dashboard).
- Once you're in the dashboard and return to the website, the cache should be properly evaluated.
Asset Caching
CSS and JavaScript Post-Processing
- Config:
'concrete.cache.assets'
- Combines assets by type and combination allowance.
- Minification should be done beforehand.
- Processing occurs in
JavascriptAsset
andCssAsset
classes.
Theme CSS Cache
- Config:
'concrete.cache.theme_css'
- Caches compiled LESS files when
true
.
LESS Output Compression
- Config:
'concrete.theme.compress_preprocessor_output'
(default:true
) - Config:
'concrete.theme.generate_less_sourcemap'
(default:false
)