Skip to content

Commit

Permalink
Improvements to Cloudinary Example (#44572)
Browse files Browse the repository at this point in the history
## Improvements to Image Gallery

- Added blur image optimization that cuts initial page size by more than half
- Added masonry layout to handle images of different sizes
- Converted querySelector to use refs
  • Loading branch information
Nutlope authored Jan 4, 2023
1 parent b5e5355 commit ca73cbf
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 12 deletions.
2 changes: 2 additions & 0 deletions examples/with-cloudinary/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
"cloudinary": "^1.32.0",
"eslint-config-next": "^13.0.1",
"framer-motion": "^7.6.4",
"imagemin": "^8.0.1",
"imagemin-jpegtran": "^7.0.0",
"next": "latest",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
18 changes: 8 additions & 10 deletions examples/with-cloudinary/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Head from 'next/head'
import Image from 'next/image'
import Link from 'next/link'
import { useRouter } from 'next/router'
import { useEffect } from 'react'
import { useEffect, useRef } from 'react'
import Bridge from '../components/Icons/Bridge'
import Logo from '../components/Icons/Logo'
import Modal from '../components/Modal'
Expand All @@ -17,13 +17,12 @@ const Home: NextPage = ({ images }: { images: ImageProps[] }) => {
const { photoId } = router.query
const [lastViewedPhoto, setLastViewedPhoto] = useLastViewedPhoto()

const lastViewedPhotoRef = useRef<HTMLAnchorElement>(null)

useEffect(() => {
// This effect keeps track of the last viewed photo in the modal to keep the index page in sync when the user navigates back
if (lastViewedPhoto && !photoId) {
document
.querySelector(`#photo-${lastViewedPhoto}`)
.scrollIntoView({ block: 'center' })

lastViewedPhotoRef.current.scrollIntoView({ block: 'center' })
setLastViewedPhoto(null)
}
}, [photoId, lastViewedPhoto, setLastViewedPhoto])
Expand All @@ -50,9 +49,8 @@ const Home: NextPage = ({ images }: { images: ImageProps[] }) => {
}}
/>
)}

<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4">
<div className="after:content relative col-span-1 row-span-3 flex flex-col items-center justify-end gap-4 overflow-hidden rounded-lg bg-white/10 px-6 pb-16 pt-64 text-center text-white shadow-highlight after:pointer-events-none after:absolute after:inset-0 after:rounded-lg after:shadow-highlight sm:col-span-2 lg:col-span-1 lg:row-span-2 lg:pt-0">
<div className="columns-1 gap-4 sm:columns-2 xl:columns-3 2xl:columns-4">
<div className="after:content relative mb-5 flex h-[629px] flex-col items-center justify-end gap-4 overflow-hidden rounded-lg bg-white/10 px-6 pb-16 pt-64 text-center text-white shadow-highlight after:pointer-events-none after:absolute after:inset-0 after:rounded-lg after:shadow-highlight lg:pt-0">
<div className="absolute inset-0 flex items-center justify-center opacity-20">
<span className="flex max-h-full max-w-full items-center justify-center">
<Bridge />
Expand Down Expand Up @@ -81,9 +79,9 @@ const Home: NextPage = ({ images }: { images: ImageProps[] }) => {
key={id}
href={`/?photoId=${id}`}
as={`/p/${id}`}
id={`photo-${id}`}
ref={id === Number(lastViewedPhoto) ? lastViewedPhotoRef : null}
shallow
className="after:content group relative cursor-zoom-in after:pointer-events-none after:absolute after:inset-0 after:rounded-lg after:shadow-highlight"
className="after:content group relative mb-5 block w-full cursor-zoom-in after:pointer-events-none after:absolute after:inset-0 after:rounded-lg after:shadow-highlight"
>
<Image
alt="Next.js Conf photo"
Expand Down
9 changes: 7 additions & 2 deletions examples/with-cloudinary/utils/generateBlurPlaceholder.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import imagemin from 'imagemin'
import imageminJpegtran from 'imagemin-jpegtran'
import type { ImageProps } from './types'

const cache = new Map<ImageProps, string>()
Expand All @@ -13,8 +15,11 @@ export default async function getBase64ImageUrl(
`https://res.cloudinary.com/${process.env.NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME}/image/upload/f_jpg,w_8,q_70/${image.public_id}.${image.format}`
)
const buffer = await response.arrayBuffer()
const base64 = Buffer.from(buffer).toString('base64')
url = `data:image/jpeg;base64,${base64}`
const minified = await imagemin.buffer(Buffer.from(buffer), {
plugins: [imageminJpegtran()],
})

url = `data:image/jpeg;base64,${Buffer.from(minified).toString('base64')}`
cache.set(image, url)
return url
}

0 comments on commit ca73cbf

Please sign in to comment.