Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions Plugin/Framework/App/Response/Http.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace MageOS\ThemeOptimization\Plugin\Framework\App\Response;

use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\RequestInterface;
use Magento\PageCache\Model\Config;

class Http
{

protected const CONFIG_PATH = 'system/full_page_cache/';

public function __construct(
protected ScopeConfigInterface $config,
protected RequestInterface $request,
protected Config $pageCacheConfig
)
{
}

/**
* @param \Magento\Framework\App\Response\Http $subject
* @return void
*/
public function afterSetNoCacheHeaders(\Magento\Framework\App\Response\Http $subject): void
{
if ($this->config->isSetFlag(self::CONFIG_PATH . 'bfcache_enabled')) {
$excludedPaths = explode('|', $this->config->getValue(self::CONFIG_PATH . 'excluded_paths'));
if (!in_array($this->request->getModuleName(), $excludedPaths)) {
$subject->setPublicHeaders($this->pageCacheConfig->getTtl());
}
}
}
}
67 changes: 67 additions & 0 deletions Plugin/PageCache/Model/Varnish/VclGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

namespace MageOS\ThemeOptimization\Plugin\PageCache\Model\Varnish;

use Magento\Framework\Module\Dir;
use Magento\Framework\Module\Dir\Reader;
use Magento\Framework\Filesystem\Directory\ReadFactory;
use Magento\Framework\App\Config\ScopeConfigInterface;

class VclGenerator
{
protected const CONFIG_PATH = 'system/full_page_cache/';
protected const NOCACHE_FILE = 'nocache_snippet.vcl';
protected const BFCACHE_FILE = 'bfcache_snippet.vcl';
protected const EXCLUDED_PATHS_PLACEHOLDER = '/* {{ excluded_paths }} */';

public function __construct(
protected Reader $reader,
protected ReadFactory $readFactory,
protected ScopeConfigInterface $config
)
{
}

/**
* Return generated varnish.vcl configuration file
*
* @param \Magento\PageCache\Model\Varnish\VclGenerator $subject
* @param string $result
* @return string
*/
public function afterGenerateVcl(\Magento\PageCache\Model\Varnish\VclGenerator $subject, string $result): string
{
if ($this->config->isSetFlag(self::CONFIG_PATH . 'bfcache_enabled')) {
$excludedPaths = $this->config->getValue(self::CONFIG_PATH . 'excluded_paths');
$bfCacheSnippet = str_replace(
self::EXCLUDED_PATHS_PLACEHOLDER,
$excludedPaths,
$this->getBfCacheSnippet()
);
$result = str_replace($this->getNoCacheSnippet(), $bfCacheSnippet, $result);
}
return $result;
}

/**
* Read content of nocache_snippet.vcl
*/
public function getNoCacheSnippet(): string
{
$configFilePath = $this->reader->getModuleDir(Dir::MODULE_ETC_DIR, 'MageOS_ThemeOptimization');
$directoryRead = $this->readFactory->create($configFilePath);
$configFilePath = $directoryRead->getRelativePath($configFilePath . '/' . self::NOCACHE_FILE);
return $directoryRead->readFile($configFilePath);
}

/**
* Read content of bfcache_snippet.vcl
*/
public function getBfCacheSnippet(): string
{
$configFilePath = $this->reader->getModuleDir(Dir::MODULE_ETC_DIR, 'MageOS_ThemeOptimization');
$directoryRead = $this->readFactory->create($configFilePath);
$configFilePath = $directoryRead->getRelativePath($configFilePath . '/' . self::BFCACHE_FILE);
return $directoryRead->readFile($configFilePath);
}
}
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ This module provides theme-related features to improve the performance of your M

* Page transitions when navigating between pages on Magento
* Speculative preloading of internal links on hover
* BF Cache management

## Installation details

Expand Down Expand Up @@ -33,7 +34,15 @@ The module provides settings in the Magento Admin Panel under:

• **Exclude Selectors** - CSS selectors for links to never preload. Enter one selector per line. (Default: .do-not-prerender)

All values can be configured at Default, Website, and Store View scopes.
**Stores > Configuration > Advanced > System > Full Page Cache**

The module adds two new settings for bf cache management:

• **Enable Back Forward Cache** - Decide if Bf should be enabled or not

• **Excluded paths** - Specify a list of paths separated by "|" that mustn't be cached by the browser.

When "Varnish Cache" is selected as "Caching Application" this module will update the VCL generated inside the "varnish" section below using "Excluded paths".

There is no configuration for the Page Transitions feature. When installed, page transitions are always enabled for all Magento themes (frontend and admin panel).

Expand Down
29 changes: 29 additions & 0 deletions ViewModel/BFCacheSections.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace MageOS\ThemeOptimization\ViewModel;

use Magento\Customer\Block\SectionConfig;
use Magento\Framework\View\Element\Block\ArgumentInterface;

