Skip to content

Commit be8cd7f

Browse files
authored
feat(templates): website optimisations for image sizes and loading (#9447)
Adds defaultPopulate on pages and posts Further optimises images and fetching staticParams
1 parent b9d02aa commit be8cd7f

File tree

15 files changed

+84
-60
lines changed

15 files changed

+84
-60
lines changed

templates/website/src/Footer/Component.tsx

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type { Footer } from '@/payload-types'
66

77
import { ThemeSelector } from '@/providers/Theme/ThemeSelector'
88
import { CMSLink } from '@/components/Link'
9+
import { Logo } from '@/components/Logo/Logo'
910

1011
export async function Footer() {
1112
const footer: Footer = await getCachedGlobal('footer', 1)()
@@ -16,15 +17,7 @@ export async function Footer() {
1617
<footer className="border-t border-border bg-black dark:bg-card text-white">
1718
<div className="container py-8 gap-8 flex flex-col md:flex-row md:justify-between">
1819
<Link className="flex items-center" href="/">
19-
<picture>
20-
<img
21-
alt="Payload Logo"
22-
width={193}
23-
height={43}
24-
className="max-w-[6rem] invert-0 w-full"
25-
src="https://raw.githubusercontent.com/payloadcms/payload/main/packages/ui/src/assets/payload-logo-light.svg"
26-
/>
27-
</picture>
20+
<Logo />
2821
</Link>
2922

3023
<div className="flex flex-col-reverse items-start md:flex-row gap-4 md:items-center">

templates/website/src/Header/Component.client.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export const HeaderClient: React.FC<HeaderClientProps> = ({ header }) => {
3333
<header className="container relative z-20 " {...(theme ? { 'data-theme': theme } : {})}>
3434
<div className="py-8 border-b border-border flex justify-between">
3535
<Link href="/">
36-
<Logo />
36+
<Logo loading="eager" priority="high" />
3737
</Link>
3838
<HeaderNav header={header} />
3939
</div>

templates/website/src/app/(frontend)/[slug]/page.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ export async function generateStaticParams() {
2121
draft: false,
2222
limit: 1000,
2323
overrideAccess: false,
24+
select: {
25+
slug: true,
26+
},
2427
})
2528

2629
const params = pages.docs

templates/website/src/app/(frontend)/posts/[slug]/page.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ export async function generateStaticParams() {
2121
draft: false,
2222
limit: 1000,
2323
overrideAccess: false,
24+
select: {
25+
slug: true,
26+
},
2427
})
2528

2629
const params = posts.docs.map(({ slug }) => {

templates/website/src/collections/Pages/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ export const Pages: CollectionConfig = {
3030
read: authenticatedOrPublished,
3131
update: authenticated,
3232
},
33+
// This config controls what's populated by default when a page is referenced
34+
// https://payloadcms.com/docs/queries/select#defaultpopulate-collection-config-property
35+
defaultPopulate: {
36+
title: true,
37+
slug: true,
38+
},
3339
admin: {
3440
defaultColumns: ['title', 'slug', 'updatedAt'],
3541
livePreview: {

templates/website/src/collections/Posts/index.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,17 @@ export const Posts: CollectionConfig = {
3636
read: authenticatedOrPublished,
3737
update: authenticated,
3838
},
39+
// This config controls what's populated by default when a post is referenced
40+
// https://payloadcms.com/docs/queries/select#defaultpopulate-collection-config-property
41+
defaultPopulate: {
42+
title: true,
43+
slug: true,
44+
categories: true,
45+
meta: {
46+
image: true,
47+
description: true,
48+
},
49+
},
3950
admin: {
4051
defaultColumns: ['title', 'slug', 'updatedAt'],
4152
livePreview: {

templates/website/src/components/Card/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export const Card: React.FC<{
3737
>
3838
<div className="relative w-full ">
3939
{!metaImage && <div className="">No image</div>}
40-
{metaImage && typeof metaImage !== 'string' && <Media resource={metaImage} size="360px" />}
40+
{metaImage && typeof metaImage !== 'string' && <Media resource={metaImage} size="33vw" />}
4141
</div>
4242
<div className="p-4">
4343
{showCategories && hasCategories && (

templates/website/src/components/Logo/Logo.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,26 @@
11
import React from 'react'
22

3-
export const Logo = () => {
3+
interface Props {
4+
className?: string
5+
loading?: 'lazy' | 'eager'
6+
priority?: 'auto' | 'high' | 'low'
7+
}
8+
9+
export const Logo = (props: Props) => {
10+
const { loading: loadingFromProps, priority: priorityFromProps } = props
11+
12+
const loading = loadingFromProps || 'lazy'
13+
const priority = priorityFromProps || 'low'
14+
415
return (
516
/* eslint-disable @next/next/no-img-element */
617
<img
718
alt="Payload Logo"
819
width={193}
920
height={43}
21+
loading={loading}
22+
fetchPriority={priority}
23+
decoding="async"
1024
className="max-w-[9.375rem] invert dark:invert-0 w-full"
1125
src="https://raw.githubusercontent.com/payloadcms/payload/main/packages/ui/src/assets/payload-logo-light.svg"
1226
/>

templates/website/src/components/Media/ImageMedia/index.tsx

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,27 @@ import React from 'react'
88

99
import type { Props as MediaProps } from '../types'
1010

11-
import cssVariables from '@/cssVariables'
11+
import { cssVariables } from '@/cssVariables'
1212
import { getClientSideURL } from '@/utilities/getURL'
1313

1414
const { breakpoints } = cssVariables
1515

1616
// A base64 encoded image to use as a placeholder while the image is loading
1717
const placeholderBlur =
18-
'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'
18+
'data:image/png;base64,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'
1919

2020
export const ImageMedia: React.FC<MediaProps> = (props) => {
2121
const {
2222
alt: altFromProps,
2323
fill,
2424
imgClassName,
25-
onClick,
26-
onLoad: onLoadFromProps,
2725
priority,
2826
resource,
2927
size: sizeFromProps,
3028
src: srcFromProps,
29+
loading: loadingFromProps,
3130
} = props
3231

33-
const [isLoading, setIsLoading] = React.useState(true)
34-
3532
let width: number | undefined
3633
let height: number | undefined
3734
let alt = altFromProps
@@ -53,33 +50,31 @@ export const ImageMedia: React.FC<MediaProps> = (props) => {
5350
src = `${getClientSideURL()}${url}`
5451
}
5552

53+
const loading = loadingFromProps || 'lazy'
54+
5655
// NOTE: this is used by the browser to determine which image to download at different screen sizes
5756
const sizes = sizeFromProps
5857
? sizeFromProps
5958
: Object.entries(breakpoints)
60-
.map(([, value]) => `(max-width: ${value}px) ${value}px`)
59+
.map(([, value]) => `(max-width: ${value}px) ${value * 2}w`)
6160
.join(', ')
6261

6362
return (
64-
<NextImage
65-
alt={alt || ''}
66-
className={cn(imgClassName)}
67-
fill={fill}
68-
height={!fill ? height : undefined}
69-
onClick={onClick}
70-
onLoad={() => {
71-
setIsLoading(false)
72-
if (typeof onLoadFromProps === 'function') {
73-
onLoadFromProps()
74-
}
75-
}}
76-
placeholder="blur"
77-
blurDataURL={placeholderBlur}
78-
priority={priority}
79-
quality={90}
80-
sizes={sizes}
81-
src={src}
82-
width={!fill ? width : undefined}
83-
/>
63+
<picture>
64+
<NextImage
65+
alt={alt || ''}
66+
className={cn(imgClassName)}
67+
fill={fill}
68+
height={!fill ? height : undefined}
69+
placeholder="blur"
70+
blurDataURL={placeholderBlur}
71+
priority={priority}
72+
quality={100}
73+
loading={loading}
74+
sizes={sizes}
75+
src={src}
76+
width={!fill ? width : undefined}
77+
/>
78+
</picture>
8479
)
8580
}

templates/website/src/components/Media/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export interface Props {
1111
imgClassName?: string
1212
onClick?: () => void
1313
onLoad?: () => void
14+
loading?: 'lazy' | 'eager' // for NextImage only
1415
priority?: boolean // for NextImage only
1516
ref?: Ref<HTMLImageElement | HTMLVideoElement | null>
1617
resource?: MediaType | string | number // for Payload media

0 commit comments

Comments
 (0)