fix: chunk large JCEF messages to prevent JetBrains sidebar freezes#11899
Merged
Patrick-Erichsen merged 8 commits intomainfrom Mar 26, 2026
Merged
fix: chunk large JCEF messages to prevent JetBrains sidebar freezes#11899Patrick-Erichsen merged 8 commits intomainfrom
Patrick-Erichsen merged 8 commits intomainfrom
Conversation
When session data exceeds ~1MB (e.g. long conversations with many context items), sendToWebview embeds the entire JSON payload in a single executeJavaScript call. JCEF's JS parser/compiler cannot handle source strings that large and freezes the IDE. This adds a chunked sending path: payloads over 1MB are base64-encoded, split into 512KB chunks sent as individual executeJavaScript calls that each append to a buffer variable, then a final call decodes and dispatches the reassembled message via window.postMessage. Each individual call is trivial for JCEF to parse, and V8 handles the string concatenation and final JSON.parse without issue. Messages under 1MB (the vast majority) take the existing fast path unchanged.
Contributor
|
Docs Review: No documentation updates needed. This PR is an internal bug fix to the JetBrains extension's JCEF message handling. The chunking mechanism is:
The existing docs accurately describe using Continue in JetBrains — they don't need to explain internal message transport mechanisms. |
Contributor
There was a problem hiding this comment.
1 issue found across 1 file
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/browser/ContinueBrowser.kt">
<violation number="1" location="extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/browser/ContinueBrowser.kt:92">
P2: Escape or serialize messageId before embedding it into JavaScript string literals. As written, a messageId containing quotes/backslashes will break the generated JS (or allow injection) in the chunked path.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
.../src/main/kotlin/com/github/continuedev/continueintellijextension/browser/ContinueBrowser.kt
Show resolved
Hide resolved
Replaces O(n²) string concatenation (+=) with O(n) array push + join for JS-side chunk buffering. Extracts script generation into testable buildChunkScripts() and adds unit tests for chunking logic.
Reduces IPC round-trips by 4x (e.g. 7 calls instead of 26 for 10MB). Safe because chunks are trivial JS with pure Base64 string literals.
atob() returns Latin-1, so multi-byte UTF-8 characters (em dashes, accented letters, CJK, emoji) were mangled. Use TextDecoder to properly decode UTF-8 bytes after base64 decoding.
This was referenced Mar 26, 2026
Patrick-Erichsen
previously approved these changes
Mar 26, 2026
Patrick-Erichsen
approved these changes
Mar 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
sendToWebviewis called with a large payload (e.g. loading a long conversation session), the entire JSON is embedded in a singleexecuteJavaScript("window.postMessage(<huge JSON>, '*')")call. JCEF's JS source parser/compiler cannot handle multi-megabyte source strings and freezes the IDE.executeJavaScriptcalls that each push to an array buffer, then one final small call joins, decodes, and dispatches the complete message viawindow.postMessage.How the chunking works
JCEF never sees partial JSON. Each
executeJavaScriptcall just pushes a base64 string fragment to an array (buffer.push("abc123...")). No JSON parsing happens until the very last call, which runsJSON.parse(atob(buffer.join("")))on the reassembled complete string. The freeze was caused by JCEF having to compile a massive JS source string, not by V8 processing the data — so keeping each source string small (~2MB) avoids the freeze entirely.Array push+join is used instead of string concatenation to keep reassembly O(n) instead of O(n²). The chunk generation logic is extracted into a testable
buildChunkScripts()function with unit tests.Related issues
Fixes the large-session-file variant of the JCEF freeze reported across multiple issues:
Test plan
./gradlew test --tests "*.ContinueBrowserChunkTest"— all 7 unit tests pass