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(
|
||||
document.head.querySelector<HTMLLinkElement>('link[rel~="icon"]')?.getAttribute('href'),
|
||||
).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 () => {
|
||||
@@ -114,6 +119,10 @@ describe('App', () => {
|
||||
expect(
|
||||
document.head.querySelector<HTMLLinkElement>('link[rel~="icon"]')?.getAttribute('href'),
|
||||
).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('fetchpriority', 'high');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
<header class="immersive-header" [class.immersive-header--compact]="!showHero()">
|
||||
<div
|
||||
class="immersive-header__backdrop"
|
||||
[style.background-image]="backgroundImageUrl() ? 'url(' + backgroundImageUrl() + ')' : null"
|
||||
></div>
|
||||
<div class="immersive-header__backdrop">
|
||||
@if (showHero() && backgroundImageUrl(); as backgroundImage) {
|
||||
<img
|
||||
class="immersive-header__backdrop-image"
|
||||
[src]="backgroundImage"
|
||||
alt=""
|
||||
loading="eager"
|
||||
fetchpriority="high"
|
||||
decoding="async"
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="immersive-header__content">
|
||||
<nav
|
||||
@@ -11,7 +19,13 @@
|
||||
>
|
||||
<a routerLink="/" class="immersive-header__brand" aria-label="Ir al inicio">
|
||||
@if (logoUrl()) {
|
||||
<img [src]="logoUrl()" alt="Logo del comercio" />
|
||||
<img
|
||||
[src]="logoUrl()"
|
||||
alt="Logo del comercio"
|
||||
loading="eager"
|
||||
fetchpriority="high"
|
||||
decoding="async"
|
||||
/>
|
||||
}
|
||||
</a>
|
||||
|
||||
|
||||
@@ -25,9 +25,19 @@
|
||||
grid-area: 1 / 1;
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
overflow: hidden;
|
||||
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,
|
||||
@@ -35,6 +45,8 @@
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.immersive-header__backdrop::before {
|
||||
|
||||
@@ -13,7 +13,14 @@
|
||||
aria-label="Logo del comercio"
|
||||
>
|
||||
@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 {
|
||||
<div class="store-layout__brand-logo-shell" aria-hidden="true">
|
||||
<span class="store-layout__brand-logo-skeleton"></span>
|
||||
|
||||
@@ -281,10 +281,27 @@ describe('StoreLayoutComponent', () => {
|
||||
expect(element.querySelector('.immersive-header__description')?.textContent).toContain(
|
||||
'Reservá tu entrada',
|
||||
);
|
||||
expect(element.querySelectorAll('.continuous-carousel__set')).toHaveLength(2);
|
||||
expect(element.querySelector('.continuous-carousel__image')?.getAttribute('src')).toBe(
|
||||
'/first.jpg',
|
||||
const backdropImage = element.querySelector<HTMLImageElement>(
|
||||
'.immersive-header__backdrop-image',
|
||||
);
|
||||
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();
|
||||
});
|
||||
|
||||
@@ -487,11 +504,13 @@ describe('StoreLayoutComponent', () => {
|
||||
|
||||
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(
|
||||
`app-store-header img.store-layout__brand-logo[src="${tenant.header_logo}"]`,
|
||||
),
|
||||
).not.toBeNull();
|
||||
const headerLogo = compiled.querySelector<HTMLImageElement>(
|
||||
`app-store-header img.store-layout__brand-logo[src="${tenant.header_logo}"]`,
|
||||
);
|
||||
expect(headerLogo).not.toBeNull();
|
||||
expect(headerLogo?.getAttribute('loading')).toBe('eager');
|
||||
expect(headerLogo?.getAttribute('fetchpriority')).toBe('high');
|
||||
expect(headerLogo?.getAttribute('decoding')).toBe('async');
|
||||
expect(
|
||||
compiled.querySelector(
|
||||
`app-store-footer img.store-layout__brand-logo[src="${tenant.footer_logo}"]`,
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
[src]="image"
|
||||
alt=""
|
||||
[loading]="set === 0 && $index < 5 ? 'eager' : 'lazy'"
|
||||
fetchpriority="low"
|
||||
decoding="async"
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user