footer build SHA auto-resolve + devblog w27

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dz6jMCAoU9ip7mEshjZci7
This commit is contained in:
Gergő Törcsvári 2026-07-07 17:03:56 +02:00
commit 93e73c590e
No known key found for this signature in database
GPG key ID: 8E75F2CDE64E5322
5 changed files with 94 additions and 6 deletions

18
site/package-lock.json generated
View file

@ -18,6 +18,7 @@
"devDependencies": {
"@astrojs/check": "^0.9.9",
"@tailwindcss/postcss": "^4.3.0",
"@types/node": "^26.1.0",
"tailwindcss": "^4.3.0",
"typescript": "^6.0.3"
},
@ -2281,6 +2282,16 @@
"@types/unist": "*"
}
},
"node_modules/@types/node": {
"version": "26.1.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-26.1.0.tgz",
"integrity": "sha512-O0A1G3xPGy4w7AgQdAQYUlQ+BKk2Oovw8eRpofyp5KdBZULnbe+WqaOVNrm705SHphCiG4XHsACrSmPu1f+Kgw==",
"devOptional": true,
"license": "MIT",
"dependencies": {
"undici-types": "~8.3.0"
}
},
"node_modules/@types/unist": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
@ -7015,6 +7026,13 @@
"integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==",
"license": "MIT"
},
"node_modules/undici-types": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz",
"integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==",
"devOptional": true,
"license": "MIT"
},
"node_modules/unified": {
"version": "11.0.5",
"resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz",

View file

@ -24,6 +24,7 @@
"devDependencies": {
"@astrojs/check": "^0.9.9",
"@tailwindcss/postcss": "^4.3.0",
"@types/node": "^26.1.0",
"tailwindcss": "^4.3.0",
"typescript": "^6.0.3"
}

View file

@ -1,4 +1,5 @@
---
import { execSync } from 'node:child_process';
import Icon from './Icon.astro';
import EECredit from './EECredit.astro';
@ -6,11 +7,21 @@ const year = new Date().getFullYear();
// TODO(links): add Roadmap (/roadmap) and dedicated How-it-works/Open pages when they ship.
const GITHUB_URL = 'https://github.com/emergence-engineering';
// Build provenance. Hardcoded because the site ships as static assets (R2), so
// there's no build-time git/env to read it from. BUMP THIS to the deployed
// main-repo (pcbjam) commit on each release — it pins the KiCad + wxWidgets
// submodule revisions implicitly. See /licenses for the source-code offer.
const BUILD_SHA = '695a460';
// Build provenance: the pcbjam commit this site was built from — it pins the
// KiCad + wxWidgets submodule revisions implicitly and is our GPLv3
// corresponding-source pointer (see /licenses). Resolved at build time:
// Vercel sets VERCEL_GIT_COMMIT_SHA; local builds fall back to git.
function resolveBuildSha(): string {
const vercelSha = process.env.VERCEL_GIT_COMMIT_SHA;
if (vercelSha) return vercelSha.slice(0, 7);
try {
return execSync('git rev-parse --short=7 HEAD', { encoding: 'utf8' }).trim();
} catch {
// No git either (e.g. tarball build) — link to the branch head.
return 'main';
}
}
const BUILD_SHA = resolveBuildSha();
const BUILD_COMMIT_URL = `https://github.com/emergence-engineering/pcbjam/commit/${BUILD_SHA}`;
---

View file

@ -0,0 +1,58 @@
---
title: "DevBlog 2026 week 27"
description: "Optimizing, loadtime, download-size, 3d"
author: Gergő Törcsvári
pubDate: 2026-07-06
---
# Lowering the size and load time!
This week looks like a week of optimizations, but its not that simple, its never that simple.
## OCC split
KiCad has OpenCascade as a dependency, which was about 30% of the pcbnew.wasm, but it only does STEP parsing/exporting for the 3D viewer.
So we moved OCC into a stnadalone worker, with its own memory, and only fetch it on demand. The editor size dropped from ~146MB to ~109MB which is HUGE.
If you don't use the 3D viewer, you don't need to load it, and the app loads way faster.
As an added bonus, we found out that STEP export was not working, and this brought us a step closer to make that work too!
## Native exceptions
We migrated the whole build from Emscripten's (legacy) JS-based exception handling (which effectively did a wasm->js->wasm call on every try/catch) to native wasm exceptions.
KiCad is very exception heavy, so we got a big payoff, eeschema.wasm gzip went from 37.2MB to 28.9MB, kinda the same ~24% reduction was in pcbnew too.
The cold loads got 30-35% faster and documents opens up 20-35% faster. Not crossing the wasm \<-> js boundary is a big win both in size and speed.
It also unblocked the multithreading in some cases like in the 3D view raytracer.
## Multithreading fixes
WASM pthreads are actually WebWorkers, so spawning one, requires the main thread to return to the browser event loop, and request one.
This means that every block on the main thread that is waiting for a worker thread start effectively deadlocked themselves.
The raytracer was hit with this, and we fixed it with a predefined threadpool, and also fixed problems with its resize interactions.
## Libs loading (symbols and footprints)
We load libs in multiple passes. First while the editor loads we do an R2->IDB sync
(which is a bit slow, but we found an easy solution for that this morning so we will do that parallel), and we have a wasm \<-> js sync.
This later was about 4.5 minutes for 222 symbol libs, which is far from being user friendly.
The previous solution used json between the boundary, but only the json deserialization in the wasm part was 61s (yes... 0.2s serialization in js land, 61s deser in wasm land, it seems removing `\n`-s is "hard").
So we changed the protocol a bit, and we send a json in the first line, and a big concatenated text as a blob after, and the json tells the wasm where the next "file" starts in the blob. (This reduced the 61s to 0.2s.)
We changed the loading to be parallel, and the memory allocator to mimalloc (120s->45s raw cpu time in s-expr pars just with this change).
All of the above reduced the raw loadtime from 274s to 44s which is in parallel about 6-10s, which is much better.
We hiding the "freezed up" editor under the overlay while this happening, and communicate the fact that we need to wait, which makes the whole process less painful to the future users.
## Size optimizations
I wanted to switch back the "default footprint" feature in eeschema, so we hit a problem.
Previously we tried to minimize the wasm footprint from 500MB so we split the KiCad editor into multiple smaller editors. KiCad has these components called KiFaces.
For the eeschema, we needed the symbol editor (and vica versa). For the pcbnew, we needed the footprint editor (and vica versa). But we effectively split KiCad to smaller pieces, achiving ~180-230MB wasms.
But if you want to show the footprints in the symbol editor, we need the footprint editor KiFace, which is effectively dragging the whole pcbnew too.
Also, at this point we have about 80-100MB wasms. So we made a single wasm from these four editors, only changing "main" to select which KiFace should open up.
Now instead of 4x80MB we have a single 100MB or so wasm. Also we switched on brotli-q11 which killed our release time (3m to 20m), but shaved the download size a LOT (currently 30MB).
# 3D viewer
We made two separate things in this part (4 actually if we count the multi threading and the OCC too).
We built a gl1-on-WebGL2 emulation layer, which lets KiCad's real OpenGL 3D renderer to run unmodified.
Basically we made a WebGL implementation of the functions that KiCad uses, and we made a translation layer to convert the OpenGL calls to WebGL calls.
This is a huge win, because we can now run the 3D viewer on any browser, its fast, efficient, and worked like a charm!
On the other hand, we added 3D models to work the same as other libs, so they do the same R2->IndexedDb->WASM loading, but its done lazily, and per model instead of per lib,
so you don't need to download models that you never viewed. We also added some UI to the demo page to show you how much data we store in your IDB, and you can drop the 3D models.
# Demo release
We made a [demo release](https://demo.pcbjam.com) and wrote a post to [HackerNews](https://news.ycombinator.com/item?id=48793542) which was on the first page for a while, and got some buzz.