web: right-size card images and load the first ones eagerly
This commit is contained in:
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>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 && (
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in new issue
Block a user