Base64-encoded images in JSON-LD or direct-to-server uploads bloat HTML payloads by 30-40%, blow up your origin bandwidth bill, and destroy Core Web Vitals. LCP spikes past 4 seconds on mobile, browsers cannot cache per-image, and you lose responsive format negotiation (WebP, AVIF) that CDNs handle automatically. Google downranks slow pages, paid traffic converts worse, and every listing view costs you compute you should not be paying for.
Critical because origin bandwidth costs and LCP regression directly threaten directory economics and search rankings.
Move all listing images to a CDN-backed object store and persist only the resulting URL in your database. Use S3 + CloudFront, Cloudinary, or Vercel Image Optimization so browsers get cached, format-negotiated responses instead of inline base64. Migrate existing rows with a backfill job that uploads each embedded payload to the bucket and rewrites the field.
const { Location } = await s3.upload({
Bucket: 'directory-listing-images',
Key: `listings/${listing.id}/${filename}`,
Body: imageBuffer,
ContentType: mimeType,
CacheControl: 'public, max-age=31536000, immutable'
}).promise()
await db.listing.update({ where: { id: listing.id }, data: { imageUrl: Location } })
ID: directory-listing-schema.structured-data.images-cdn
Severity: critical
What to look for: List all image URLs referenced in listing data. For each URL, check the image storage mechanism. Look for references to AWS S3, Google Cloud Storage, Cloudinary, Vercel Image Optimization, or other CDN/object storage. Search the codebase for base64-encoded images in JSON-LD, img src attributes, or markdown content. Check the database schema or upload handler.
Pass criteria: All images are stored on a CDN or object storage service (S3, GCS, Cloudinary, etc.), not as base64 data URIs in JSON-LD or HTML, and not as direct uploads to the application server — 100% of listing images must be served from a CDN or optimized image service. Report: "X listing images found, all Y served from CDN."
Fail criteria: Images are embedded as base64 in JSON-LD or HTML, or uploaded directly to and served from the application server without CDN.
Skip (N/A) when: The listing type does not use images (text-only directory).
Detail on fail: Specify the issue. Example: "Images are base64-encoded in JSON-LD blocks, bloating the HTML payload" or "Images stored in app server /public/uploads — no CDN or object storage used"
Remediation: Migrate images to a CDN or object storage. Example with AWS S3:
const s3 = new AWS.S3()
const result = await s3.upload({
Bucket: 'my-directory-images',
Key: `listings/${listing.id}/${filename}`,
Body: imageBuffer,
ContentType: 'image/jpeg'
}).promise()
const imageUrl = result.Location
await db.listing.update({
where: { id: listing.id },
data: { imageUrl }
})