web: right-size card images and load the first ones eagerly

This commit is contained in:
ponas committed 2026-10-14 02:02:26 +02:00
1 parent 4c05c3c8c3
commit e3e4a613c5
6 files changed
+61 -9

No files matched your search

@@ -35,8 +35,10 @@ import "./swiper.scss";
const Slide = ({
item: maskedItem,
priority,
}: {
item: FragmentType<typeof ImageSliderItemFragmentDefinition>;
priority?: boolean;
}) => {
const item = unmaskFragment(ImageSliderItemFragmentDefinition, maskedItem);
const image = unmaskFragment(ImageFragmentDefinition, item.image);
@@ -50,6 +52,8 @@ const Slide = ({
attribution={image.attribution}
caption={item.text}
sizes="100vw"
loading={priority ? "eager" : undefined}
fetchPriority={priority ? "high" : undefined}
/>
);
};
@@ -83,7 +87,7 @@ export const ImageSliderBlock = ({
}
return (
<SwiperSlide key={index}>
<Slide item={item} />
<Slide item={item} priority={hero && index === 0} />
</SwiperSlide>
);
})}
+10 -1
View File
@@ -19,6 +19,15 @@ import {
const DATE_PILLS_TO_SHOW = 2;
// How wide the image is shown, so the browser can pick a file that fits.
// "large" follows the list grid (three, two, then one column); the other two
// are thumbnails, except "small" in the wide calendar grid
const IMAGE_SIZES = {
large: "(max-width: 700px) calc(100vw - 2rem), (max-width: 1200px) 50vw, 30vw",
medium: "192px",
small: "(max-width: 700px) 192px, 15vw",
};
export const EventItem = ({
event,
mode,
@@ -60,7 +69,7 @@ export const EventItem = ({
alt={featuredImage.alt}
width={0}
height={0}
sizes="(max-width: 900px) calc(100vw - 2rem), 30vw"
sizes={IMAGE_SIZES[size ?? "large"]}
loading={imageLoading}
fetchPriority={imageFetchPriority}
/>
+18 -2
View File
@@ -4,7 +4,17 @@ import { NewsFragment, NewsListItemFragment } from "@/lib/news";
import { formatDate } from "@/lib/date";
import Link from "next/link";
export const NewsItem = ({ news }: { news: NewsFragment | NewsListItemFragment }) => {
export const NewsItem = ({
news,
wide,
priority,
}: {
news: NewsFragment | NewsListItemFragment;
// one of the half-width cards at the top of the list on wide screens
wide?: boolean;
// above the fold: load the image right away
priority?: boolean;
}) => {
const featuredImage: any = news.featuredImage;
return (
@@ -16,7 +26,13 @@ export const NewsItem = ({ news }: { news: NewsFragment | NewsListItemFragment }
alt={featuredImage.alt}
width={featuredImage.width}
height={featuredImage.height}
sizes="(max-width: 600px) 25vw, 55vw"
sizes={
wide
? "(max-width: 600px) 25vw, 50vw"
: "(max-width: 600px) 25vw, (max-width: 900px) 50vw, 25vw"
}
loading={priority ? "eager" : undefined}
fetchPriority={priority ? "high" : undefined}
/>
)}
</div>
+9 -2
View File
@@ -55,8 +55,15 @@ export const NewsList = ({
<SectionHeader heading={heading} link="/aktuelt" linkText="Se flere artikler" />
)}
<ul className={`${styles.newsList} ${featured && styles.featured}`}>
{shown.map((singleNews) => (
<NewsItem key={singleNews.id} news={singleNews} />
{shown.map((singleNews, index) => (
<NewsItem
key={singleNews.id}
news={singleNews}
// the first two cards are half-width; on /aktuelt they are also
// the first thing on the page
wide={index < 2}
priority={!featured && index < 2}
/>
))}
</ul>
{!featured && knownTotal > items.length && (
+10 -1
View File
@@ -3,7 +3,14 @@ import styles from "./venueItem.module.scss";
import Link from "next/link";
import { Image } from "@/components/general/Image";
export const VenueItem = ({ venue }: { venue: VenueFragment }) => {
export const VenueItem = ({
venue,
priority,
}: {
venue: VenueFragment;
// above the fold: load the image right away
priority?: boolean;
}) => {
const featuredImage: any = venue.featuredImage;
const { capacitySitting, capacityStanding, usedFor } = venue;
@@ -27,6 +34,8 @@ export const VenueItem = ({ venue }: { venue: VenueFragment }) => {
width={0}
height={0}
sizes="(max-width: 600px) 100vw, (max-width: 900px) 50vw, 35vw"
loading={priority ? "eager" : undefined}
fetchPriority={priority ? "high" : undefined}
/>
)}
</div>
+9 -2
View File
@@ -6,9 +6,12 @@ import { SectionHeader } from "../general/SectionHeader";
export const VenueList = ({
venues,
heading,
priority,
}: {
venues: VenueFragment[];
heading?: string;
// the list is the first thing on the page: load its first row right away
priority?: boolean;
}) => {
return (
<div>
@@ -16,8 +19,12 @@ export const VenueList = ({
<SectionHeader heading={heading} />
)}
<ul className={styles.venueList}>
{venues.map((venue) => (
<VenueItem key={venue.id} venue={venue} />
{venues.map((venue, index) => (
<VenueItem
key={venue.id}
venue={venue}
priority={priority && index < 3}
/>
))}
</ul>
</div>