detached bea4eff

perf(webkit): enable page cache and smooth scrolling for faster page transitions

commit
bea4eff521de2ddec97702ffdc80da6ffd622293
author
bnema · · 2025-10-23 22:06 UTC
committer
bnema · · 2025-10-24 17:33 UTC
parent
d5280cf
signature
unsigned
3 files · +64 -21
M internal/app/browser/webview.go +13 -11
@@ -43,17 +43,19 @@ func (app *BrowserApp) buildWebkitConfig() (*webkit.Config, error) {
4343
4444 // Build WebKit configuration with data directories for persistence
4545 cfg := &webkit.Config{
46- UserAgent: buildUserAgent(app.config),
47- EnableJavaScript: true,
48- EnableWebGL: true,
49- EnableMediaStream: true,
50- HardwareAcceleration: true,
51- DefaultFontSize: app.config.Appearance.DefaultFontSize,
52- MinimumFontSize: 8,
53- DataDir: webkitData,
54- CacheDir: webkitCache,
55- AppearanceConfigJSON: app.buildAppearanceConfigJSON(),
56- CreateWindow: true, // Default to creating a window for standalone WebViews
46+ UserAgent: buildUserAgent(app.config),
47+ EnableJavaScript: true,
48+ EnableWebGL: true,
49+ EnableMediaStream: true,
50+ HardwareAcceleration: true,
51+ DefaultFontSize: app.config.Appearance.DefaultFontSize,
52+ MinimumFontSize: 8,
53+ EnablePageCache: true, // Instant back/forward navigation (bfcache)
54+ EnableSmoothScrolling: true, // Smooth scrolling animations
55+ DataDir: webkitData,
56+ CacheDir: webkitCache,
57+ AppearanceConfigJSON: app.buildAppearanceConfigJSON(),
58+ CreateWindow: true, // Default to creating a window for standalone WebViews
5759 }
5860
5961 return cfg, nil
@@ -43,17 +43,19 @@ func (app *BrowserApp) buildWebkitConfig() (*webkit.Config, error) {
43 43
44 // Build WebKit configuration with data directories for persistence44 // Build WebKit configuration with data directories for persistence
45 cfg := &webkit.Config{45 cfg := &webkit.Config{
46- UserAgent: buildUserAgent(app.config),46+ UserAgent: buildUserAgent(app.config),
47- EnableJavaScript: true,47+ EnableJavaScript: true,
48- EnableWebGL: true,48+ EnableWebGL: true,
49- EnableMediaStream: true,49+ EnableMediaStream: true,
50- HardwareAcceleration: true,50+ HardwareAcceleration: true,
51- DefaultFontSize: app.config.Appearance.DefaultFontSize,51+ DefaultFontSize: app.config.Appearance.DefaultFontSize,
52- MinimumFontSize: 8,52+ MinimumFontSize: 8,
53- DataDir: webkitData,53+ EnablePageCache: true, // Instant back/forward navigation (bfcache)
54- CacheDir: webkitCache,54+ EnableSmoothScrolling: true, // Smooth scrolling animations
55- AppearanceConfigJSON: app.buildAppearanceConfigJSON(),55+ DataDir: webkitData,
56- CreateWindow: true, // Default to creating a window for standalone WebViews56+ CacheDir: webkitCache,
57+ AppearanceConfigJSON: app.buildAppearanceConfigJSON(),
58+ CreateWindow: true, // Default to creating a window for standalone WebViews
57 }59 }
58 60
59 return cfg, nil61 return cfg, nil
M pkg/webkit/types.go +17 -8
@@ -45,6 +45,13 @@ type Config struct {
4545 // MinimumFontSize in pixels
4646 MinimumFontSize int
4747
48+ // Performance optimizations
49+ // EnablePageCache enables back/forward cache for instant navigation
50+ EnablePageCache bool
51+
52+ // EnableSmoothScrolling enables smooth scrolling animations
53+ EnableSmoothScrolling bool
54+
4855 // DataDir is the directory for persistent data (cookies, localStorage, etc.)
4956 DataDir string
5057
@@ -63,13 +70,15 @@ type Config struct {
6370 // GetDefaultConfig returns a Config with sensible defaults
6471 func GetDefaultConfig() *Config {
6572 return &Config{
66- UserAgent: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36",
67- EnableJavaScript: true,
68- EnableWebGL: true,
69- EnableMediaStream: true,
70- HardwareAcceleration: true,
71- DefaultFontSize: 16,
72- MinimumFontSize: 8,
73- CreateWindow: true, // Default to standalone window
73+ UserAgent: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36",
74+ EnableJavaScript: true,
75+ EnableWebGL: true,
76+ EnableMediaStream: true,
77+ HardwareAcceleration: true,
78+ DefaultFontSize: 16,
79+ MinimumFontSize: 8,
80+ EnablePageCache: true, // Instant back/forward navigation
81+ EnableSmoothScrolling: true, // Better UX
82+ CreateWindow: true, // Default to standalone window
7483 }
7584 }
@@ -45,6 +45,13 @@ type Config struct {
45 // MinimumFontSize in pixels45 // MinimumFontSize in pixels
46 MinimumFontSize int46 MinimumFontSize int
47 47
48+ // Performance optimizations
49+ // EnablePageCache enables back/forward cache for instant navigation
50+ EnablePageCache bool
51+
52+ // EnableSmoothScrolling enables smooth scrolling animations
53+ EnableSmoothScrolling bool
54+
48 // DataDir is the directory for persistent data (cookies, localStorage, etc.)55 // DataDir is the directory for persistent data (cookies, localStorage, etc.)
49 DataDir string56 DataDir string
50 57
@@ -63,13 +70,15 @@ type Config struct {
63 // GetDefaultConfig returns a Config with sensible defaults70 // GetDefaultConfig returns a Config with sensible defaults
64 func GetDefaultConfig() *Config {71 func GetDefaultConfig() *Config {
65 return &Config{72 return &Config{
66- UserAgent: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36",73+ UserAgent: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36",
67- EnableJavaScript: true,74+ EnableJavaScript: true,
68- EnableWebGL: true,75+ EnableWebGL: true,
69- EnableMediaStream: true,76+ EnableMediaStream: true,
70- HardwareAcceleration: true,77+ HardwareAcceleration: true,
71- DefaultFontSize: 16,78+ DefaultFontSize: 16,
72- MinimumFontSize: 8,79+ MinimumFontSize: 8,
73- CreateWindow: true, // Default to standalone window80+ EnablePageCache: true, // Instant back/forward navigation
81+ EnableSmoothScrolling: true, // Better UX
82+ CreateWindow: true, // Default to standalone window
74 }83 }
75 }84 }
M pkg/webkit/webview.go +34 -2
@@ -46,6 +46,9 @@ type WebView struct {
4646 onWorkspaceNavigation func(direction string) bool // Workspace pane navigation
4747 onPaneModeShortcut func(action string) bool // Pane mode shortcuts (enter, actions, exit)
4848 isPaneModeActive func() bool // Check if pane mode is active
49+ onLoadStarted func() // Load started event
50+ onLoadCommitted func() // Load committed event (DOM available)
51+ onLoadFinished func() // Load finished event
4952 }
5053
5154 // NewWebView creates a new WebView with the given configuration
@@ -197,6 +200,13 @@ func (w *WebView) applyConfig() error {
197200 // Enable hardware acceleration if configured
198201 settings.SetHardwareAccelerationPolicy(webkit.HardwareAccelerationPolicyAlways)
199202
203+ // Performance optimizations for faster page transitions
204+ // Enable page cache for instant back/forward navigation (bfcache)
205+ settings.SetEnablePageCache(w.config.EnablePageCache)
206+
207+ // Enable smooth scrolling for better UX
208+ settings.SetEnableSmoothScrolling(w.config.EnableSmoothScrolling)
209+
200210 return nil
201211 }
202212
@@ -229,9 +239,31 @@ func (w *WebView) setupEventHandlers() {
229239 // Favicon changed - connect to FaviconDatabase
230240 w.setupFaviconHandlers()
231241
232- // Load changed
242+ // Load changed - track page lifecycle for performance monitoring
233243 w.view.ConnectLoadChanged(func(event webkit.LoadEvent) {
234- // Handle load events if needed
244+ // Avoid calling callbacks if WebView is being destroyed to prevent reference cycles
245+ // especially important when page cache is enabled
246+ if w.IsDestroyed() {
247+ return
248+ }
249+
250+ switch event {
251+ case webkit.LoadStarted:
252+ // Page load started - could show loading indicator
253+ if w.onLoadStarted != nil {
254+ w.onLoadStarted()
255+ }
256+ case webkit.LoadCommitted:
257+ // Page committed - DOM is now available for interaction
258+ if w.onLoadCommitted != nil {
259+ w.onLoadCommitted()
260+ }
261+ case webkit.LoadFinished:
262+ // Page fully loaded - all resources downloaded
263+ if w.onLoadFinished != nil {
264+ w.onLoadFinished()
265+ }
266+ }
235267 })
236268
237269 // TLS error handling - connect to load-failed-with-tls-errors signal
@@ -46,6 +46,9 @@ type WebView struct {
46 onWorkspaceNavigation func(direction string) bool // Workspace pane navigation46 onWorkspaceNavigation func(direction string) bool // Workspace pane navigation
47 onPaneModeShortcut func(action string) bool // Pane mode shortcuts (enter, actions, exit)47 onPaneModeShortcut func(action string) bool // Pane mode shortcuts (enter, actions, exit)
48 isPaneModeActive func() bool // Check if pane mode is active48 isPaneModeActive func() bool // Check if pane mode is active
49+ onLoadStarted func() // Load started event
50+ onLoadCommitted func() // Load committed event (DOM available)
51+ onLoadFinished func() // Load finished event
49 }52 }
50 53
51 // NewWebView creates a new WebView with the given configuration54 // NewWebView creates a new WebView with the given configuration
@@ -197,6 +200,13 @@ func (w *WebView) applyConfig() error {
197 // Enable hardware acceleration if configured200 // Enable hardware acceleration if configured
198 settings.SetHardwareAccelerationPolicy(webkit.HardwareAccelerationPolicyAlways)201 settings.SetHardwareAccelerationPolicy(webkit.HardwareAccelerationPolicyAlways)
199 202
203+ // Performance optimizations for faster page transitions
204+ // Enable page cache for instant back/forward navigation (bfcache)
205+ settings.SetEnablePageCache(w.config.EnablePageCache)
206+
207+ // Enable smooth scrolling for better UX
208+ settings.SetEnableSmoothScrolling(w.config.EnableSmoothScrolling)
209+
200 return nil210 return nil
201 }211 }
202 212
@@ -229,9 +239,31 @@ func (w *WebView) setupEventHandlers() {
229 // Favicon changed - connect to FaviconDatabase239 // Favicon changed - connect to FaviconDatabase
230 w.setupFaviconHandlers()240 w.setupFaviconHandlers()
231 241
232- // Load changed242+ // Load changed - track page lifecycle for performance monitoring
233 w.view.ConnectLoadChanged(func(event webkit.LoadEvent) {243 w.view.ConnectLoadChanged(func(event webkit.LoadEvent) {
234- // Handle load events if needed244+ // Avoid calling callbacks if WebView is being destroyed to prevent reference cycles
245+ // especially important when page cache is enabled
246+ if w.IsDestroyed() {
247+ return
248+ }
249+
250+ switch event {
251+ case webkit.LoadStarted:
252+ // Page load started - could show loading indicator
253+ if w.onLoadStarted != nil {
254+ w.onLoadStarted()
255+ }
256+ case webkit.LoadCommitted:
257+ // Page committed - DOM is now available for interaction
258+ if w.onLoadCommitted != nil {
259+ w.onLoadCommitted()
260+ }
261+ case webkit.LoadFinished:
262+ // Page fully loaded - all resources downloaded
263+ if w.onLoadFinished != nil {
264+ w.onLoadFinished()
265+ }
266+ }
235 })267 })
236 268
237 // TLS error handling - connect to load-failed-with-tls-errors signal269 // TLS error handling - connect to load-failed-with-tls-errors signal

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