Skip to content

Commit

Permalink
~ 50% reduction in the time to render a page (#49)
Browse files Browse the repository at this point in the history
  • Loading branch information
BelleNottelling committed Jun 19, 2023
1 parent d920b26 commit 8d9e894
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 42 deletions.
14 changes: 8 additions & 6 deletions src/AntCMS/AntCMS.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,25 +126,27 @@ public function getPage(string $page)
*/
public static function getThemeTemplate(string $layout = 'default', string $theme = null)
{
$theme = $theme ?? AntConfig::currentConfig('activeTheme');
$theme ??= AntConfig::currentConfig('activeTheme');

if (!is_dir(antThemePath . '/' . $theme)) {
if (!is_dir(antThemePath . DIRECTORY_SEPARATOR . $theme)) {
$theme = 'Default';
}

$basePath = AntTools::repairFilePath(antThemePath . DIRECTORY_SEPARATOR . $theme);

if (strpos($layout, '_') !== false) {
$layoutPrefix = explode('_', $layout)[0];
$templatePath = AntTools::repairFilePath(antThemePath . '/' . $theme . '/' . 'Templates' . '/' . $layoutPrefix);
$templatePath = $basePath . DIRECTORY_SEPARATOR . 'Templates' . DIRECTORY_SEPARATOR . $layoutPrefix;
$defaultTemplates = AntTools::repairFilePath(antThemePath . '/Default/Templates' . '/' . $layoutPrefix);
} else {
$templatePath = AntTools::repairFilePath(antThemePath . '/' . $theme . '/' . 'Templates');
$templatePath = $basePath . DIRECTORY_SEPARATOR . 'Templates';
$defaultTemplates = AntTools::repairFilePath(antThemePath . '/Default/Templates');
}

try {
$template = @file_get_contents(AntTools::repairFilePath($templatePath . '/' . $layout . '.html.twig'));
$template = @file_get_contents($templatePath . DIRECTORY_SEPARATOR . $layout . '.html.twig');
if (empty($template)) {
$template = file_get_contents(AntTools::repairFilePath($defaultTemplates . '/' . $layout . '.html.twig'));
$template = file_get_contents($defaultTemplates . DIRECTORY_SEPARATOR . $layout . '.html.twig');
}
} catch (\Exception) {
}
Expand Down
48 changes: 30 additions & 18 deletions src/AntCMS/AntCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ class AntCache
/**
* Creates a new cache object, sets the correct caching type. ('auto', 'filesystem', 'apcu', or 'none')
*/
public function __construct()
public function __construct(null|string $mode = null)
{
$config = AntConfig::currentConfig();
$mode = $config['cacheMode'] ?? 'auto';
$mode = $mode ?? AntConfig::currentConfig('cacheMode') ?? 'auto';

switch ($mode) {
case 'none':
$this->cacheType = self::noCache;
Expand Down Expand Up @@ -86,11 +86,9 @@ public function getCache(string $key)
return file_get_contents($cachePath);
case self::apcuCache:
$apcuKey = $this->cacheKeyApcu . $key;
if (apcu_exists($apcuKey)) {
return apcu_fetch($apcuKey);
} else {
return false;
}
$success = false;
$result = apcu_fetch($apcuKey, $success);
return $success ? $result : false;
default:
return false;
}
Expand Down Expand Up @@ -129,16 +127,20 @@ public function isCached(string $key)
*/
public function createCacheKey(string $content, string $salt = 'cache')
{
/**
* If the server is modern enough to have xxh128, use that. It is really fast and still produces long hashes
* If not, use MD4 since it's still quite fast.
* Source: https://php.watch/articles/php-hash-benchmark
*/
if (defined('HAS_XXH128')) {
return hash('xxh128', $content . $salt);
} else {
return hash('md4', $content . $salt);
}
return hash(self::getHashAlgo(), $content . $salt);
}

/**
* Generates a unique cache key for a file and a salt value.
* The salt is used to ensure that each cache key is unique to each component, even if multiple components are using the same source content but caching different results.
*
* @param string $filePath The file path to create a cache key for.
* @param string $salt An optional salt value to use in the cache key generation. Default is 'cache'.
* @return string The generated cache key.
*/
public function createCacheKeyFile(string $filePath, string $salt = 'cache')
{
return hash_file(self::getHashAlgo(), $filePath) . $salt;
}

public static function clearCache(): void
Expand All @@ -162,4 +164,14 @@ public static function clearCache(): void
}
}
}

public static function getHashAlgo(): string
{
/**
* If the server is modern enough to have xxh128, use that. It is really fast and still produces long hashes
* If not, use MD4 since it's still quite fast.
* Source: https://php.watch/articles/php-hash-benchmark
*/
return defined('HAS_XXH128') ? 'xxh128' : 'md4';
}
}
8 changes: 3 additions & 5 deletions src/AntCMS/AntConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ public static function generateConfig()
*/
public static function currentConfig(?string $key = null)
{
$config = AntYaml::parseFile(antConfigFile);
// FS cache enabled to save ~10% of the time to deliver the file page.
$config = AntYaml::parseFile(antConfigFile, true);
if (is_null($key)) {
return $config;
} else {
Expand All @@ -57,7 +58,6 @@ public static function currentConfig(?string $key = null)
}
}


