build: 🔧 use externally hosted image service

Build time increases exponentially with more images pulled in by the eleventy-image plugin. This keeps build times low and shifts computational load to an external image hosting service.
This commit is contained in:
Sebin Nyshkim 2025-04-20 16:22:53 +02:00
parent 45246edf20
commit e37b5a9823
19 changed files with 33 additions and 29 deletions

View file

@ -22,9 +22,24 @@ import markdownItDeflist from 'markdown-it-deflist';
import markdownItFootnote from 'markdown-it-footnote'; import markdownItFootnote from 'markdown-it-footnote';
import markdownItImageFigures from 'markdown-it-image-figures'; import markdownItImageFigures from 'markdown-it-image-figures';
const MARKDOWNIT_OPTIONS = { html: true, linkify: true, typographer: true };
Image.concurrency = 4; Image.concurrency = 4;
const urlFormat = ({ src, width, format }) => {
const baseUrl = `https://img.sebin-nyshkim.net/i`;
const imgUuid = src.match(/\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.(\w{3,})/);
const imgFormat = format === 'jpeg' ? 'jpg' : format;
return `${baseUrl}/${imgUuid[1]}.${imgFormat}?width=${width}`;
};
const MARKDOWNIT_OPTIONS = { html: true, linkify: true, typographer: true };
const ELEVENTY_IMAGE_DEFAULTS = {
formats: ['webp', 'auto'],
urlPath: '/img/',
outputDir: './public/img/',
urlFormat
};
export default async function (eleventyConfig) { export default async function (eleventyConfig) {
eleventyConfig.addPassthroughCopy('./src/css/prism.css'); eleventyConfig.addPassthroughCopy('./src/css/prism.css');
eleventyConfig.addWatchTarget('./src/css/'); eleventyConfig.addWatchTarget('./src/css/');
@ -32,9 +47,6 @@ export default async function (eleventyConfig) {
eleventyConfig.addPassthroughCopy('./src/fonts/'); eleventyConfig.addPassthroughCopy('./src/fonts/');
eleventyConfig.addWatchTarget('./src/fonts/'); eleventyConfig.addWatchTarget('./src/fonts/');
eleventyConfig.addPassthroughCopy('./src/img/sebin.png');
eleventyConfig.addWatchTarget('./src/img/sebin.png');
eleventyConfig.addCollection('posts', (collection) => eleventyConfig.addCollection('posts', (collection) =>
process.env.ELEVENTY_PRODUCTION process.env.ELEVENTY_PRODUCTION
? collection.getFilteredByGlob('./src/posts/*.md') ? collection.getFilteredByGlob('./src/posts/*.md')
@ -90,13 +102,9 @@ export default async function (eleventyConfig) {
} }
}); });
eleventyConfig.addPlugin(eleventyImageTransformPlugin, { eleventyConfig.addPlugin(eleventyImageTransformPlugin, {
...ELEVENTY_IMAGE_DEFAULTS,
extensions: 'html', extensions: 'html',
formats: ['avif', 'webp', 'auto'],
widths: [640, 800, 1280, 1920, 2560, 3840, 'auto'], widths: [640, 800, 1280, 1920, 2560, 3840, 'auto'],
sharpJpegOptions: { mozjpeg: true, optimiseScans: true, quality: 95 },
sharpPngOptions: { compressionLevel: 9 },
urlPath: '/img/',
outputDir: './public/img/',
defaultAttributes: { defaultAttributes: {
loading: 'lazy', loading: 'lazy',
decoding: 'async', decoding: 'async',
@ -138,12 +146,8 @@ export default async function (eleventyConfig) {
eleventyConfig.addShortcode('year', () => `${new Date().getFullYear()}`); eleventyConfig.addShortcode('year', () => `${new Date().getFullYear()}`);
eleventyConfig.addShortcode('bgimgset', async (src) => { eleventyConfig.addShortcode('bgimgset', async (src) => {
const imgset = await Image(src, { const imgset = await Image(src, {
...ELEVENTY_IMAGE_DEFAULTS,
widths: [1920, 2560, 3840], widths: [1920, 2560, 3840],
sharpJpegOptions: { mozjpeg: true, optimiseScans: true, quality: 95 },
sharpPngOptions: { compressionLevel: 9 },
formats: ['avif', 'webp', 'auto'],
urlPath: '/img/',
outputDir: './public/img/'
}); });
const getSets = ({ url, sourceType }, i) => `url(${url}) type('${sourceType}') ${i + 1}x`; const getSets = ({ url, sourceType }, i) => `url(${url}) type('${sourceType}') ${i + 1}x`;

View file

@ -6,7 +6,7 @@ permalink: /404.html
# Here be no dragons # Here be no dragons
![Sebin is unhappy with the content on his phone](/img/sebin-sticker-phone.png) ![Sebin is unhappy with the content on his phone](https://img.sebin-nyshkim.net/i/00372308-6677-4e84-8344-2630b58f6651)
The page you were looking for does not exist! The page you were looking for does not exist!

View file

@ -8,7 +8,7 @@ eleventyNavigation:
# {{ title }} # {{ title }}
![Sebin does a think](/img/sebin-sticker-think.png) ![Sebin does a think](https://img.sebin-nyshkim.net/i/35da87be-0734-4738-9503-07d52c64c905)
| Key | Value | | Key | Value |
| --------- | ----------------- | | --------- | ----------------- |

View file

@ -6,7 +6,7 @@
"author": { "author": {
"name": "Sebin Nyshkim", "name": "Sebin Nyshkim",
"href": "https://blog.sebin-nyshkim.net", "href": "https://blog.sebin-nyshkim.net",
"image": "https://cdn.sebin-nyshkim.net/-o3c3fVEgEx" "image": "https://img.sebin-nyshkim.net/i/b6629b72-ab77-4a6c-bf97-b1a615cc2454"
}, },
"twitter": { "twitter": {
"cardType": "summary_large_image", "cardType": "summary_large_image",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 752 KiB

View file

@ -7,7 +7,7 @@ eleventyNavigation:
# Rawr there! 👋🏻 # Rawr there! 👋🏻
![Sebin says hello](/img/sebin-sticker-hello.png) ![Sebin says hello](https://img.sebin-nyshkim.net/i/928fab95-ac55-4b66-b876-1c31b5924db6)
Welcome to my little corner of the internet! This is where I pour out my thoughts whenever I have them :3 Welcome to my little corner of the internet! This is where I pour out my thoughts whenever I have them :3

View file

@ -29,14 +29,14 @@
<meta name="fediverse:creator" content="{{ mastodon.fediverseCreator }}" /> <meta name="fediverse:creator" content="{{ mastodon.fediverseCreator }}" />
{% endif %} {% endif %}
<link rel="alternate" href="/feed.xml" title="Sebin's Blog" type="application/atom+xml"> <link rel="alternate" href="/feed.xml" title="Sebin's Blog" type="application/atom+xml">
<link rel="shortcut icon" href="/img/sebin.png" type="image/png"> <link rel="shortcut icon" href="https://img.sebin-nyshkim.net/i/b6629b72-ab77-4a6c-bf97-b1a615cc2454.png" type="image/png">
<link rel="me" href="https://meow.social/@SebinNyshkim"> <link rel="me" href="https://meow.social/@SebinNyshkim">
</head> </head>
<body class="bg-slate-300 text-slate-700 dark:bg-slate-900 dark:text-slate-300"> <body class="bg-slate-300 text-slate-700 dark:bg-slate-900 dark:text-slate-300">
<header class="absolute z-10 left-0 right-0 top-0 sm:px-safe-offset-4 md:px-safe-offset-6"> <header class="absolute z-10 left-0 right-0 top-0 sm:px-safe-offset-4 md:px-safe-offset-6">
<div class="flex min-h-16 max-w-(--breakpoint-xl) items-center justify-center bg-sky-600 shadow-xl sm:m-4 sm:mx-auto sm:justify-between sm:rounded-xl dark:bg-sky-950"> <div class="flex min-h-16 max-w-(--breakpoint-xl) items-center justify-center bg-sky-600 shadow-xl sm:m-4 sm:mx-auto sm:justify-between sm:rounded-xl dark:bg-sky-950">
<div class="hidden sm:flex sm:items-center"> <div class="hidden sm:flex sm:items-center">
<img src="/img/sebin.png" alt="" class="m-4 max-w-12 rounded-full border-4 border-white shadow-2xl lg:m-5 lg:max-w-14"> <img src="https://img.sebin-nyshkim.net/i/b6629b72-ab77-4a6c-bf97-b1a615cc2454" alt="" class="m-4 max-w-12 rounded-full border-4 border-white shadow-2xl lg:m-5 lg:max-w-14">
<h1 class="text-2xl text-white lg:text-3xl">Sebin's Blog</h1> <h1 class="text-2xl text-white lg:text-3xl">Sebin's Blog</h1>
</div> </div>
<nav class="eleventy-navigation" aria-label="Main"> <nav class="eleventy-navigation" aria-label="Main">

View file

@ -1,7 +1,7 @@
--- ---
title: Building a Blog with Eleventy (blind, any%) title: Building a Blog with Eleventy (blind, any%)
image: image:
src: https://cdn.sebin-nyshkim.net/-QMvyHZfXru src: https://img.sebin-nyshkim.net/i/3163c7b0-4657-40bb-b08a-462a06d1fdd5
alt: Close-up of SVG code on a computer screen alt: Close-up of SVG code on a computer screen
credit: Photo by Paico Oficial on Unsplash credit: Photo by Paico Oficial on Unsplash
width: 1200 width: 1200

View file

@ -1,7 +1,7 @@
--- ---
title: Responsive, Self-hosted Images for Your Eleventy Blog title: Responsive, Self-hosted Images for Your Eleventy Blog
image: image:
src: https://cdn.sebin-nyshkim.net/-iTHSLFBdpY src: https://img.sebin-nyshkim.net/i/f33879d8-3f98-4c8e-a1b3-08edf6f174ac
alt: Close-up of SVG code on a computer screen alt: Close-up of SVG code on a computer screen
credit: Photo by Florian Olivo on Unsplash credit: Photo by Florian Olivo on Unsplash
width: 1200 width: 1200

View file

@ -1,7 +1,7 @@
--- ---
title: Apple has no idea what to do with the iPad title: Apple has no idea what to do with the iPad
image: image:
src: https://cdn.sebin-nyshkim.net/-rtKd7CgZ6g src: https://img.sebin-nyshkim.net/i/e634e666-bdd0-4694-bd59-929ada1cd30a
alt: iOS face with swirly eyes emoji surrounded by a word cloud of Apple marketing jargon on red background with jagged lines alt: iOS face with swirly eyes emoji surrounded by a word cloud of Apple marketing jargon on red background with jagged lines
credit: Made with GIMP credit: Made with GIMP
width: 1200 width: 1200

View file

@ -1,7 +1,7 @@
--- ---
title: Open Graph Metadata and Images in Eleventy Made Easy title: Open Graph Metadata and Images in Eleventy Made Easy
image: image:
src: https://cdn.sebin-nyshkim.net/-asGarKBdVZ src: https://img.sebin-nyshkim.net/i/28d944cf-3630-4db8-bc4e-469769c83d00
alt: The Open Graph protocol logo sourrounded by the logos of Twitter, Mastodon, Telegram, Discord and the Fediverse alt: The Open Graph protocol logo sourrounded by the logos of Twitter, Mastodon, Telegram, Discord and the Fediverse
credit: Made with GIMP, logos © their respective owners credit: Made with GIMP, logos © their respective owners
width: 1200 width: 1200

View file

@ -1,7 +1,7 @@
--- ---
title: Screw the Bird title: Screw the Bird
image: image:
src: https://cdn.sebin-nyshkim.net/-6V4ELaxuR6 src: https://img.sebin-nyshkim.net/i/b884ca38-6d3c-4ecc-940c-a4137fa79cba
alt: Person throwing the blue Twitter logo into a trash can alt: Person throwing the blue Twitter logo into a trash can
credit: Made with GIMP credit: Made with GIMP
width: 1200 width: 1200

View file

@ -1,7 +1,7 @@
--- ---
title: Why Bluesky is running circles around Mastodon title: Why Bluesky is running circles around Mastodon
image: image:
src: https://cdn.sebin-nyshkim.net/-ot2jxWCtxH src: https://img.sebin-nyshkim.net/i/4cc7b20e-6a50-4674-af98-2db254c7737e
alt: An upset Mastodon logo next to a group of people talking, with one person jumping out from the group with a Bluesky logo on its head giving the Mastodon logo a big, indifferent thumbs up alt: An upset Mastodon logo next to a group of people talking, with one person jumping out from the group with a Bluesky logo on its head giving the Mastodon logo a big, indifferent thumbs up
credit: Made with GIMP credit: Made with GIMP
width: 1200 width: 1200

View file

@ -1,7 +1,7 @@
--- ---
title: How I stopped worrying and ended up using Linux instead title: How I stopped worrying and ended up using Linux instead
image: image:
src: https://cdn.sebin-nyshkim.net/-bCnLXhZpYp src: https://img.sebin-nyshkim.net/i/b9fd20eb-e4c5-4f76-ae8a-b57773c3acc9
alt: Photo of a penguin flapping its wings alt: Photo of a penguin flapping its wings
credit: Photo by Sander Crombach on Unsplash credit: Photo by Sander Crombach on Unsplash
width: 1200 width: 1200

View file

@ -1,7 +1,7 @@
--- ---
title: Mario Kart World costing $80 is not the issue title: Mario Kart World costing $80 is not the issue
image: image:
src: https://cdn.sebin-nyshkim.net/-uKSq8Wscus src: https://img.sebin-nyshkim.net/i/273d250e-177c-4054-a20b-f9f3e83bb7b2
alt: Mario Kart World Key Art alt: Mario Kart World Key Art
credit: © Nintendo credit: © Nintendo
width: 1200 width: 1200

View file

@ -6,7 +6,7 @@
"author": { "author": {
"name": "Sebin Nyshkim", "name": "Sebin Nyshkim",
"href": "https://blog.sebin-nyshkim.net", "href": "https://blog.sebin-nyshkim.net",
"image": "https://cdn.sebin-nyshkim.net/-o3c3fVEgEx" "image": "https://img.sebin-nyshkim.net/i/b6629b72-ab77-4a6c-bf97-b1a615cc2454"
}, },
"twitter": { "twitter": {
"cardType": "summary_large_image", "cardType": "summary_large_image",