View Ticket
Not logged in
Ticket Hash: 2a6347f721d611a848110c47177a555e2e89243f
Title: Hex preview is slow for larger files
Status: Review Type: Feature Request
Severity: Important Priority: Medium
Subsystem: ZPreview.net Resolution: Open
Last Modified: 2026-04-29 11:17:47
83.3 minutes ago
Created: 2026-04-29 09:26:13
3.2 hours ago
Version Found In: 47b3fd1c81
User Comments:
tinus added on 2026-04-29 09:26:13:

Rendering seems very slow when viewing even moderately large files (>=10 MB).

Noticeable when:

  • Showing/hiding the inspector panel
  • Scrolling
  • Selecting

github-copilot/gpt-5.4 (claiming to be tinus) added on 2026-04-29 10:11:26:

Analysis summary:

  • Most likely causes are synchronous inspector work on every selection change, resize-triggered reloads when toggling the inspector while BytesPerLine is auto, and synchronous window reloads from the paint path while scrolling.
  • Additional cost likely comes from per-byte rendering and formatting inside OnPaint().
  • Highest-value fix directions are to limit inspector processing to a small prefix of the selection, avoid rereading file data on resize-only layout changes, and move window reloads out of the paint path.

github-copilot/gpt-5.4 (claiming to be tinus) added on 2026-04-29 10:11:26:

Proposed implementation order:

  • Add small logic tests around inspector sampling so we can cap the inspected byte slice without losing the fixed-width interpretations currently shown.
  • Change the inspector update path to pass both total selection length and a sampled prefix, capped at 32 bytes. That still covers the current fixed-width types, including Guid, Decimal, and SYSTEMTIME.
  • Add a small debounce of about 250 ms for selection updates during mouse dragging, with an immediate refresh on mouse-up.
  • Change resize handling so auto BytesPerLine recalculation updates layout without reopening the file or rereading the window unnecessarily.
  • Move window reloads out of OnPaint() and trigger them from scroll or cursor movement before invalidation.
  • Reassess scrolling cost afterward, and only then do a smaller paint-path cleanup if it is still needed.

github-copilot/gpt-5.4 (claiming to be tinus) added on 2026-04-29 10:50:47:

Updated implementation order after additional repro details:

  • The new observations strongly suggest that the main lag is not primarily the inspector. With the inspector hidden, a 24-byte selection still takes about 3 seconds to move, and End moves the scrollbar immediately but takes more than 2 seconds to repaint the content.
  • That makes the first priority removing synchronous window reloads and other expensive work from OnPaint(). The current paint path appears to be able to trigger window reloads while rendering bytes near or beyond the current window margin.
  • First step: add focused tests around the window reload decision logic, especially near the end of large files, so we can safely stop reloads from happening during paint.
  • Second step: move window loading to scroll and cursor movement paths, and ensure a single user action can cause at most one window reload before invalidation.
  • Third step: remeasure End, click-to-reposition, and scrolling on a large local file with the inspector hidden.
  • Fourth step: if repaint cost is still too high, reduce paint-path overhead with cheaper byte-to-hex and byte-to-ASCII formatting and less per-byte rendering churn.
  • Fifth step: apply the inspector-specific optimizations afterward: cap sampled selection bytes to 32 unless a displayed fixed-width interpretation needs more, and debounce drag-selection updates by about 250 ms with an immediate refresh on mouse-up.
  • Sixth step: reassess whether any DataGridView churn remains significant once the main paint-path issue is fixed.

github-copilot/gpt-5.4 (claiming to be tinus) added on 2026-04-29 11:08:18:

Starting implementation on a dedicated branch from develop. First step is removing window reloads from the paint path and adding focused regression tests around large-file window behavior.


github-copilot/gpt-5.4 (claiming to be tinus) added on 2026-04-29 11:12:00:

Step 1 implemented locally: the hex preview no longer reloads file windows from OnPaint(). The viewport now ensures the needed window is loaded before invalidation, and focused logic tests were added for viewport-based reload decisions near the end of large files. Build succeeded. Runtime test execution is still blocked on Linux because Microsoft.WindowsDesktop.App is not available.


github-copilot/gpt-5.4 (claiming to be tinus) added on 2026-04-29 11:17:13:

Step 2 implemented locally: reduced per-byte paint overhead by caching hex and ASCII byte text, limited inspector sampling to 32 bytes while preserving the full reported selection length, and debounced inspector refreshes during drag selection with an immediate refresh on mouse-up. The same inspector update behavior was applied to the SQLite blob viewer. Build succeeded. Runtime execution is still not available on this Linux host because Microsoft.WindowsDesktop.App is missing.


github-copilot/gpt-5.4 (claiming to be tinus) added on 2026-04-29 11:17:47:

Implemented on branch t2a6347f721-hex-preview-performance in fee3ca2325 and 795bfd2b42. The changes remove window reloads from the hex paint path, reduce per-byte repaint overhead, and limit/debounce inspector updates in both the main hex preview and the SQLite blob viewer. I could build the affected projects and test assemblies, but I could not run the WinForms runtime behavior on this Linux host because Microsoft.WindowsDesktop.App is unavailable, so leaving this in Review for Windows-side verification.