-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve Static Asset Generation Performance #12922
Improve Static Asset Generation Performance #12922
Conversation
🦋 Changeset detectedLatest commit: 11ce57e The changes in this PR will be included in the next version bump. Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
CodSpeed Performance ReportMerging #12922 will not alter performanceComparing Summary
|
@ascorbic I’m skeptical that this change would affect any tests, but 5 CI tests are failing. A quick investigation reveals that some fixture assets are As you mentioned, because we |
Yes, this does make me concerned that it's not waiting correctly. One way to check could be to push all of the |
Bingo! It was the for (const [_, transform] of transformsAndPath.transforms) {
await queue
.add(async () => generateImage(transform.finalPath, transform.transform))
.catch((e) => {
throw e;
});
} The |
ebedb9f
to
3064167
Compare
OK, great. Well found. I'll review this in detail today, because it will need a careful look because it's a critical piece. |
Could you update the PR description to match what you finally did, so we can refer to it in future? Including most of the wording from the comment would cover most of it. |
Changes
Improve static asset generation performance by removing the
await
in thefor
loop. This change will allow the p-queue concurrency to limit the number of parallel tasks. Previously, theawait
in thefor
loop would cause all asset generation tasks to run serially.core/build/generate.ts:
await
in thisfor
loop so that tasks can execute based on the p-queueconcurrency
.queue
togenerateImagesForPath
.assets/build/generate.ts:
queue.add
here, prevents unintentional adding to the queue after we expect the queue to be completeawait queue.onIdle();
Fixes #12845
Design Decision:
We have 3 source images (A.png, B.png, C.png) and 3 transforms for each:
Option 1
Enqueue all transforms indiscriminantly
Option 2
Enqueue all transforms, but constrain processing order by source image
Option 3
Enqueue each source image, but perform the transforms for that source image sequentially
Best Option:
Option 3. Most projects will have a higher number of source images with a few transforms on each. Even though Option 2 should be faster and should prevent context switching, this was not observed in nascent tests. Context switching was high and the overall performance was half of Option 3.
If looking to optimize further, please consider the following:
queue.add()
in an async for loop. Notice theawait queue.onIdle();
after this loop. We do not want to create a scenario where tasks are added to the queue afterqueue.onIdle()
resolves. This can break tests and create annoying race conditions.astro.config.mjs
to allow users to override Node’sos.cpus().length
default.Testing
No additional tests required.
Docs
Static asset generation performance should increase by
os.cpus().length
in most Astro projects with assets.