The time between deciding and the site saying so

Part 2 of 7 of ./blog.sh v1.6

Publishing a post used to cost the size of the archive, not the size of the change. A post dated today alters a dozen files. The build rendered every page in the archive and read every one back off disk to find that out.

On the archive this engine was built around — 6,639 posts, on the server it lives on — that was 47 seconds for a rebuild that changed nothing, and 48 from pressing publish to the post being out. Fine for one post in the morning. Less fine for fixing a typo in ten of them.

What the build remembers now

1.6 keeps a record of what went into each page: the post, the template, the locale, the configuration, the engine itself. On the next build it renders only the pages whose record no longer matches, and the rest cost one stat each instead of a full render and a read-back.

The same archive, measured the same way: a rebuild that changes nothing takes a seventh of what it did. Publishing a post dated today takes about two fifths — 16 seconds of build and 2 of upload, where it was 48 — and the build says so itself: Pages already up to date, not rebuilt: 10,160. The ratio is what travels; the seconds are one machine's.

What it still cannot skip

A post dated into the early 2000s costs four fifths of a full build, and there is no way around that. A post landing there moves every listing page between the front page and where it lands, and those pages genuinely changed. The cache skips what did not change; it cannot skip what did. Importing an archive is backdating several thousand times over, so an import is a full build, as it always was — which is also why an import should land in one go rather than post by post.

Editing a template, a locale or site.yml throws the whole record away, because any of those can change every page. So does a change of timezone, including the one a system update makes without you touching anything. A stylesheet is the exception worth knowing: pages link it, they do not embed it, so editing one changes the stylesheet and nothing else — the build after it renders the pages once more and finds nothing new to upload but the one file.

A note, not an authority

The record is an optimisation and never the truth about the site. Anything it cannot vouch for is built the old way: a record that is missing, truncated, in a different format, or left by a build that died halfway. A page somebody deleted or damaged by hand in public.nosync/ comes back on the next build, because the record is checked against what is actually on disk. And public.nosync/ is still swept of anything the build does not produce, cache or no cache.

It lives in .build_cache.json in the installation directory — gitignored, one per machine, always safe to delete. Deleting it costs one slow build and nothing else, which is the whole point of keeping the archive as files: the note about the files is just another file.

./blog.sh rebuild --full        # build every page again, then deploy

Nothing to migrate. The first build after git pull is a full one and writes the record; every build after it reads it.

Comments