detached f2573c8

feat(webui): show resolved performance settings in config page

commit
f2573c88961ef9a59e1aa0c38109f71de32a9528
author
brice · · 2025-12-28 21:22 UTC
committer
brice · · 2025-12-29 17:28 UTC
parent
8cf3f3c
signature
unsigned
2 files · +74 -1
M internal/infrastructure/webkit/scheme_handler.go +27 -1
@@ -77,7 +77,20 @@ type configAppearancePayload struct {
7777 }
7878
7979 type configPerformancePayload struct {
80- Profile string `json:"profile"`
80+ Profile string `json:"profile"`
81+ Resolved configResolvedPerformance `json:"resolved"`
82+}
83+
84+// configResolvedPerformance shows the actual values that will be applied at startup.
85+type configResolvedPerformance struct {
86+ SkiaCPUThreads int `json:"skia_cpu_threads"`
87+ SkiaGPUThreads int `json:"skia_gpu_threads"`
88+ WebProcessMemoryMB int `json:"web_process_memory_mb"`
89+ NetworkProcessMemoryMB int `json:"network_process_memory_mb"`
90+ WebViewPoolPrewarm int `json:"webview_pool_prewarm"`
91+ ConservativeThreshold float64 `json:"conservative_threshold"`
92+ StrictThreshold float64 `json:"strict_threshold"`
93+ KillThreshold float64 `json:"kill_threshold"`
8194 }
8295
8396 type configPayload struct {
@@ -143,6 +156,9 @@ func (h *DumbSchemeHandler) registerDefaults() {
143156 }
144157
145158 func buildConfigResponse(cfg *config.Config) *SchemeResponse {
159+ // Resolve performance profile to get actual values
160+ resolved := config.ResolvePerformanceProfile(&cfg.Performance)
161+
146162 resp := configPayload{
147163 DefaultUIScale: cfg.DefaultUIScale,
148164 DefaultSearchEngine: cfg.DefaultSearchEngine,
@@ -158,6 +174,16 @@ func buildConfigResponse(cfg *config.Config) *SchemeResponse {
158174 },
159175 Performance: configPerformancePayload{
160176 Profile: string(cfg.Performance.Profile),
177+ Resolved: configResolvedPerformance{
178+ SkiaCPUThreads: resolved.SkiaCPUPaintingThreads,
179+ SkiaGPUThreads: resolved.SkiaGPUPaintingThreads,
180+ WebProcessMemoryMB: resolved.WebProcessMemoryLimitMB,
181+ NetworkProcessMemoryMB: resolved.NetworkProcessMemoryLimitMB,
182+ WebViewPoolPrewarm: resolved.WebViewPoolPrewarmCount,
183+ ConservativeThreshold: resolved.WebProcessMemoryConservativeThreshold,
184+ StrictThreshold: resolved.WebProcessMemoryStrictThreshold,
185+ KillThreshold: resolved.WebProcessMemoryKillThreshold,
186+ },
161187 },
162188 }
163189
@@ -77,7 +77,20 @@ type configAppearancePayload struct {
77 }77 }
78 78
79 type configPerformancePayload struct {79 type configPerformancePayload struct {
80- Profile string `json:"profile"`80+ Profile string `json:"profile"`
81+ Resolved configResolvedPerformance `json:"resolved"`
82+}
83+
84+// configResolvedPerformance shows the actual values that will be applied at startup.
85+type configResolvedPerformance struct {
86+ SkiaCPUThreads int `json:"skia_cpu_threads"`
87+ SkiaGPUThreads int `json:"skia_gpu_threads"`
88+ WebProcessMemoryMB int `json:"web_process_memory_mb"`
89+ NetworkProcessMemoryMB int `json:"network_process_memory_mb"`
90+ WebViewPoolPrewarm int `json:"webview_pool_prewarm"`
91+ ConservativeThreshold float64 `json:"conservative_threshold"`
92+ StrictThreshold float64 `json:"strict_threshold"`
93+ KillThreshold float64 `json:"kill_threshold"`
81 }94 }
82 95
83 type configPayload struct {96 type configPayload struct {
@@ -143,6 +156,9 @@ func (h *DumbSchemeHandler) registerDefaults() {
143 }156 }
144 157
145 func buildConfigResponse(cfg *config.Config) *SchemeResponse {158 func buildConfigResponse(cfg *config.Config) *SchemeResponse {
159+ // Resolve performance profile to get actual values
160+ resolved := config.ResolvePerformanceProfile(&cfg.Performance)
161+
146 resp := configPayload{162 resp := configPayload{
147 DefaultUIScale: cfg.DefaultUIScale,163 DefaultUIScale: cfg.DefaultUIScale,
148 DefaultSearchEngine: cfg.DefaultSearchEngine,164 DefaultSearchEngine: cfg.DefaultSearchEngine,
@@ -158,6 +174,16 @@ func buildConfigResponse(cfg *config.Config) *SchemeResponse {
158 },174 },
159 Performance: configPerformancePayload{175 Performance: configPerformancePayload{
160 Profile: string(cfg.Performance.Profile),176 Profile: string(cfg.Performance.Profile),
177+ Resolved: configResolvedPerformance{
178+ SkiaCPUThreads: resolved.SkiaCPUPaintingThreads,
179+ SkiaGPUThreads: resolved.SkiaGPUPaintingThreads,
180+ WebProcessMemoryMB: resolved.WebProcessMemoryLimitMB,
181+ NetworkProcessMemoryMB: resolved.NetworkProcessMemoryLimitMB,
182+ WebViewPoolPrewarm: resolved.WebViewPoolPrewarmCount,
183+ ConservativeThreshold: resolved.WebProcessMemoryConservativeThreshold,
184+ StrictThreshold: resolved.WebProcessMemoryStrictThreshold,
185+ KillThreshold: resolved.WebProcessMemoryKillThreshold,
186+ },
161 },187 },
162 }188 }
163 189
M webui/src/pages/ConfigPage.svelte +47 -0
@@ -26,8 +26,20 @@
2626 description: string;
2727 };
2828
29+ type ResolvedPerformance = {
30+ skia_cpu_threads: number;
31+ skia_gpu_threads: number;
32+ web_process_memory_mb: number;
33+ network_process_memory_mb: number;
34+ webview_pool_prewarm: number;
35+ conservative_threshold: number;
36+ strict_threshold: number;
37+ kill_threshold: number;
38+ };
39+
2940 type PerformanceConfig = {
3041 profile: string;
42+ resolved: ResolvedPerformance;
3143 };
3244
3345 type ConfigDTO = {
@@ -439,6 +451,41 @@
439451 </p>
440452 </div>
441453 {/if}
454+
455+ <!-- Resolved values display -->
456+ {#if config.performance.resolved}
457+ <div class="space-y-3">
458+ <div class="text-sm font-semibold uppercase tracking-[0.2em] text-muted-foreground">
459+ Resolved Settings (applied on restart)
460+ </div>
461+ <div class="grid gap-3 rounded-md border border-border bg-muted/20 p-4 text-sm md:grid-cols-2">
462+ <div class="flex justify-between">
463+ <span class="text-muted-foreground">Skia CPU Threads</span>
464+ <span class="font-mono">{config.performance.resolved.skia_cpu_threads === 0 ? 'unset' : config.performance.resolved.skia_cpu_threads}</span>
465+ </div>
466+ <div class="flex justify-between">
467+ <span class="text-muted-foreground">Skia GPU Threads</span>
468+ <span class="font-mono">{config.performance.resolved.skia_gpu_threads === -1 ? 'unset' : config.performance.resolved.skia_gpu_threads}</span>
469+ </div>
470+ <div class="flex justify-between">
471+ <span class="text-muted-foreground">Web Process Memory</span>
472+ <span class="font-mono">{config.performance.resolved.web_process_memory_mb === 0 ? 'unset' : config.performance.resolved.web_process_memory_mb + ' MB'}</span>
473+ </div>
474+ <div class="flex justify-between">
475+ <span class="text-muted-foreground">Network Process Memory</span>
476+ <span class="font-mono">{config.performance.resolved.network_process_memory_mb === 0 ? 'unset' : config.performance.resolved.network_process_memory_mb + ' MB'}</span>
477+ </div>
478+ <div class="flex justify-between">
479+ <span class="text-muted-foreground">WebView Pool Prewarm</span>
480+ <span class="font-mono">{config.performance.resolved.webview_pool_prewarm}</span>
481+ </div>
482+ <div class="flex justify-between">
483+ <span class="text-muted-foreground">Memory Kill Threshold</span>
484+ <span class="font-mono">{config.performance.resolved.kill_threshold === -1 ? 'never' : (config.performance.resolved.kill_threshold * 100).toFixed(0) + '%'}</span>
485+ </div>
486+ </div>
487+ </div>
488+ {/if}
442489 </Card.Content>
443490 </Card.Root>
444491 </Tabs.Content>
@@ -26,8 +26,20 @@
26 description: string;26 description: string;
27 };27 };
28 28
29+ type ResolvedPerformance = {
30+ skia_cpu_threads: number;
31+ skia_gpu_threads: number;
32+ web_process_memory_mb: number;
33+ network_process_memory_mb: number;
34+ webview_pool_prewarm: number;
35+ conservative_threshold: number;
36+ strict_threshold: number;
37+ kill_threshold: number;
38+ };
39+
29 type PerformanceConfig = {40 type PerformanceConfig = {
30 profile: string;41 profile: string;
42+ resolved: ResolvedPerformance;
31 };43 };
32 44
33 type ConfigDTO = {45 type ConfigDTO = {
@@ -439,6 +451,41 @@
439 </p>451 </p>
440 </div>452 </div>
441 {/if}453 {/if}
454+
455+ <!-- Resolved values display -->
456+ {#if config.performance.resolved}
457+ <div class="space-y-3">
458+ <div class="text-sm font-semibold uppercase tracking-[0.2em] text-muted-foreground">
459+ Resolved Settings (applied on restart)
460+ </div>
461+ <div class="grid gap-3 rounded-md border border-border bg-muted/20 p-4 text-sm md:grid-cols-2">
462+ <div class="flex justify-between">
463+ <span class="text-muted-foreground">Skia CPU Threads</span>
464+ <span class="font-mono">{config.performance.resolved.skia_cpu_threads === 0 ? 'unset' : config.performance.resolved.skia_cpu_threads}</span>
465+ </div>
466+ <div class="flex justify-between">
467+ <span class="text-muted-foreground">Skia GPU Threads</span>
468+ <span class="font-mono">{config.performance.resolved.skia_gpu_threads === -1 ? 'unset' : config.performance.resolved.skia_gpu_threads}</span>
469+ </div>
470+ <div class="flex justify-between">
471+ <span class="text-muted-foreground">Web Process Memory</span>
472+ <span class="font-mono">{config.performance.resolved.web_process_memory_mb === 0 ? 'unset' : config.performance.resolved.web_process_memory_mb + ' MB'}</span>
473+ </div>
474+ <div class="flex justify-between">
475+ <span class="text-muted-foreground">Network Process Memory</span>
476+ <span class="font-mono">{config.performance.resolved.network_process_memory_mb === 0 ? 'unset' : config.performance.resolved.network_process_memory_mb + ' MB'}</span>
477+ </div>
478+ <div class="flex justify-between">
479+ <span class="text-muted-foreground">WebView Pool Prewarm</span>
480+ <span class="font-mono">{config.performance.resolved.webview_pool_prewarm}</span>
481+ </div>
482+ <div class="flex justify-between">
483+ <span class="text-muted-foreground">Memory Kill Threshold</span>
484+ <span class="font-mono">{config.performance.resolved.kill_threshold === -1 ? 'never' : (config.performance.resolved.kill_threshold * 100).toFixed(0) + '%'}</span>
485+ </div>
486+ </div>
487+ </div>
488+ {/if}
442 </Card.Content>489 </Card.Content>
443 </Card.Root>490 </Card.Root>
444 </Tabs.Content>491 </Tabs.Content>

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close