feat: Enhance response viewer behavior when receives large response content#9740
feat: Enhance response viewer behavior when receives large response content#9740
Conversation
There was a problem hiding this comment.
Pull request overview
This PR improves UI responsiveness when rendering very large response bodies by truncating extremely long individual lines in read-only CodeMirror viewers and providing an inline control to expand them on demand.
Changes:
- Adds a
truncateLongLinesprop toCodeEditorand enables it for response viewers and MCP event preview. - Implements long-line truncation (>10,000 chars) with an inline “Show full value” bookmark widget to restore the full line.
- Tweaks CodeMirror configuration with
maxHighlightLengthto reduce highlight work on long lines.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| packages/insomnia/src/ui/components/viewers/response-viewer.tsx | Enables long-line truncation for JSON/source response viewing. |
| packages/insomnia/src/ui/components/mcp/event-view.tsx | Enables long-line truncation for MCP message previews. |
| packages/insomnia/src/ui/components/.client/codemirror/code-editor.tsx | Adds truncation implementation + new prop; adjusts CodeMirror options. |
Comments suppressed due to low confidence (1)
packages/insomnia/src/ui/components/.client/codemirror/code-editor.tsx:773
useImperativeHandleis created with an empty dependency array, but the exposedsetValuenow depends onshouldTruncateLongLines(derived from props). IfreadOnly/truncateLongLineschanges for an existing mounted editor, the imperativesetValuewill keep using the initial value and behave incorrectly. IncludeshouldTruncateLongLines(and any other referenced values) in the dependency array, or wrap it via a ref (e.g.useLatest) to avoid stale closures.
useImperativeHandle(
ref,
() => ({
setValue: value =>
shouldTruncateLongLines
? setEditorValueWithTruncation(codeMirror.current, value)
: codeMirror.current?.setValue(value || ''),
getValue: () => codeMirror.current?.getValue() || '',
selectAll: () =>
codeMirror.current?.setSelection({ line: 0, ch: 0 }, { line: codeMirror.current.lineCount(), ch: 0 }),
focus: () => codeMirror.current?.focus(),
scrollToSelection: (chStart: number, chEnd: number, lineStart: number, lineEnd: number) => {
codeMirror.current?.setSelection({ line: lineStart, ch: chStart }, { line: lineEnd, ch: chEnd });
// If sizing permits, position selection just above center
codeMirror.current?.scrollIntoView({ line: lineStart, ch: chStart }, window.innerHeight / 2 - 100);
},
focusEnd: () => {
if (codeMirror.current && !codeMirror.current.hasFocus()) {
codeMirror.current.focus();
}
codeMirror.current?.getDoc()?.setCursor(codeMirror.current.getDoc().lineCount(), 0);
},
getCursor: () => {
return codeMirror.current?.getCursor();
},
setCursorLine: (lineNumber: number) => {
codeMirror.current?.setCursor(lineNumber);
},
tryToSetOption,
hasFocus: () => codeMirror.current?.hasFocus() as boolean,
indexFromPos: (pos?: CodeMirror.Position) => (pos ? codeMirror.current?.indexFromPos(pos) || 0 : 0),
getDoc: () => codeMirror.current?.getDoc(),
}),
[],
);
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
packages/insomnia/src/ui/components/.client/codemirror/code-editor.tsx
Outdated
Show resolved
Hide resolved
packages/insomnia/src/ui/components/.client/codemirror/code-editor.tsx
Outdated
Show resolved
Hide resolved
✅ Circular References ReportGenerated at: 2026-03-26T06:59:49.131Z Summary
Click to view all circular references in PR (71)Click to view all circular references in base branch (71)Analysis✅ No Change: This PR does not introduce or remove any circular references. This report was generated automatically by comparing against the |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (1)
packages/insomnia/src/ui/components/.client/codemirror/code-editor.tsx:777
useImperativeHandleis created with an empty dependency array, but thesetValueimplementation now depends onshouldTruncateLongLines. IfreadOnly/truncateLongLineschanges after mount, the exposedsetValuewill keep using the initial value and may not truncate when it should (or vice versa). Consider either removing the deps array (recompute each render) or includingshouldTruncateLongLines(and any other referenced values you expect to vary) in the deps list.
useImperativeHandle(
ref,
() => ({
setValue: value =>
shouldTruncateLongLines
? setEditorValueWithTruncation(codeMirror.current, value)
: codeMirror.current?.setValue(value || ''),
getValue: () => codeMirror.current?.getValue() || '',
selectAll: () =>
codeMirror.current?.setSelection({ line: 0, ch: 0 }, { line: codeMirror.current.lineCount(), ch: 0 }),
focus: () => codeMirror.current?.focus(),
scrollToSelection: (chStart: number, chEnd: number, lineStart: number, lineEnd: number) => {
codeMirror.current?.setSelection({ line: lineStart, ch: chStart }, { line: lineEnd, ch: chEnd });
// If sizing permits, position selection just above center
codeMirror.current?.scrollIntoView({ line: lineStart, ch: chStart }, window.innerHeight / 2 - 100);
},
focusEnd: () => {
if (codeMirror.current && !codeMirror.current.hasFocus()) {
codeMirror.current.focus();
}
codeMirror.current?.getDoc()?.setCursor(codeMirror.current.getDoc().lineCount(), 0);
},
getCursor: () => {
return codeMirror.current?.getCursor();
},
setCursorLine: (lineNumber: number) => {
codeMirror.current?.setCursor(lineNumber);
},
tryToSetOption,
hasFocus: () => codeMirror.current?.hasFocus() as boolean,
indexFromPos: (pos?: CodeMirror.Position) => (pos ? codeMirror.current?.indexFromPos(pos) || 0 : 0),
getDoc: () => codeMirror.current?.getDoc(),
}),
[],
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
...ation.$organizationId.project.$projectId.workspace.$workspaceId.debug.request.$requestId.tsx
Outdated
Show resolved
Hide resolved
packages/insomnia/src/ui/components/.client/codemirror/code-editor.tsx
Outdated
Show resolved
Hide resolved
packages/insomnia/src/ui/components/.client/codemirror/code-editor.tsx
Outdated
Show resolved
Hide resolved
437fac0 to
93d7869
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| } | ||
| placeholder="..." | ||
| readOnly | ||
| truncateLongLines |
There was a problem hiding this comment.
truncateLongLines is enabled for the JSON-friendly and source viewers, but the PREVIEW_MODE_RAW path still renders a read-only CodeEditor without this flag. If the hang happens in raw view (common for large/minified payloads), the performance issue may persist there; consider enabling truncateLongLines for the raw viewer too (or handling it at a shared wrapper level).
Background:
When viewing a large API response (eg: MCP app resources contains the entire DOM tree), the response editor would hang or become unresponsive on load due to CodeMirror performance issue.
Changes:
INS-2250