feat(store-header): add fetchpriority and loading attributes to images for performance optimization
This commit is contained in:
@@ -90,6 +90,11 @@ describe('App', () => {
|
|||||||
expect(
|
expect(
|
||||||
document.head.querySelector<HTMLLinkElement>('link[rel~="icon"]')?.getAttribute('href'),
|
document.head.querySelector<HTMLLinkElement>('link[rel~="icon"]')?.getAttribute('href'),
|
||||||
).toBe(tenant.favicon);
|
).toBe(tenant.favicon);
|
||||||
|
expect(
|
||||||
|
document.head
|
||||||
|
.querySelector<HTMLLinkElement>('link[rel~="icon"]')
|
||||||
|
?.getAttribute('fetchpriority'),
|
||||||
|
).toBe('high');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders the tenant not found screen when the tenant is missing', async () => {
|
it('renders the tenant not found screen when the tenant is missing', async () => {
|
||||||
@@ -114,6 +119,10 @@ describe('App', () => {
|
|||||||
expect(
|
expect(
|
||||||
document.head.querySelector<HTMLLinkElement>('link[rel~="icon"]')?.getAttribute('href'),
|
document.head.querySelector<HTMLLinkElement>('link[rel~="icon"]')?.getAttribute('href'),
|
||||||
).toBe("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'/%3E");
|
).toBe("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'/%3E");
|
||||||
|
expect(
|
||||||
|
document.head
|
||||||
|
.querySelector<HTMLLinkElement>('link[rel~="icon"]')
|
||||||
|
?.getAttribute('fetchpriority'),
|
||||||
|
).toBe('high');
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ export class App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
favicon.setAttribute('href', faviconHref);
|
favicon.setAttribute('href', faviconHref);
|
||||||
|
favicon.setAttribute('fetchpriority', 'high');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,16 @@
|
|||||||
<header class="immersive-header" [class.immersive-header--compact]="!showHero()">
|
<header class="immersive-header" [class.immersive-header--compact]="!showHero()">
|
||||||
<div
|
<div class="immersive-header__backdrop">
|
||||||
class="immersive-header__backdrop"
|
@if (showHero() && backgroundImageUrl(); as backgroundImage) {
|
||||||
[style.background-image]="backgroundImageUrl() ? 'url(' + backgroundImageUrl() + ')' : null"
|
<img
|
||||||
></div>
|
class="immersive-header__backdrop-image"
|
||||||
|
[src]="backgroundImage"
|
||||||
|
alt=""
|
||||||
|
loading="eager"
|
||||||
|
fetchpriority="high"
|
||||||
|
decoding="async"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="immersive-header__content">
|
<div class="immersive-header__content">
|
||||||
<nav
|
<nav
|
||||||
@@ -11,7 +19,13 @@
|
|||||||
>
|
>
|
||||||
<a routerLink="/" class="immersive-header__brand" aria-label="Ir al inicio">
|
<a routerLink="/" class="immersive-header__brand" aria-label="Ir al inicio">
|
||||||
@if (logoUrl()) {
|
@if (logoUrl()) {
|
||||||
<img [src]="logoUrl()" alt="Logo del comercio" />
|
<img
|
||||||
|
[src]="logoUrl()"
|
||||||
|
alt="Logo del comercio"
|
||||||
|
loading="eager"
|
||||||
|
fetchpriority="high"
|
||||||
|
decoding="async"
|
||||||
|
/>
|
||||||
}
|
}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|||||||
@@ -25,9 +25,19 @@
|
|||||||
grid-area: 1 / 1;
|
grid-area: 1 / 1;
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
|
overflow: hidden;
|
||||||
background-color: #101010;
|
background-color: #101010;
|
||||||
background-position: center 42%;
|
}
|
||||||
background-size: cover;
|
|
||||||
|
.immersive-header__backdrop-image {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 0;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
object-position: center 42%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.immersive-header__backdrop::before,
|
.immersive-header__backdrop::before,
|
||||||
@@ -35,6 +45,8 @@
|
|||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
|
z-index: 1;
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.immersive-header__backdrop::before {
|
.immersive-header__backdrop::before {
|
||||||
|
|||||||
@@ -13,7 +13,14 @@
|
|||||||
aria-label="Logo del comercio"
|
aria-label="Logo del comercio"
|
||||||
>
|
>
|
||||||
@if (logoUrl()) {
|
@if (logoUrl()) {
|
||||||
<img class="store-layout__brand-logo" [src]="logoUrl()" alt="Logo del comercio" />
|
<img
|
||||||
|
class="store-layout__brand-logo"
|
||||||
|
[src]="logoUrl()"
|
||||||
|
alt="Logo del comercio"
|
||||||
|
loading="eager"
|
||||||
|
fetchpriority="high"
|
||||||
|
decoding="async"
|
||||||
|
/>
|
||||||
} @else {
|
} @else {
|
||||||
<div class="store-layout__brand-logo-shell" aria-hidden="true">
|
<div class="store-layout__brand-logo-shell" aria-hidden="true">
|
||||||
<span class="store-layout__brand-logo-skeleton"></span>
|
<span class="store-layout__brand-logo-skeleton"></span>
|
||||||
|
|||||||
@@ -281,10 +281,27 @@ describe('StoreLayoutComponent', () => {
|
|||||||
expect(element.querySelector('.immersive-header__description')?.textContent).toContain(
|
expect(element.querySelector('.immersive-header__description')?.textContent).toContain(
|
||||||
'Reservá tu entrada',
|
'Reservá tu entrada',
|
||||||
);
|
);
|
||||||
expect(element.querySelectorAll('.continuous-carousel__set')).toHaveLength(2);
|
const backdropImage = element.querySelector<HTMLImageElement>(
|
||||||
expect(element.querySelector('.continuous-carousel__image')?.getAttribute('src')).toBe(
|
'.immersive-header__backdrop-image',
|
||||||
'/first.jpg',
|
|
||||||
);
|
);
|
||||||
|
expect(backdropImage?.getAttribute('src')).toBe(tenant.header_bg_image);
|
||||||
|
expect(backdropImage?.getAttribute('loading')).toBe('eager');
|
||||||
|
expect(backdropImage?.getAttribute('fetchpriority')).toBe('high');
|
||||||
|
expect(backdropImage?.getAttribute('decoding')).toBe('async');
|
||||||
|
const headerLogo = element.querySelector<HTMLImageElement>('.immersive-header__brand img');
|
||||||
|
expect(headerLogo?.getAttribute('loading')).toBe('eager');
|
||||||
|
expect(headerLogo?.getAttribute('fetchpriority')).toBe('high');
|
||||||
|
expect(headerLogo?.getAttribute('decoding')).toBe('async');
|
||||||
|
expect(element.querySelectorAll('.continuous-carousel__set')).toHaveLength(2);
|
||||||
|
const carouselImages = element.querySelectorAll<HTMLImageElement>(
|
||||||
|
'.continuous-carousel__image',
|
||||||
|
);
|
||||||
|
expect(carouselImages[0]?.getAttribute('src')).toBe('/first.jpg');
|
||||||
|
expect(carouselImages[0]?.getAttribute('loading')).toBe('eager');
|
||||||
|
expect(carouselImages[0]?.getAttribute('fetchpriority')).toBe('low');
|
||||||
|
expect(carouselImages[1]?.getAttribute('fetchpriority')).toBe('low');
|
||||||
|
expect(carouselImages[5]?.getAttribute('loading')).toBe('lazy');
|
||||||
|
expect(carouselImages[5]?.getAttribute('fetchpriority')).toBe('low');
|
||||||
expect(element.querySelector('app-cart-icon')).not.toBeNull();
|
expect(element.querySelector('app-cart-icon')).not.toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -487,11 +504,13 @@ describe('StoreLayoutComponent', () => {
|
|||||||
|
|
||||||
expect(compiled.querySelector('[data-testid="store-header-brand-slot"]')).not.toBeNull();
|
expect(compiled.querySelector('[data-testid="store-header-brand-slot"]')).not.toBeNull();
|
||||||
expect(compiled.querySelector('[data-testid="store-footer-brand-slot"]')).not.toBeNull();
|
expect(compiled.querySelector('[data-testid="store-footer-brand-slot"]')).not.toBeNull();
|
||||||
expect(
|
const headerLogo = compiled.querySelector<HTMLImageElement>(
|
||||||
compiled.querySelector(
|
`app-store-header img.store-layout__brand-logo[src="${tenant.header_logo}"]`,
|
||||||
`app-store-header img.store-layout__brand-logo[src="${tenant.header_logo}"]`,
|
);
|
||||||
),
|
expect(headerLogo).not.toBeNull();
|
||||||
).not.toBeNull();
|
expect(headerLogo?.getAttribute('loading')).toBe('eager');
|
||||||
|
expect(headerLogo?.getAttribute('fetchpriority')).toBe('high');
|
||||||
|
expect(headerLogo?.getAttribute('decoding')).toBe('async');
|
||||||
expect(
|
expect(
|
||||||
compiled.querySelector(
|
compiled.querySelector(
|
||||||
`app-store-footer img.store-layout__brand-logo[src="${tenant.footer_logo}"]`,
|
`app-store-footer img.store-layout__brand-logo[src="${tenant.footer_logo}"]`,
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
[src]="image"
|
[src]="image"
|
||||||
alt=""
|
alt=""
|
||||||
[loading]="set === 0 && $index < 5 ? 'eager' : 'lazy'"
|
[loading]="set === 0 && $index < 5 ? 'eager' : 'lazy'"
|
||||||
|
fetchpriority="low"
|
||||||
|
decoding="async"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user