You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up to f0312d8: removes repeated lookups, revalidation requests and avoidable layout shift on public pages. No public component contract changes.
ShowBlogPostPage
- ShortCodeRepository.GetAllAsync() # every visit+ ShortCodeCache.GetAsync() # cleared by ShortCodesPage store/delete
SimilarBlogPostSection.OnParametersSetAsync
- 2 queries × every parent render (~6)+ skip if same post; FusionCache "similar/{id}", tagged
SimilarBlogPostJob (runs on publish, save, delete)
+ RemoveByTagAsync(CacheTag) after rebuild
OnAfterRender(first)
- StoreUserRecordAsync → IsBookmarked+ IsBookmarked → StoreUserRecordAsync # icon no longer waits on a DB write
ArchivePage
- project p.Slug # unmapped → full entity incl. Content+ project Title, Slug computed on the record
BookmarkService
- ContainsKey + Get (+ Set) per card+ concurrent callers share one pending read; later pages read fresh
App.razor
- <link href="css/basic.css"> # no-cache, revalidated every load+ <link href="@Assets["css/basic.css"]"> # fingerprinted, immutable+ <ImportMap /> # .razor.js imports hit hashed files
ThemeToggler
- render one icon after 3 encrypted-storage interop calls+ render both, CSS on :root[data-bs-theme] picks one; click → JS toggleTheme()
ReadingIndicator.razor.js
- addEventListener('scroll') per post visit+ one passive, rAF-throttled listener; tracks the current post's elements
Also: home cards re-render only when bookmarked, Like reads storage once per post, static JsonSerializerOptions in StructuredData, code blocks get the highlight.js box up front, post images use height:auto with decoding="async" and fetchpriority="high" on the first, cards use contain-intrinsic-size: auto 300px.
Evidence
Headless Chrome against dummy data, baseline from a worktree at master:
Before
After
Post visit, first (DB commands)
8
4
Post visit, repeat (DB commands)
9
1 (visit record insert)
Archive SQL selects Content
yes
no
Scroll listeners after post → home → post
2
1
Theme icon before Blazor starts, light scheme
moon
sun
Local CSS/JS URLs
plain, no-cache
hashed, max-age=31536000, immutable¹
¹ Development serves even hashed URLs as no-cache; the header is from the endpoint manifest.
Tests: unit 446 passed, integration 229 passed. New:
BookmarkService: 3 concurrent IsBookmarked → 1 storage read
BookmarkService: a later check sees a bookmark another tab added
SimilarBlogPostJob: rebuild evicts cached similar-post lists
SimilarBlogPostSection: re-render with the same post → 1 query
ThemeToggler: both icons rendered, no interop until click; click → toggleTheme
Merge Danger
Door: two-way
Blast Radius: public pages
Visitors who only have the old encrypted preferred-theme key fall back to the system preference once.
Similar posts and shortcodes are now cached. SimilarBlogPostJob evicts similar-post lists after each rebuild; the shortcodes page evicts shortcodes. Shortcodes written to the DB any other way stay cached up to 7 days.
Images without declared dimensions still shift; code-block and image CLS gains weren't measurable locally (CDN theme loads too fast).
This PR improves public-page performance by caching repeated lookups, fingerprinting local assets, and reducing unnecessary rendering and layout shifts.
Changes:
Cache shortcodes, similar posts, and bookmark reads; streamline archive projections.
Fingerprint assets and simplify theme switching and reading-progress updates.
Adjust image and code-block styling, with tests for the updated behavior.
The reason will be displayed to describe this comment to others. Learn more.
Fixed in db79b25: entries are tagged SimilarBlogPostJob.CacheTag and the job evicts the tag after each rebuild. Delete, publish and save all run the job.
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
Restoring an article version neither invalidates nor rebuilds the related-post cache, leaving fresh visits with stale titles, descriptions, and slugs until the cache expires.
After a related-post list is cached, restoring an article version leaves fresh visits showing its pre-restore title, description, and slug until the cache expires. The restore path saves the article but neither invalidates SimilarBlogPostJob.CacheTag nor runs the rebuild used by normal saves. Invalidate that tag or trigger the rebuild after restoration, and add a test that warms the cache before restoring a version.
Restore path fixed in d2826b4: restoring a version now runs SimilarBlogPostJob like a normal save, which recomputes similarities and evicts SimilarBlogPostJob.CacheTag. Covered by GivenVersionRestore_SimilarBlogPostsAreRecalculated; eviction itself by ShouldEvictCachedSimilarBlogPostsAfterRecalculating.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Follow-up to f0312d8: removes repeated lookups, revalidation requests and avoidable layout shift on public pages. No public component contract changes.
Also: home cards re-render only when bookmarked,
Likereads storage once per post, staticJsonSerializerOptionsinStructuredData, code blocks get the highlight.js box up front, post images useheight:autowithdecoding="async"andfetchpriority="high"on the first, cards usecontain-intrinsic-size: auto 300px.Evidence
Headless Chrome against dummy data, baseline from a worktree at
master:Contentno-cachemax-age=31536000, immutable¹¹ Development serves even hashed URLs as
no-cache; the header is from the endpoint manifest.Tests: unit 446 passed, integration 229 passed. New:
Merge Danger
Door: two-way
Blast Radius: public pages
preferred-themekey fall back to the system preference once.SimilarBlogPostJobevicts similar-post lists after each rebuild; the shortcodes page evicts shortcodes. Shortcodes written to the DB any other way stay cached up to 7 days.