enhance: shrink the diff file tree data and move it out of window.config - #39242
Open
silverwind wants to merge 12 commits into
Open
enhance: shrink the diff file tree data and move it out of window.config#39242silverwind wants to merge 12 commits into
window.config#39242silverwind wants to merge 12 commits into
Conversation
DiffFileTree dominated window.config on large diffs, 257kB of the 277kB payload on a 558-file commit. It is page-specific data that every page carried the cost of parsing, so it now renders into its own JSON block on the diff page instead. The payload itself drops to 83kB by deduplicating the repeated per-file icon markup into a table, omitting empty fields, and rebuilding the full paths in the frontend from the names already in the tree. Folder icons come from the frontend's own SVG set now, so the diff tree no longer follows FOLDER_ICON_THEME. Assisted-by: Claude Code:Opus 5
Rendering them from the frontend's SVG set made the diff tree ignore FOLDER_ICON_THEME. Assisted-by: Claude Code:Opus 5
Assisted-by: Claude Code:Opus 5
delvh
reviewed
Sep 4, 2026
The icon markup was the largest part of the tree payload and repeated the same few SVGs hundreds of times. The definitions are already on the page in FileIconPoolHTML, so each entry now carries only the ID to reference and the wrapper class, and the frontend builds the element. The class has to come from the backend: `.svg:not(.git-entry-icon)` sets `fill: currentcolor`, which octicons need and material icons must not have, so it cannot be inferred client-side. Entries also drop EntryMode, since the presence of children already tells directories apart, and the full path, which the frontend rebuilds from the names it already has. Assisted-by: Claude Code:Opus 5
…ashes NameHash was the largest field left in the payload and, being SHA-1 hex, nearly all of its entropy. The diff boxes already carry both halves of the mapping in data-new-filename and id, so the tree derives the anchor from there. Files whose box has not been rendered yet now get no link rather than one pointing at an element that does not exist. Assisted-by: Claude Code:Opus 5
…ntry Nearly every file in a diff resolves to the same wrapper class, so repeating it per entry was the biggest remaining field. The tree carries it once and entries only override it, which submodules and symlinks do. Also drop the duplicate box query that ran on every filter keystroke. Assisted-by: Claude Code:Opus 5
Member
Author
|
Some more payload optimization done, size is now down to 45kB, compared to 277kB before. |
wxiaoguang
reviewed
Sep 4, 2026
silverwind
commented
Sep 4, 2026
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
The frontend currently computes directory “viewed” state before child directories’ IsViewed is derived, which breaks initial viewed-state for nested directories.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR reduces the diff page payload by moving DiffFileTree out of window.config.pageData into a dedicated JSON block and compressing the file tree data (icons by pooled SVG ID, fewer repeated fields, and reconstructing paths client-side).
Changes:
- Render diff file tree data into
<script type="application/json" id="diff-file-tree-data">and build the Vue store from that JSON instead ofwindow.config.pageData. - Shrink tree payload by pooling icons (SVG IDs + common class), omitting repeated/empty fields, and rebuilding full paths in the frontend.
- Update file-tree UI + filters to work off reconstructed paths and a DOM-derived box-id map.
File summaries
| File | Description |
|---|---|
| web_src/js/utils.ts | Adds joinPath helper for rebuilding full paths on the client. |
| web_src/js/modules/diff-file.ts | Reworks diff tree store to parse JSON block, use pathMap/boxIdMap, and filter by reconstructed paths. |
| web_src/js/modules/diff-file.test.ts | Updates unit tests to the new tree shape (names as segments + rebuilt paths). |
| web_src/js/globals.d.ts | Removes DiffFileTree + folder icon entries from window.config.pageData typings. |
| web_src/js/features/repo-diff.ts | Guards filter application when file tree is not present. |
| web_src/js/features/pull-view-file.ts | Removes diff-tree store mutation from the viewed-file checkbox handler (now handled in file tree component). |
| web_src/js/components/DiffFileTreeItem.vue | Switches file icon rendering to pooled <use href="#id"> and links by DOM box ID map. |
| web_src/js/components/DiffFileTreeItem.test.ts | Updates component test setup to provide the new JSON block. |
| web_src/js/components/DiffFileTree.vue | Adds delegated listener to keep tree “viewed” state in sync with checkboxes; passes path prop into items. |
| templates/repo/diff/box.tmpl | Injects icon pool HTML and the new JSON block for the diff file tree. |
| routers/web/repo/treelist.go | Changes server-side tree DTO to compact fields, pool icons, and attach folder/icon metadata. |
| routers/web/repo/treelist_test.go | Updates expectations for the new compact tree fields and icon pooling behavior. |
| routers/web/repo/pull.go | Uses shared setDiffFileTreeData to populate template data for PR diff pages. |
| routers/web/repo/compare.go | Uses shared setDiffFileTreeData to populate template data for compare pages. |
| routers/web/repo/commit.go | Uses shared setDiffFileTreeData to populate template data for commit diff pages. |
| modules/fileicon/render.go | Adds RenderEntryIconID and icon-pooling support for <use> references. |
| modules/fileicon/material.go | Adds material icon ID pooling and returns wrapper class for <use> rendering. |
Review details
- Files reviewed: 16/17 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
A directory's viewed state was derived before its child directories had theirs, so a directory containing only viewed subdirectories stayed unviewed until something re-triggered it. Also rename Icon to IconID, and render the pooled icon through SvgIcon with a new useHref option instead of hand-written markup. Assisted-by: Claude Code:Opus 5
silverwind
commented
Sep 4, 2026
Signed-off-by: silverwind <me@silverwind.io>
Assisted-by: Claude Code:Opus 5
Assisted-by: Claude Code:Opus 5
Assisted-by: Claude Code:Opus 5
silverwind
commented
Sep 4, 2026
Signed-off-by: silverwind <me@silverwind.io>
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.
DiffFileTreewas the largest thing inwindow.config, 257kB of the 277kB payload on a 558-file commit. It now renders into its own JSON block on the diff page, and shrinks to 45kB by referencing icons by SVG ID instead of repeating their markup, resolving file anchors from the DOM instead of sending a SHA-1 per file, omitting empty and repeated values, and rebuilding full paths in the frontend.