Skip to content

Commit

Permalink
Parallelize @astrojs/image transforms (#4626)
Browse files Browse the repository at this point in the history
  • Loading branch information
altano committed Sep 6, 2022
1 parent 5231ec0 commit 494c2b8
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .changeset/rich-dolphins-teach.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/image': patch
---

Parallelize image transforms
1 change: 1 addition & 0 deletions packages/integrations/image/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"test": "mocha --exit --timeout 20000 test"
},
"dependencies": {
"@altano/tiny-async-pool": "^1.0.2",
"image-size": "^1.0.2",
"magic-string": "^0.25.9",
"mime": "^3.0.0",
Expand Down
26 changes: 19 additions & 7 deletions packages/integrations/image/src/build/ssg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import type { SSRImageService, TransformOptions } from '../loaders/index.js';
import { loadLocalImage, loadRemoteImage } from '../utils/images.js';
import { debug, info, LoggerLevel, warn } from '../utils/logger.js';
import { isRemoteImage } from '../utils/paths.js';
import OS from 'node:os';
import { doWork } from '@altano/tiny-async-pool';

function getTimeStat(timeStart: number, timeEnd: number) {
const buildTime = timeEnd - timeStart;
Expand All @@ -23,19 +25,26 @@ export interface SSGBuildParams {

export async function ssgBuild({ loader, staticImages, config, outDir, logLevel }: SSGBuildParams) {
const timer = performance.now();
const cpuCount = OS.cpus().length;

info({
level: logLevel,
prefix: false,
message: `${bgGreen(
black(` optimizing ${staticImages.size} image${staticImages.size > 1 ? 's' : ''} `)
black(
` optimizing ${staticImages.size} image${
staticImages.size > 1 ? 's' : ''
} in batches of ${cpuCount} `
)
)}`,
});

const inputFiles = new Set<string>();

// process transforms one original image file at a time
for (let [src, transformsMap] of staticImages) {
async function processStaticImage([src, transformsMap]: [
string,
Map<string, TransformOptions>
]): Promise<void> {
let inputFile: string | undefined = undefined;
let inputBuffer: Buffer | undefined = undefined;

Expand All @@ -60,15 +69,15 @@ export async function ssgBuild({ loader, staticImages, config, outDir, logLevel
if (!inputBuffer) {
// eslint-disable-next-line no-console
warn({ level: logLevel, message: `"${src}" image could not be fetched` });
continue;
return;
}

const transforms = Array.from(transformsMap.entries());

debug({ level: logLevel, prefix: false, message: `${green('▶')} ${src}` });
debug({ level: logLevel, prefix: false, message: `${green('▶')} transforming ${src}` });
let timeStart = performance.now();

// process each transformed versiono of the
// process each transformed version
for (const [filename, transform] of transforms) {
timeStart = performance.now();
let outputFile: string;
Expand All @@ -92,11 +101,14 @@ export async function ssgBuild({ loader, staticImages, config, outDir, logLevel
debug({
level: logLevel,
prefix: false,
message: ` ${cyan('└─')} ${dim(pathRelative)} ${dim(timeIncrease)}`,
message: ` ${cyan('created')} ${dim(pathRelative)} ${dim(timeIncrease)}`,
});
}
}

// transform each original image file in batches
await doWork(cpuCount, staticImages, processStaticImage);

info({
level: logLevel,
prefix: false,
Expand Down
6 changes: 6 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 494c2b8

Please sign in to comment.