/**
* @param array<mixed> $array
* @param array<mixed> $keys
Expand All @@ -67,13 +67,11 @@ private static function getArrayValue(array $array, array $keys)
{
foreach ($keys as $key) {
if (isset($array[$key])) {
$array = $array[$key];
return $array[$key];
} else {
return null;
}
}

return $array;
}

/**
Expand Down
10 changes: 4 additions & 6 deletions src/AntCMS/AntPages.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,29 +52,26 @@ public static function generatePages()
AntYaml::saveFile(antPagesList, $pageList);
}

/** @return array<mixed> */
public static function getPages()
public static function getPages():array
{
return AntYaml::parseFile(antPagesList);
}

/**
* @param string $currentPage optional - What page is the active page. Used for highlighting the active page in the navbar
* @return string
*/
public static function generateNavigation(string $navTemplate = '', string $currentPage = '')
public static function generateNavigation(string $navTemplate = '', string $currentPage = ''): string
{
$pages = AntPages::getPages();
$antCache = new AntCache;
$antTwig = new AntTwig();

$theme = AntConfig::currentConfig('activeTheme');
$cacheKey = $antCache->createCacheKey(json_encode($pages), $theme . $currentPage);

if ($antCache->isCached($cacheKey)) {
$cachedContent = $antCache->getCache($cacheKey);

if ($cachedContent !== false && !empty($cachedContent)) {
if (!empty($cachedContent)) {
return $cachedContent;
}
}
Expand All @@ -91,6 +88,7 @@ public static function generateNavigation(string $navTemplate = '', string $curr
}
}

$antTwig = new AntTwig();
$navHTML = $antTwig->renderWithTiwg($navTemplate, array('pages' => $pages));

$antCache->setCache($cacheKey, $navHTML);
Expand Down
2 changes: 1 addition & 1 deletion src/AntCMS/AntTwig.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public function __construct(string $theme = null)
$twigCache = (AntConfig::currentConfig('enableCache') !== 'none') ? AntCachePath : false;
$this->theme = $theme ?? AntConfig::currentConfig('activeTheme');

if (!is_dir(antThemePath . '/' . $this->theme)) {
if (!is_dir(antThemePath . DIRECTORY_SEPARATOR . $this->theme)) {
$this->theme = 'Default';
}

Expand Down
25 changes: 19 additions & 6 deletions src/AntCMS/AntYaml.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,25 @@

class AntYaml
{
/**
* @return array<mixed>
*/
public static function parseFile(string $file)
public static function parseFile(string $file, bool $fileCache = false): array
{
return Yaml::parseFile($file);
if ($fileCache) {
$antCache = new AntCache('filesystem');
} else {
$antCache = new AntCache();
}

$cacheKey = $antCache->createCacheKeyFile($file);
if ($antCache->isCached($cacheKey)) {
$parsed = json_decode($antCache->getCache($cacheKey), true);
}

if (empty($parsed)) {
$parsed = Yaml::parseFile($file);
$antCache->setCache($cacheKey, json_encode($parsed));
}

return $parsed;
}

/**
Expand All @@ -27,7 +40,7 @@ public static function saveFile(string $file, array $data): bool
/**
* @return array<mixed>|null
*/
public static function parseYaml(string $yaml)
public static function parseYaml(string $yaml): ?array
{
try {
return Yaml::parse($yaml);
Expand Down

0 comments on commit 8d9e894

Please sign in to comment.