Incremental builds
The first dotnet publish renders every page. Later publishes reuse a page's HTML when
nothing it depends on has changed, and always produce a complete site.
What changes cause work?
| Change | Work |
|---|---|
| Markdown changes | Render pages that read that item or its collection. |
| Content is added, removed, or reordered | Render pages that read the whole collection, and add or remove pages. |
| Page parameters change | Render affected pages. |
| A local image changes | Render pages that use it and update its variants. |
| A static asset changes | Update the asset and pages that link it through Assets or ImportMap. |
| Code, packages, the .NET runtime, or site settings change | Render all pages. |
A page uses an AlwaysRender component |
Render that page on every publish. |
Feeds, sitemaps, and custom artifacts are regenerated on every publish.
Page dependencies
Posts[ContentKey] depends on one item. Enumerating a dictionary, reading Count, Keys,
or Values, or looking up a missing key depends on the whole collection, even if you
filter afterward. Reads in layouts and child components count too: a layout that lists
every post makes every page depend on all posts.
Pass a content key or another simple value through AddPageParameters and look the item
up while rendering. Passing whole models or arrays works but disables reuse for that page;
see the reusable parameter types.
Render pages that use external data
Kiji tracks reads through ContentDictionary<T>. To track other data, load it with
UseContentSource and supply
digests. Kiji cannot see other reads, such as files, HTTP, environment variables, the
clock, or service state. Mark components that render such values:
@attribute [AlwaysRender]
<p>@Environment.GetEnvironmentVariable("SITE_ANNOUNCEMENT")</p>
Every page that renders the component, including through a layout, is rendered on every publish. If external state decides whether a child component appears, mark the parent.
AlwaysRender only re-renders HTML; it does not refresh data a service has cached, and
content reloads do not recreate singletons. Build shared derived data with
UseContentSource instead. During development, restart dotnet watch when external data
changes.
Reset and inspect
# Render every page once; later publishes reuse the results.
dotnet publish -p:KijiForce=true
# Show per-file details. --tl:off is needed because the default terminal display hides them.
dotnet publish -p:KijiVerbose=true --tl:off
# Remove build output and the cache.
dotnet clean
Kiji keeps its publish cache in .kiji/cache and development output in .kiji/dev-site.
Saving the cache between CI runs often does not pay off, because transferring it takes time
and code or package changes render every page anyway. Before relying on a CI cache,
compare total CI time with and without it.