performance: Caching, deferred Tracking & externe Timeouts (H7, M12, M13)
- Navigations-Chrome (CategoryNavigation), Suche- und Newsroom-Seitendaten 300s gecacht; gemeinsamer WebPageCache-Helper (eine TTL/Key-Konvention). - Cache-Poisoning über ?page= geschlossen (Key an Paginator ausgerichtet, kein withQueryString im Cache); Newsrooms cachet nur den ungefilterten Fall und die ersten Seiten (kein unbegrenzter Key-Raum). - Detailseiten schreiben Hits/View-Events deferred nach der Response (M12); OpenAI-/Markt-/USt-ID-Aufrufe mit Connect-Timeouts und begrenzten Retries; Admin-Memo-Caches konsistent invalidiert. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
1afcc364ac
commit
22975e762e
18 changed files with 419 additions and 39 deletions
|
|
@ -24,12 +24,30 @@ class CategoryNavigation
|
|||
* Sortiert nach Anzahl veröffentlichter Pressemitteilungen; `null` als
|
||||
* Limit liefert alle Rubriken (z. B. für das „Mehr“-Dropdown im Header).
|
||||
*
|
||||
* Die Navigation rendert auf jeder Web-Seite (Header/Footer/Branchenindex/
|
||||
* Suche) und ist rein portal-/sprachabhängig → 300s gecacht (wie TickerData),
|
||||
* sonst ≥2 uncachede Count-Aggregate pro anonymem Seitenaufruf.
|
||||
*
|
||||
* @return Collection<int, array{label:string, slug:string, href:string}>
|
||||
*/
|
||||
public static function items(?int $limit = 9): Collection
|
||||
{
|
||||
$portal = Portal::tryFrom((string) config('app.theme')) ?? Portal::Businessportal24;
|
||||
$language = app()->getLocale();
|
||||
|
||||
$cacheKey = WebPageCache::key('category-nav', [$portal->value, $language, $limit ?? 'all']);
|
||||
|
||||
return WebPageCache::remember(
|
||||
$cacheKey,
|
||||
static fn (): Collection => self::query($portal, $language, $limit)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int, array{label:string, slug:string, href:string}>
|
||||
*/
|
||||
private static function query(Portal $portal, string $language, ?int $limit): Collection
|
||||
{
|
||||
$portalValues = [$portal->value, Portal::Both->value];
|
||||
|
||||
return Category::query()
|
||||
|
|
|
|||
46
app/Support/WebPageCache.php
Normal file
46
app/Support/WebPageCache.php
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace App\Support;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
/**
|
||||
* Gemeinsame Cache-Konvention der öffentlichen Web-Seitendaten (HomePageData,
|
||||
* CategoryPageData, NewsroomDetail/NewsroomsPageData, SuchePageData,
|
||||
* CategoryNavigation). Bündelt die einheitliche TTL und den `web.`-Präfix an
|
||||
* einer Stelle, statt vier verschiedene Konstanten/Magic-Numbers zu pflegen.
|
||||
*/
|
||||
class WebPageCache
|
||||
{
|
||||
/**
|
||||
* Einheitliche Cache-Dauer der Web-Seitendaten in Sekunden.
|
||||
*/
|
||||
public const TtlSeconds = 300;
|
||||
|
||||
/**
|
||||
* Baut einen `web.`-Cache-Key aus Segmenten (leere Segmente entfallen).
|
||||
*
|
||||
* @param array<int, string|int> $segments
|
||||
*/
|
||||
public static function key(string $group, array $segments = []): string
|
||||
{
|
||||
$parts = array_filter(
|
||||
array_map(static fn (string|int $segment): string => (string) $segment, $segments),
|
||||
static fn (string $segment): bool => $segment !== '',
|
||||
);
|
||||
|
||||
return implode('.', array_merge(['web', $group], $parts));
|
||||
}
|
||||
|
||||
/**
|
||||
* @template TValue
|
||||
*
|
||||
* @param Closure(): TValue $callback
|
||||
* @return TValue
|
||||
*/
|
||||
public static function remember(string $key, Closure $callback): mixed
|
||||
{
|
||||
return Cache::remember($key, self::TtlSeconds, $callback);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue