perf(gitdiff): optimize inline diff highlighting using cache (#38706)

This pull request optimizes code diff highlighting in the PR Files
Changed view, which is a major CPU bottleneck and hot path in
production.

Previously, Gitea executed the expensive `DiffMatchPatch` algorithm
twice for every matching deleted/added line pair (once for the deleted
line, and once for the added line). We now run the diff algorithm once
and cache the resulting `DiffInline` on the `DiffLine` struct itself,
allowing the second line to render via a 0-cost cache lookup.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
This commit is contained in:
Shudhanshu Singh
2026-07-30 22:13:36 +05:30
committed by GitHub
parent 11d0ed699b
commit d87d26d735
11 changed files with 186 additions and 157 deletions
+1 -1
View File
@@ -288,7 +288,7 @@ func prepareMockDataUnicodeEscape(ctx *context.Context) {
lineEscapeStatus := make([]*charset.EscapeStatus, len(highlightLines))
for i, hl := range highlightLines {
lineEscapeStatus[i], hl.FormattedContent = charset.EscapeControlHTML(hl.FormattedContent, ctx.Locale)
escapeStatus = escapeStatus.Or(lineEscapeStatus[i])
escapeStatus.Combine(lineEscapeStatus[i])
}
ctx.Data["HighlightLines"] = highlightLines
ctx.Data["EscapeStatus"] = escapeStatus
+1 -1
View File
@@ -272,7 +272,7 @@ func renderBlame(ctx *context.Context, blameParts []*git.BlamePart, commitNames
line = template.HTML(util.UnsafeBytesToString(unsafeLines[i]))
}
br.EscapeStatus, br.Code = charset.EscapeControlHTML(line, ctx.Locale)
escapeStatus = escapeStatus.Or(br.EscapeStatus)
escapeStatus.Combine(br.EscapeStatus)
}
ctx.Data["EscapeStatus"] = escapeStatus
+1 -1
View File
@@ -127,7 +127,7 @@ func handleFileViewRenderSource(ctx *context.Context, attrs *attribute.Attribute
statuses := make([]*charset.EscapeStatus, len(fileContent))
for i, line := range fileContent {
statuses[i], fileContent[i] = charset.EscapeControlHTML(line, ctx.Locale)
status = status.Or(statuses[i])
status.Combine(statuses[i])
}
ctx.Data["EscapeStatus"] = status
ctx.Data["FileContent"] = fileContent