improve: performance

This commit is contained in:
2026-05-14 13:34:56 +02:00
parent b598779c60
commit 806c04e47a
5 changed files with 33 additions and 32 deletions
+1 -1
View File
@@ -57,7 +57,7 @@ function getProfile(relativePath) {
} }
if (normalizedRelativePath.startsWith('portrait/')) { if (normalizedRelativePath.startsWith('portrait/')) {
return { maxWidth: 640, quality: 82, alphaQuality: 90, variants: [128, 320, 480] }; return { maxWidth: 640, quality: 82, alphaQuality: 90, variants: [128, 320, 384, 480] };
} }
return { maxWidth: 1600, quality: 82, alphaQuality: 92 }; return { maxWidth: 1600, quality: 82, alphaQuality: 92 };
+1 -1
View File
@@ -434,7 +434,7 @@ describe('HomeComponent', (): void => {
spyOn(window, 'matchMedia').and.callFake( spyOn(window, 'matchMedia').and.callFake(
(query: string): MediaQueryList => (query: string): MediaQueryList =>
({ ({
matches: query === '(prefers-reduced-motion: reduce)' ? false : true, matches: query !== '(prefers-reduced-motion: reduce)',
}) as MediaQueryList, }) as MediaQueryList,
); );
+4 -3
View File
@@ -137,7 +137,9 @@ export class HomeComponent implements OnInit, AfterViewInit, OnDestroy {
} }
ngOnInit(): void { ngOnInit(): void {
this.zone.runOutsideAngular((): void => {
this.initNameGradientScrollAnimation(); this.initNameGradientScrollAnimation();
});
this.zone.runOutsideAngular((): void => { this.zone.runOutsideAngular((): void => {
interval(1000) interval(1000)
.pipe(takeUntilDestroyed(this.destroyRef)) .pipe(takeUntilDestroyed(this.destroyRef))
@@ -151,8 +153,10 @@ export class HomeComponent implements OnInit, AfterViewInit, OnDestroy {
} }
ngAfterViewInit(): void { ngAfterViewInit(): void {
this.zone.runOutsideAngular((): void => {
this.initProjectEntryRevealObserver(); this.initProjectEntryRevealObserver();
this.initAboutSectionScrollAnimation(); this.initAboutSectionScrollAnimation();
});
} }
ngOnDestroy(): void { ngOnDestroy(): void {
if (this.bioHideTimeoutId !== null) { if (this.bioHideTimeoutId !== null) {
@@ -231,13 +235,11 @@ export class HomeComponent implements OnInit, AfterViewInit, OnDestroy {
if (!this.shouldEnableScrollEffects()) return; if (!this.shouldEnableScrollEffects()) return;
window.addEventListener('scroll', this.scheduleNameGradientUpdate, { passive: true }); window.addEventListener('scroll', this.scheduleNameGradientUpdate, { passive: true });
window.addEventListener('resize', this.scheduleNameGradientUpdate, { passive: true }); window.addEventListener('resize', this.scheduleNameGradientUpdate, { passive: true });
this.scheduleNameGradientUpdate();
} }
private initProjectEntryRevealObserver(): void { private initProjectEntryRevealObserver(): void {
if (!this.shouldEnableScrollEffects()) return; if (!this.shouldEnableScrollEffects()) return;
window.addEventListener('scroll', this.scheduleProjectEntryRevealUpdate, { passive: true }); window.addEventListener('scroll', this.scheduleProjectEntryRevealUpdate, { passive: true });
window.addEventListener('resize', this.scheduleProjectEntryRevealUpdate, { passive: true }); window.addEventListener('resize', this.scheduleProjectEntryRevealUpdate, { passive: true });
this.scheduleProjectEntryRevealUpdate();
} }
private destroyProjectEntryRevealObserver(): void { private destroyProjectEntryRevealObserver(): void {
if (typeof window === 'undefined' || typeof document === 'undefined') return; if (typeof window === 'undefined' || typeof document === 'undefined') return;
@@ -259,7 +261,6 @@ export class HomeComponent implements OnInit, AfterViewInit, OnDestroy {
window.addEventListener('resize', this.scheduleAboutSectionScrollAnimationUpdate, { window.addEventListener('resize', this.scheduleAboutSectionScrollAnimationUpdate, {
passive: true, passive: true,
}); });
this.scheduleAboutSectionScrollAnimationUpdate();
} }
private destroyAboutSectionScrollAnimation(): void { private destroyAboutSectionScrollAnimation(): void {
if (typeof window === 'undefined' || typeof document === 'undefined') return; if (typeof window === 'undefined' || typeof document === 'undefined') return;
+12 -12
View File
@@ -119,9 +119,9 @@ export const deLanguage: LanguagePack = {
{ {
image: 'assets/optimized/portrait/me.webp', image: 'assets/optimized/portrait/me.webp',
imageSrcset: imageSrcset:
'assets/optimized/portrait/me-320.webp 320w, assets/optimized/portrait/me-480.webp 480w, assets/optimized/portrait/me.webp 640w', 'assets/optimized/portrait/me-320.webp 320w, assets/optimized/portrait/me-384.webp 384w, assets/optimized/portrait/me-480.webp 480w, assets/optimized/portrait/me.webp 640w',
imageSizes: imageSizes:
'(max-width: 700px) calc(100vw - 2rem), (max-width: 900px) min(100vw - 6rem, 560px), 560px', '(max-width: 700px) calc(100vw - 4rem), (max-width: 900px) min(calc(100vw - 9rem), 560px), 320px',
imageWidth: 640, imageWidth: 640,
imageHeight: 769, imageHeight: 769,
text: 'Ich', text: 'Ich',
@@ -129,9 +129,9 @@ export const deLanguage: LanguagePack = {
{ {
image: 'assets/optimized/portrait/love.webp', image: 'assets/optimized/portrait/love.webp',
imageSrcset: imageSrcset:
'assets/optimized/portrait/love-320.webp 320w, assets/optimized/portrait/love-480.webp 480w, assets/optimized/portrait/love.webp 640w', 'assets/optimized/portrait/love-320.webp 320w, assets/optimized/portrait/love-384.webp 384w, assets/optimized/portrait/love-480.webp 480w, assets/optimized/portrait/love.webp 640w',
imageSizes: imageSizes:
'(max-width: 700px) calc(100vw - 2rem), (max-width: 900px) min(100vw - 6rem, 560px), 560px', '(max-width: 700px) calc(100vw - 4rem), (max-width: 900px) min(calc(100vw - 9rem), 560px), 320px',
imageWidth: 640, imageWidth: 640,
imageHeight: 710, imageHeight: 710,
text: 'Meine Liebe', text: 'Meine Liebe',
@@ -139,9 +139,9 @@ export const deLanguage: LanguagePack = {
{ {
image: 'assets/optimized/portrait/scuba.webp', image: 'assets/optimized/portrait/scuba.webp',
imageSrcset: imageSrcset:
'assets/optimized/portrait/scuba-320.webp 320w, assets/optimized/portrait/scuba-480.webp 480w, assets/optimized/portrait/scuba.webp 640w', 'assets/optimized/portrait/scuba-320.webp 320w, assets/optimized/portrait/scuba-384.webp 384w, assets/optimized/portrait/scuba-480.webp 480w, assets/optimized/portrait/scuba.webp 640w',
imageSizes: imageSizes:
'(max-width: 700px) calc(100vw - 2rem), (max-width: 900px) min(100vw - 6rem, 560px), 560px', '(max-width: 700px) calc(100vw - 4rem), (max-width: 900px) min(calc(100vw - 9rem), 560px), 320px',
imageWidth: 640, imageWidth: 640,
imageHeight: 480, imageHeight: 480,
text: 'Tauchen', text: 'Tauchen',
@@ -149,9 +149,9 @@ export const deLanguage: LanguagePack = {
{ {
image: 'assets/optimized/portrait/trains.webp', image: 'assets/optimized/portrait/trains.webp',
imageSrcset: imageSrcset:
'assets/optimized/portrait/trains-320.webp 320w, assets/optimized/portrait/trains-480.webp 480w, assets/optimized/portrait/trains.webp 640w', 'assets/optimized/portrait/trains-320.webp 320w, assets/optimized/portrait/trains-384.webp 384w, assets/optimized/portrait/trains-480.webp 480w, assets/optimized/portrait/trains.webp 640w',
imageSizes: imageSizes:
'(max-width: 700px) calc(100vw - 2rem), (max-width: 900px) min(100vw - 6rem, 560px), 560px', '(max-width: 700px) calc(100vw - 4rem), (max-width: 900px) min(calc(100vw - 9rem), 560px), 320px',
imageWidth: 640, imageWidth: 640,
imageHeight: 850, imageHeight: 850,
text: 'Züge', text: 'Züge',
@@ -159,9 +159,9 @@ export const deLanguage: LanguagePack = {
{ {
image: 'assets/optimized/portrait/traveling.webp', image: 'assets/optimized/portrait/traveling.webp',
imageSrcset: imageSrcset:
'assets/optimized/portrait/traveling-320.webp 320w, assets/optimized/portrait/traveling-480.webp 480w, assets/optimized/portrait/traveling.webp 640w', 'assets/optimized/portrait/traveling-320.webp 320w, assets/optimized/portrait/traveling-384.webp 384w, assets/optimized/portrait/traveling-480.webp 480w, assets/optimized/portrait/traveling.webp 640w',
imageSizes: imageSizes:
'(max-width: 700px) calc(100vw - 2rem), (max-width: 900px) min(100vw - 6rem, 560px), 560px', '(max-width: 700px) calc(100vw - 4rem), (max-width: 900px) min(calc(100vw - 9rem), 560px), 320px',
imageWidth: 640, imageWidth: 640,
imageHeight: 480, imageHeight: 480,
text: 'Reisen', text: 'Reisen',
@@ -169,9 +169,9 @@ export const deLanguage: LanguagePack = {
{ {
image: 'assets/optimized/portrait/culture.webp', image: 'assets/optimized/portrait/culture.webp',
imageSrcset: imageSrcset:
'assets/optimized/portrait/culture-320.webp 320w, assets/optimized/portrait/culture-480.webp 480w, assets/optimized/portrait/culture.webp 640w', 'assets/optimized/portrait/culture-320.webp 320w, assets/optimized/portrait/culture-384.webp 384w, assets/optimized/portrait/culture-480.webp 480w, assets/optimized/portrait/culture.webp 640w',
imageSizes: imageSizes:
'(max-width: 700px) calc(100vw - 2rem), (max-width: 900px) min(100vw - 6rem, 560px), 560px', '(max-width: 700px) calc(100vw - 4rem), (max-width: 900px) min(calc(100vw - 9rem), 560px), 320px',
imageWidth: 640, imageWidth: 640,
imageHeight: 482, imageHeight: 482,
text: 'Kultur', text: 'Kultur',
+12 -12
View File
@@ -119,9 +119,9 @@ export const enLanguage: LanguagePack = {
{ {
image: 'assets/optimized/portrait/me.webp', image: 'assets/optimized/portrait/me.webp',
imageSrcset: imageSrcset:
'assets/optimized/portrait/me-320.webp 320w, assets/optimized/portrait/me-480.webp 480w, assets/optimized/portrait/me.webp 640w', 'assets/optimized/portrait/me-320.webp 320w, assets/optimized/portrait/me-384.webp 384w, assets/optimized/portrait/me-480.webp 480w, assets/optimized/portrait/me.webp 640w',
imageSizes: imageSizes:
'(max-width: 700px) calc(100vw - 2rem), (max-width: 900px) min(100vw - 6rem, 560px), 560px', '(max-width: 700px) calc(100vw - 4rem), (max-width: 900px) min(calc(100vw - 9rem), 560px), 320px',
imageWidth: 640, imageWidth: 640,
imageHeight: 769, imageHeight: 769,
text: 'ME', text: 'ME',
@@ -129,9 +129,9 @@ export const enLanguage: LanguagePack = {
{ {
image: 'assets/optimized/portrait/love.webp', image: 'assets/optimized/portrait/love.webp',
imageSrcset: imageSrcset:
'assets/optimized/portrait/love-320.webp 320w, assets/optimized/portrait/love-480.webp 480w, assets/optimized/portrait/love.webp 640w', 'assets/optimized/portrait/love-320.webp 320w, assets/optimized/portrait/love-384.webp 384w, assets/optimized/portrait/love-480.webp 480w, assets/optimized/portrait/love.webp 640w',
imageSizes: imageSizes:
'(max-width: 700px) calc(100vw - 2rem), (max-width: 900px) min(100vw - 6rem, 560px), 560px', '(max-width: 700px) calc(100vw - 4rem), (max-width: 900px) min(calc(100vw - 9rem), 560px), 320px',
imageWidth: 640, imageWidth: 640,
imageHeight: 710, imageHeight: 710,
text: 'My Love', text: 'My Love',
@@ -139,9 +139,9 @@ export const enLanguage: LanguagePack = {
{ {
image: 'assets/optimized/portrait/scuba.webp', image: 'assets/optimized/portrait/scuba.webp',
imageSrcset: imageSrcset:
'assets/optimized/portrait/scuba-320.webp 320w, assets/optimized/portrait/scuba-480.webp 480w, assets/optimized/portrait/scuba.webp 640w', 'assets/optimized/portrait/scuba-320.webp 320w, assets/optimized/portrait/scuba-384.webp 384w, assets/optimized/portrait/scuba-480.webp 480w, assets/optimized/portrait/scuba.webp 640w',
imageSizes: imageSizes:
'(max-width: 700px) calc(100vw - 2rem), (max-width: 900px) min(100vw - 6rem, 560px), 560px', '(max-width: 700px) calc(100vw - 4rem), (max-width: 900px) min(calc(100vw - 9rem), 560px), 320px',
imageWidth: 640, imageWidth: 640,
imageHeight: 480, imageHeight: 480,
text: 'Scuba Diving', text: 'Scuba Diving',
@@ -149,9 +149,9 @@ export const enLanguage: LanguagePack = {
{ {
image: 'assets/optimized/portrait/trains.webp', image: 'assets/optimized/portrait/trains.webp',
imageSrcset: imageSrcset:
'assets/optimized/portrait/trains-320.webp 320w, assets/optimized/portrait/trains-480.webp 480w, assets/optimized/portrait/trains.webp 640w', 'assets/optimized/portrait/trains-320.webp 320w, assets/optimized/portrait/trains-384.webp 384w, assets/optimized/portrait/trains-480.webp 480w, assets/optimized/portrait/trains.webp 640w',
imageSizes: imageSizes:
'(max-width: 700px) calc(100vw - 2rem), (max-width: 900px) min(100vw - 6rem, 560px), 560px', '(max-width: 700px) calc(100vw - 4rem), (max-width: 900px) min(calc(100vw - 9rem), 560px), 320px',
imageWidth: 640, imageWidth: 640,
imageHeight: 850, imageHeight: 850,
text: 'Trains', text: 'Trains',
@@ -159,9 +159,9 @@ export const enLanguage: LanguagePack = {
{ {
image: 'assets/optimized/portrait/traveling.webp', image: 'assets/optimized/portrait/traveling.webp',
imageSrcset: imageSrcset:
'assets/optimized/portrait/traveling-320.webp 320w, assets/optimized/portrait/traveling-480.webp 480w, assets/optimized/portrait/traveling.webp 640w', 'assets/optimized/portrait/traveling-320.webp 320w, assets/optimized/portrait/traveling-384.webp 384w, assets/optimized/portrait/traveling-480.webp 480w, assets/optimized/portrait/traveling.webp 640w',
imageSizes: imageSizes:
'(max-width: 700px) calc(100vw - 2rem), (max-width: 900px) min(100vw - 6rem, 560px), 560px', '(max-width: 700px) calc(100vw - 4rem), (max-width: 900px) min(calc(100vw - 9rem), 560px), 320px',
imageWidth: 640, imageWidth: 640,
imageHeight: 480, imageHeight: 480,
text: 'Traveling', text: 'Traveling',
@@ -169,9 +169,9 @@ export const enLanguage: LanguagePack = {
{ {
image: 'assets/optimized/portrait/culture.webp', image: 'assets/optimized/portrait/culture.webp',
imageSrcset: imageSrcset:
'assets/optimized/portrait/culture-320.webp 320w, assets/optimized/portrait/culture-480.webp 480w, assets/optimized/portrait/culture.webp 640w', 'assets/optimized/portrait/culture-320.webp 320w, assets/optimized/portrait/culture-384.webp 384w, assets/optimized/portrait/culture-480.webp 480w, assets/optimized/portrait/culture.webp 640w',
imageSizes: imageSizes:
'(max-width: 700px) calc(100vw - 2rem), (max-width: 900px) min(100vw - 6rem, 560px), 560px', '(max-width: 700px) calc(100vw - 4rem), (max-width: 900px) min(calc(100vw - 9rem), 560px), 320px',
imageWidth: 640, imageWidth: 640,
imageHeight: 482, imageHeight: 482,
text: 'Culture', text: 'Culture',