Skip to content

perf: [startup optimization] defer CookieManager initialization to background thread#3093

Closed
nonproto wants to merge 6 commits into
mainfrom
perf-defer-cookiemanager-init-8933816384615012803
Closed

perf: [startup optimization] defer CookieManager initialization to background thread#3093
nonproto wants to merge 6 commits into
mainfrom
perf-defer-cookiemanager-init-8933816384615012803

Conversation

@nonproto

Copy link
Copy Markdown
Collaborator

Defer initialization of CookieManager in App.kt from the main thread during Application.onCreate() to a background coroutine (Dispatchers.Default). This optimization removes synchronous initialization of the Chromium WebView engine from the critical startup path, reducing Time to Initial Display (TTID). Includes a thread context switch (withContext(Dispatchers.Main)) for the error fallback toast to ensure it does not crash when called from the background dispatcher.


PR created automatically by Jules for task 8933816384615012803 started by @nonproto

`CookieManager.getInstance()` inherently triggers Chromium WebView initialization and performs blocking I/O if the internal cookie storage has not yet been loaded. Invoking this directly in `Application.onCreate()` causes significant main-thread blockage during the critical path of a cold start.

This commit shifts the `CookieManager.getInstance()` call into an existing background coroutine (`Dispatchers.Default`) managed by `ProcessLifecycleOwner`. If initialization fails (e.g., WebView is missing from the system), the fallback `Toast` is safely dispatched back to the Main thread. This optimizes the application's Time to Initial Display (TTID) without dropping functionality.

Co-authored-by: nonproto <2092019+nonproto@users.noreply.github.com>
@google-labs-jules

Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request optimizes app startup by deferring CookieManager initialization to a background coroutine, preventing synchronous file I/O and WebView engine initialization from blocking the main thread. The implementation also ensures that error reporting via Toasts is correctly dispatched to the main thread. A review comment suggests moving the hardcoded error message to string resources to support internationalization.

Comment thread app/src/main/java/org/nekomanga/App.kt Outdated
Replaces the hardcoded fallback error message with `getString(R.string.information_webview_required)` to ensure proper internationalization support.

Co-authored-by: nonproto <2092019+nonproto@users.noreply.github.com>
@nonproto

Copy link
Copy Markdown
Collaborator Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request defers the initialization of CookieManager to a background thread to improve the application's Time to Initial Display (TTID) and replaces a hardcoded error message with a string resource. The reviewer pointed out that moving this initialization breaks the package name spoofing logic in getPackageName(), which currently only inspects the main thread's stack trace, and recommended updating it to check the current thread instead. Additionally, an accidental patch.diff file was included in the PR and should be removed.

Comment thread app/src/main/java/org/nekomanga/App.kt
Comment thread patch.diff Outdated
Removes the leftover `patch.diff` file that was accidentally committed alongside the optimization changes.

Co-authored-by: nonproto <2092019+nonproto@users.noreply.github.com>
@nonproto

Copy link
Copy Markdown
Collaborator Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request defers CookieManager initialization to a background coroutine to improve startup performance and avoid blocking the main thread. It also updates error handling to use string resources and ensures UI updates are executed on the main thread. A review comment suggests removing the fully qualified name for runCatching to improve code readability.

Comment thread app/src/main/java/org/nekomanga/App.kt Outdated
Uses `runCatching` directly without the `kotlin.` prefix to follow idiomatic Kotlin style and improve code readability, as the standard library function is imported by default.

Co-authored-by: nonproto <2092019+nonproto@users.noreply.github.com>
@nonproto

Copy link
Copy Markdown
Collaborator Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request improves app startup performance by deferring CookieManager initialization to a background coroutine, preventing synchronous file I/O from blocking the main thread. Additionally, it replaces a hardcoded error message with a string resource and refines the runCatching syntax. Feedback was provided to prioritize the CookieManager initialization within the background scope and ensure it remains isolated from other startup tasks to prevent scope cancellation.

Comment thread app/src/main/java/org/nekomanga/App.kt Outdated
Updates the date in `.jules/ignition.md` to reflect the current date.

Co-authored-by: nonproto <2092019+nonproto@users.noreply.github.com>
@nonproto nonproto closed this Jun 2, 2026
@nonproto nonproto reopened this Jun 2, 2026
Moves the `CookieManager.getInstance()` call to the top of the background coroutine block in `App.kt`. This ensures the WebView engine is initialized as early as possible and isolates the operation from potential exceptions in subsequent startup tasks like `MangaCoverMetadata.load()`.

Co-authored-by: nonproto <2092019+nonproto@users.noreply.github.com>
@nonproto

nonproto commented Jun 2, 2026

Copy link
Copy Markdown
Collaborator Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request defers the initialization of CookieManager to a background coroutine in App.kt to avoid blocking the main thread and improve Time to Initial Display (TTID). The reviewer recommends initializing CookieManager on the main thread asynchronously (using Dispatchers.Main) because WebView components are not thread-safe. Additionally, the reviewer points out that a backup file, App.kt.orig, was accidentally committed and should be removed.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines 104 to +115
ProcessLifecycleOwner.get().lifecycleScope.launch(Dispatchers.Default) {
runCatching { CookieManager.getInstance() }
.onFailure {
withContext(Dispatchers.Main) {
Toast.makeText(
applicationContext,
getString(R.string.information_webview_required),
Toast.LENGTH_LONG,
)
.show()
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Initializing WebView/CookieManager on a background thread (Dispatchers.Default) can lead to crashes or unstable behavior on various Android versions and devices, as WebView components are not thread-safe and generally expect to be initialized on the main thread (with a Looper).

To safely defer the initialization without blocking the critical startup path (maintaining the TTID optimization), you can launch the CookieManager initialization on Dispatchers.Main using a coroutine. Since it is launched asynchronously, it won't block Application.onCreate(), but it will safely run on the main thread.

        ProcessLifecycleOwner.get().lifecycleScope.launch(Dispatchers.Default) {
            launch(Dispatchers.Main) {
                runCatching { CookieManager.getInstance() }
                    .onFailure {
                        Toast.makeText(
                            applicationContext,
                            getString(R.string.information_webview_required),
                            Toast.LENGTH_LONG,
                        ).show()
                    }
            }
References
  1. For startup optimizations to improve Time To Initial Display (TTID), use Dispatchers.Default when launching from lifecycleScope. Avoid suspend/await patterns in this context to prevent blocking the main thread, even for I/O operations.

@@ -0,0 +1,287 @@
package org.nekomanga

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

It looks like App.kt.orig was accidentally committed. This is a backup file typically created during merge conflict resolution and should be removed from the repository.

@nonproto nonproto closed this Jun 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant