Conversation
The public page stayed on 「正在加载目录…」 until the full ~1MB snapshot arrived uncompressed with no-store. Serve a lean snapshot (truncated abstracts), precompressed gzip, public SWR + If-None-Match, and paint the last-good catalog from localStorage while progress stays live. Co-authored-by: Daniel <znsoft@163.com>
Locks in the first-paint payload shrink (full → lean → gzip) so a repetitive fixture cannot hide a future size regression. Co-authored-by: Daniel <znsoft@163.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Problem
Public
/paperspaints the shell (header, chips, filters) then sits on 「正在加载目录…」 untilGET /papers/api/catalogfinishes. On the nginx → search-proxy → tunnel → search-service path that body is ~1 MB uncompressed, caching was not CDN/browser-friendly for a static snapshot, and the client always waited on a full download before the first card.What changed
Three complementary fixes; live progress / manage / visits stay on the tiny
GET /papers/api/progresspoll.catalog-snapshot.jsonnow truncates abstracts to 400 EN / 220 ZH runes (cards still show 280 / 140).query_hitsdropped. Same card ZH/EN brief, search still matches the prefix.catalog-snapshot.json.gz.GET /papers/api/catalog(andGET /papers/static/catalog-snapshot.json) serves:Cache-Control: public, max-age=60, stale-while-revalidate=300ETag+If-None-Match→ 304Content-Encoding: gzipwhenAccept-Encodingincludes gzipcan_manage/ visit overlay (those stay on/progress) so the bytes are actually staticlocalStorage(rs_papers_catalog_v1) and painted immediately on repeat visits. Catalog + progress fetch in parallel. Empty-body retry only when the first 200 is empty and nothing is on screen. Nocache: "no-store"on the catalog GET.Relay
http.Clientnow setsDisableCompression: trueso gzipContent-Encodingsurvives the tunnel (Go’s default transport would otherwise inflate it).Before / after (measured)
Unit fixture (
TestLeanCatalogSizeReduction, 80 papers, unique-ish abstracts):Scaled to the public ~1 MB catalog of similar uniqueness, first download is on the order of ~100 KB gzipped instead of ~1 MB uncompressed. Repeat visits: 304 (0 body) or localStorage paint.
Local 40-paper fixture (this agent’s browser/curl check):
GET /papers/api/catalogpublic, max-age=60, stale-while-revalidate=300, ETagAccept-Encoding: gzipContent-Encoding: gzipIf-None-Matchagent安全Public catalog stays far under the ~2 MiB tunnel safety margin. Streaming for
/papers/api/catalogis unchanged.Snapshot regenerate / invalidate
Operators do not run a separate generator.
PAPERS_CATALOG_SNAPSHOT_INTERVAL(default60s)invalidateCatalog$PAPERS_DIR/catalog-snapshot.jsonand.gzDocumented in
README.mdandagent-papers/README.md.Test plan
go test ./...Content-Encoding,If-None-Match304, lean truncation + size ratiohydrateCatalogCache/fetchCatalogJSON/If-None-Match; nono-storeon catalog fetch/papers: cards + Chinese briefs on first paint; reload is 304 / instantno-storeand still carriessnapshot_etag/can_manage/ visitsStacked on
cursor/papers-review-crosslinks-1557(current papers tip). Do not merge ontomainuntil that stack lands.