Skip to content

enhance: shrink the diff file tree data and move it out of window.config - #39242

Open
silverwind wants to merge 12 commits into
go-gitea:mainfrom
silverwind:difffiletree-size
Open

enhance: shrink the diff file tree data and move it out of window.config#39242
silverwind wants to merge 12 commits into
go-gitea:mainfrom
silverwind:difffiletree-size

Conversation

@silverwind

@silverwind silverwind commented Sep 4, 2026

Copy link
Copy Markdown
Member

DiffFileTree was the largest thing in window.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.

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
@GiteaBot GiteaBot added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Sep 4, 2026
@github-actions github-actions Bot added the type/enhancement An improvement of existing functionality label Sep 4, 2026
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
Comment thread routers/web/repo/treelist.go Outdated
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
@silverwind

silverwind commented Sep 4, 2026

Copy link
Copy Markdown
Member Author

Some more payload optimization done, size is now down to 45kB, compared to 277kB before.

Comment thread routers/web/repo/treelist.go Outdated
Comment thread web_src/js/components/DiffFileTreeItem.vue Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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 of window.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.

Comment thread web_src/js/modules/diff-file.ts
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
Comment thread web_src/js/components/SvgIcon.vue Outdated
Signed-off-by: silverwind <me@silverwind.io>
Assisted-by: Claude Code:Opus 5
Comment thread web_src/js/components/SvgIcon.vue Outdated
Signed-off-by: silverwind <me@silverwind.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. type/enhancement An improvement of existing functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants