From dd79ffcf989df629e0d9dafc836e962b2dfb2e32 Mon Sep 17 00:00:00 2001 From: Rico van Zelst Date: Thu, 1 Jan 2026 00:41:38 +0100 Subject: [PATCH] perf: optimize database queries and caching --- app/Helpers/HelperFunctions.php | 12 ++- app/Http/Controllers/ChampionController.php | 2 +- app/Http/Controllers/HomeController.php | 4 +- .../Controllers/SummonerEmoteController.php | 15 ++-- .../Controllers/SummonerIconController.php | 15 ++-- app/Models/ChampionSkin.php | 6 +- ...4_12_31_223500_add_performance_indexes.php | 74 +++++++++++++++++ resources/css/app.css | 40 ---------- .../components/home/recent_skins.blade.php | 80 +++++++++---------- 9 files changed, 147 insertions(+), 101 deletions(-) create mode 100644 database/migrations/2024_12_31_223500_add_performance_indexes.php diff --git a/app/Helpers/HelperFunctions.php b/app/Helpers/HelperFunctions.php index b898474..39cfde9 100644 --- a/app/Helpers/HelperFunctions.php +++ b/app/Helpers/HelperFunctions.php @@ -15,7 +15,7 @@ function getRoleIcon($roleName): string 'Support' => 'gm-support.png', ]; - return asset('img/'.$roleIcons[$roleName]); + return asset('img/' . $roleIcons[$roleName]); } function getAverageColorFromImageUrl($imageUrl): string @@ -75,9 +75,13 @@ function getRoleIconSvg($roleName): string */ function getChampionImage($full_id, $type): string { - $championImage = ChampionImage::where('full_id', $full_id)->where('type', $type)->first(); + $cacheKey = "champion_image_{$full_id}_{$type}"; - if (! $championImage) { + $championImage = Cache::remember($cacheKey, 60 * 60 * 24, static function () use ($full_id, $type) { + return ChampionImage::where('full_id', $full_id)->where('type', $type)->first(); + }); + + if (!$championImage) { return ''; } @@ -92,7 +96,7 @@ function getCommitHash(): string /** * @var string $commit */ - $commit = Cache::remember('commit_hash', 60 * 72, fn () => trim(exec('git log --pretty="%h" -n1 HEAD'))); + $commit = Cache::remember('commit_hash', 60 * 72, fn() => trim(exec('git log --pretty="%h" -n1 HEAD'))); return $commit; } diff --git a/app/Http/Controllers/ChampionController.php b/app/Http/Controllers/ChampionController.php index a305489..35ea00d 100644 --- a/app/Http/Controllers/ChampionController.php +++ b/app/Http/Controllers/ChampionController.php @@ -31,7 +31,7 @@ class ChampionController extends Controller $champion = Cache::remember('championShowCache' . $champion->slug, $threeDaysInSeconds, static fn() => $champion->load('streamers', 'skins', 'lanes')); - $streamers = $champion->load('streamers')->streamers; + $streamers = $champion->streamers; return view('champions.show', ['champion' => $champion, 'streamers' => $streamers]); } diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index 705bacb..a2a42e8 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -14,13 +14,13 @@ class HomeController extends Controller $query->where('release_date', '0000-00-00') ->orWhere('release_date', '>', now()); }) - ->orderBy('release_date', 'desc')->get()); + ->orderBy('release_date', 'desc')->limit(6)->get()); $latestSkins = Cache::remember('latestSkins_home', 60 * 4, static fn() => ChampionSkin::where('release_date', '!=', '0000-00-00') ->where('availability', '!=', 'Upcoming') ->where('release_date', '<=', now()) - ->orderBy('release_date', 'desc')->get()); + ->orderBy('release_date', 'desc')->limit(6)->get()); return view('home', [ 'latestSkins' => $latestSkins, diff --git a/app/Http/Controllers/SummonerEmoteController.php b/app/Http/Controllers/SummonerEmoteController.php index b974452..51c467c 100644 --- a/app/Http/Controllers/SummonerEmoteController.php +++ b/app/Http/Controllers/SummonerEmoteController.php @@ -4,17 +4,22 @@ namespace App\Http\Controllers; use App\Models\SummonerEmote; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Cache; use Spatie\QueryBuilder\QueryBuilder; class SummonerEmoteController extends Controller { public function index() { - $emotes = QueryBuilder::for(SummonerEmote::class) - ->allowedFilters('title') - ->defaultSort('-emote_id') - ->paginate(72) - ->appends(request()->query()); + $cacheKey = 'emotes_' . md5(serialize(request()->query())); + + $emotes = Cache::remember($cacheKey, 60 * 60, function () { + return QueryBuilder::for(SummonerEmote::class) + ->allowedFilters('title') + ->defaultSort('-emote_id') + ->paginate(72) + ->appends(request()->query()); + }); return view('emotes.index', ['emotes' => $emotes]); } diff --git a/app/Http/Controllers/SummonerIconController.php b/app/Http/Controllers/SummonerIconController.php index d282f4b..3b64875 100644 --- a/app/Http/Controllers/SummonerIconController.php +++ b/app/Http/Controllers/SummonerIconController.php @@ -4,17 +4,22 @@ namespace App\Http\Controllers; use App\Models\SummonerIcon; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Cache; use Spatie\QueryBuilder\QueryBuilder; class SummonerIconController extends Controller { public function index() { - $icons = QueryBuilder::for(SummonerIcon::class) - ->allowedFilters(['title', 'esports_team', 'release_year']) - ->defaultSort('-icon_id') - ->paginate(72) - ->appends(request()->query()); + $cacheKey = 'icons_' . md5(serialize(request()->query())); + + $icons = Cache::remember($cacheKey, 60 * 60, function () { + return QueryBuilder::for(SummonerIcon::class) + ->allowedFilters(['title', 'esports_team', 'release_year']) + ->defaultSort('-icon_id') + ->paginate(72) + ->appends(request()->query()); + }); return view('icons.index', ['icons' => $icons]); } diff --git a/app/Models/ChampionSkin.php b/app/Models/ChampionSkin.php index 522226c..474c541 100644 --- a/app/Models/ChampionSkin.php +++ b/app/Models/ChampionSkin.php @@ -22,7 +22,7 @@ class ChampionSkin extends Model 'availability', 'loot_eligible', 'rp_price', - 'raritiy', + 'rarity', 'release_date', 'associated_skinline', 'new_effects', @@ -70,12 +70,12 @@ class ChampionSkin extends Model public function getSkinImageLoadingAttribute(): string { - return 'https://cdn.communitydragon.org/latest/champion/'.$this->champion_id.'/portrait/skin/'.$this->skin_id; + return 'https://cdn.communitydragon.org/latest/champion/' . $this->champion_id . '/portrait/skin/' . $this->skin_id; } public function getSkinImageTileAttribute(): string { - return 'https://cdn.communitydragon.org/latest/champion/'.$this->champion_id.'/tile/skin/'.$this->skin_id; + return 'https://cdn.communitydragon.org/latest/champion/' . $this->champion_id . '/tile/skin/' . $this->skin_id; } protected function casts(): array diff --git a/database/migrations/2024_12_31_223500_add_performance_indexes.php b/database/migrations/2024_12_31_223500_add_performance_indexes.php new file mode 100644 index 0000000..672e89b --- /dev/null +++ b/database/migrations/2024_12_31_223500_add_performance_indexes.php @@ -0,0 +1,74 @@ + 0; + } + + public function up(): void + { + Schema::table('champion_skins', function (Blueprint $table) { + if (!$this->indexExists('champion_skins', 'champion_skins_availability_index')) { + $table->index('availability'); + } + if (!$this->indexExists('champion_skins', 'champion_skins_release_date_index')) { + $table->index('release_date'); + } + if (!$this->indexExists('champion_skins', 'champion_skins_slug_index')) { + $table->index('slug'); + } + if (!$this->indexExists('champion_skins', 'champion_skins_rarity_index')) { + $table->index('rarity'); + } + }); + + Schema::table('summoner_icons', function (Blueprint $table) { + if (!$this->indexExists('summoner_icons', 'summoner_icons_title_index')) { + $table->index('title'); + } + if (!$this->indexExists('summoner_icons', 'summoner_icons_esports_team_index')) { + $table->index('esports_team'); + } + if (!$this->indexExists('summoner_icons', 'summoner_icons_release_year_index')) { + $table->index('release_year'); + } + }); + } + + public function down(): void + { + Schema::table('champion_skins', function (Blueprint $table) { + if ($this->indexExists('champion_skins', 'champion_skins_availability_index')) { + $table->dropIndex(['availability']); + } + if ($this->indexExists('champion_skins', 'champion_skins_release_date_index')) { + $table->dropIndex(['release_date']); + } + if ($this->indexExists('champion_skins', 'champion_skins_slug_index')) { + $table->dropIndex(['slug']); + } + if ($this->indexExists('champion_skins', 'champion_skins_rarity_index')) { + $table->dropIndex(['rarity']); + } + }); + + Schema::table('summoner_icons', function (Blueprint $table) { + if ($this->indexExists('summoner_icons', 'summoner_icons_title_index')) { + $table->dropIndex(['title']); + } + if ($this->indexExists('summoner_icons', 'summoner_icons_esports_team_index')) { + $table->dropIndex(['esports_team']); + } + if ($this->indexExists('summoner_icons', 'summoner_icons_release_year_index')) { + $table->dropIndex(['release_year']); + } + }); + } +}; diff --git a/resources/css/app.css b/resources/css/app.css index 3c76383..53a3c2e 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -6,30 +6,6 @@ navigation: auto; /* enabled! */ } -@font-face { - font-display: swap; - font-family: "Inter"; - font-style: normal; - font-weight: 100; - src: url("/fonts/inter-v13-latin-100.woff2") format("woff2"); -} - -@font-face { - font-display: swap; - font-family: "Inter"; - font-style: normal; - font-weight: 200; - src: url("/fonts/inter-v13-latin-200.woff2") format("woff2"); -} - -@font-face { - font-display: swap; - font-family: "Inter"; - font-style: normal; - font-weight: 300; - src: url("/fonts/inter-v13-latin-300.woff2") format("woff2"); -} - @font-face { font-display: swap; font-family: "Inter"; @@ -62,22 +38,6 @@ src: url("/fonts/inter-v13-latin-700.woff2") format("woff2"); } -@font-face { - font-display: swap; - font-family: "Inter"; - font-style: normal; - font-weight: 800; - src: url("/fonts/inter-v13-latin-800.woff2") format("woff2"); -} - -@font-face { - font-display: swap; - font-family: "Inter"; - font-style: normal; - font-weight: 900; - src: url("/fonts/inter-v13-latin-900.woff2") format("woff2"); -} - .glow-shadow::before { content: ""; position: absolute; diff --git a/resources/views/components/home/recent_skins.blade.php b/resources/views/components/home/recent_skins.blade.php index 9a10162..694da0a 100644 --- a/resources/views/components/home/recent_skins.blade.php +++ b/resources/views/components/home/recent_skins.blade.php @@ -17,57 +17,55 @@
@foreach ($latestSkins as $skin) - @if ($loop->index < 6) -
-
-
- - {{ $skin->skin_name }} Splash Art - +
+
-

{{ $skin->skin_name }} -

-

Released - {{ Carbon::parse($skin->release_date)->diffForHumans([ - 'parts' => 2, - 'join' => true, - ]) }} -

+ + {{ $skin->skin_name }} Splash Art + +
+

{{ $skin->skin_name }} +

+

Released + {{ Carbon::parse($skin->release_date)->diffForHumans([ + 'parts' => 2, + 'join' => true, + ]) }} +

- @foreach ($skin->associated_skinline as $skinline) - - {{ $skinline }} - @endforeach + @foreach ($skin->associated_skinline as $skinline) + + {{ $skinline }} + @endforeach -

- @if ($skin->rp_price == '99999') - Not Available for RP - @else - - {{ $skin->rp_price }} RP - @endif -

- - @if ($skin->loot_eligible) -

- - Can be obtained from loot +

+ @if ($skin->rp_price == '99999') + Not Available for RP + @else + + {{ $skin->rp_price }} RP + @endif

- @endif + @if ($skin->loot_eligible) +

+ + Can be obtained from loot +

+ @endif + +
-
- @endif @endforeach
- + \ No newline at end of file