Files
ashen-realms/apps/web/src/app/features/hunting/encounter-card/encounter-card.component.ts
Bastian Wagner 833fa52d8d perf: serve optimized JPEG derivatives for monster artwork
encounter-card.component rendered the raw 2.39MB ash-rat.png and
2.00MB road-bandit.png directly, up to 3 cards per hunt (~7MB/load,
re-rendered on "Neu suchen"). Add 560px-wide JPEG runtime derivatives
(generated via PowerShell System.Drawing, HighQualityBicubic, quality
82) and switch to the <picture>/<source srcset> pattern already used
by context-panel for location backgrounds, keeping the original PNGs
as the <img> fallback. Also add loading="lazy" decoding="async".

ash-rat.png: 2,506,677 B -> ash-rat-560.jpg: 35,896 B
road-bandit.png: 2,097,049 B -> road-bandit-560.jpg: 50,797 B
2026-08-19 14:33:32 +02:00

28 lines
1001 B
TypeScript

import { Component, EventEmitter, Input, Output } from '@angular/core';
import { HuntEncounter } from '../../../core/api/game-api.models';
import { DangerBadgeComponent } from '../../../shared/danger-badge/danger-badge.component';
const runtimeArtworkPaths: Readonly<Record<string, string>> = {
'/images/monsters/ash-rat.png': '/images/monsters/runtime/ash-rat-560.jpg',
'/images/monsters/road-bandit.png': '/images/monsters/runtime/road-bandit-560.jpg',
};
@Component({
selector: 'app-encounter-card',
imports: [DangerBadgeComponent],
templateUrl: './encounter-card.component.html',
styleUrl: './encounter-card.component.scss',
})
export class EncounterCardComponent {
@Input({ required: true }) encounter!: HuntEncounter;
@Output() readonly attack = new EventEmitter<string>();
protected onAttack(): void {
this.attack.emit(this.encounter.id);
}
protected runtimeArtworkPath(artworkPath: string): string | undefined {
return runtimeArtworkPaths[artworkPath];
}
}