class BFCacheSections implements ArgumentInterface
{

const SECTION_TO_CHECK = 'bfcache';

public function __construct(
protected SectionConfig $sectionConfig
)
{
}

/**
* @return string
*/
public function getSectionsToReload(): string
{
return implode(
',',
array_map(fn($v) => "'$v'", $this->sectionConfig->getSections()[self::SECTION_TO_CHECK])
);
}
}
16 changes: 16 additions & 0 deletions etc/adminhtml/system.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,21 @@
</field>
</group>
</section>
<section id="system">
<group id="full_page_cache" translate="label" showInDefault="1" sortOrder="600">
<field id="bfcache_enabled" translate="label comment" type="select" sortOrder="100" showInDefault="1" canRestore="1">
<label>Enable Back Forward Cache</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<comment>Back-forward caching (or bfcache) is a browser optimization that allows instant forward and backward navigation. It significantly improves the browsing experience, especially for users with slower networks or devices.</comment>
</field>
<field id="excluded_paths" translate="label comment" type="text" sortOrder="110" showInDefault="1" canRestore="1">
<label>Excluded paths</label>
<comment>Pipe separated controller frontnames to serve with 'Cache-Control: no-store, no-cache, must-revalidate, max-age=0' response headers</comment>
<depends>
<field id="bfcache_enabled">1</field>
</depends>
</field>
</group>
</section>
</system>
</config>
6 changes: 6 additions & 0 deletions etc/bfcache_snippet.vcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Not letting browser to cache non-static files and excluded paths by magento bfcache config
if (req.url ~ "^/(/* {{ excluded_paths }} */)" && resp.http.Cache-Control !~ "private") {
set resp.http.Pragma = "no-cache";
set resp.http.Expires = "-1";
set resp.http.Cache-Control = "no-store, no-cache, must-revalidate, max-age=0";
}
6 changes: 6 additions & 0 deletions etc/config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,11 @@ productalert</exclude_paths>
<exclude_selectors>.do-not-prerender</exclude_selectors>
</speculation_rules>
</dev>
<system>
<full_page_cache>
<bfcache_enabled>0</bfcache_enabled>
<excluded_paths>checkout|cart|customer|wishlist|downloadable|sales|vault|review|newsletter</excluded_paths>
</full_page_cache>
</system>
</default>
</config>
7 changes: 7 additions & 0 deletions etc/di.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\PageCache\Model\Varnish\VclGenerator">
<plugin name="themeoptimization_bfcache_varnish_vcl_update" type="MageOS\ThemeOptimization\Plugin\PageCache\Model\Varnish\VclGenerator" />
</type>
</config>
7 changes: 7 additions & 0 deletions etc/frontend/di.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Framework\App\Response\Http">
<plugin name="themeoptimization_bfcache_no-headers_update" type="MageOS\ThemeOptimization\Plugin\Framework\App\Response\Http" />
</type>
</config>
13 changes: 13 additions & 0 deletions etc/frontend/sections.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Customer:etc/sections.xsd">
<action name="bfcache">
<section name="cart"/>
<section name="messages"/>
<section name="compare-products"/>
<section name="last-ordered-items"/>
<section name="review"/>
<section name="wishlist"/>
</action>
</config>
1 change: 1 addition & 0 deletions etc/module.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<sequence>
<module name="Magento_Framework" />
<module name="Magento_Store" />
<module name="Magento_PageCache" />
</sequence>
</module>
</config>
6 changes: 6 additions & 0 deletions etc/nocache_snippet.vcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Not letting browser to cache non-static files.
if (resp.http.Cache-Control !~ "private" && req.url !~ "^/(pub/)?(media|static)/") {
set resp.http.Pragma = "no-cache";
set resp.http.Expires = "-1";
set resp.http.Cache-Control = "no-store, no-cache, must-revalidate, max-age=0";
}
8 changes: 8 additions & 0 deletions view/frontend/layout/default.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@
<argument name="view_model" xsi:type="object">\MageOS\ThemeOptimization\ViewModel\SpeculationRules</argument>
</arguments>
</block>
<block name="theme-optimization.bfcache-customer-data"
template="MageOS_ThemeOptimization::bfcache-customer-data.phtml"
ifconfig="system/full_page_cache/bfcache_enabled"
>
<arguments>
<argument name="view_model" xsi:type="object">\MageOS\ThemeOptimization\ViewModel\BFCacheSections</argument>
</arguments>
</block>
</referenceContainer>
</body>
</page>
28 changes: 28 additions & 0 deletions view/frontend/templates/bfcache-customer-data.phtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php
/** @var Template $block */
/** @var Escaper $escaper */
/** @var SecureHtmlRenderer $secureRenderer */

use Magento\Framework\Escaper;
use Magento\Framework\View\Element\Template;
use Magento\Framework\View\Helper\SecureHtmlRenderer;
use MageOS\ThemeOptimization\ViewModel\BFCacheSections;

/** @var BFCacheSections $viewModel */
$viewModel = $block->getViewModel();
$sections = $viewModel->getSectionsToReload();
?>

<?= $secureRenderer->renderTag('script', [], <<<script
window.addEventListener('pageshow', (event) => {
if (event.persisted) {
require([
'Magento_Customer/js/customer-data'
], function (customerData) {
const sections = [$sections];
customerData.invalidate(sections);
customerData.reload(sections, true);
});
};
});
script, false); ?>