diff --git a/ios/Platform/Platform/Features/Reader/Views/ArticleWebView.swift b/ios/Platform/Platform/Features/Reader/Views/ArticleWebView.swift
index 79da55b..bdde9cf 100644
--- a/ios/Platform/Platform/Features/Reader/Views/ArticleWebView.swift
+++ b/ios/Platform/Platform/Features/Reader/Views/ArticleWebView.swift
@@ -8,6 +8,7 @@ final class ArticleRenderer {
static let shared = ArticleRenderer()
let webView: WKWebView
+ private var lastWarmTime: CFAbsoluteTime = 0
private init() {
let config = WKWebViewConfiguration()
@@ -38,11 +39,11 @@ final class ArticleRenderer {
"""
), baseURL: nil)
+ lastWarmTime = CFAbsoluteTimeGetCurrent()
}
/// Attach WKWebView to the app window (invisible) to force GPU process
- /// launch. Must be called after window is available. Keeps the webview
- /// attached — it will be moved to the article container on first use.
+ /// launch. Must be called after window is available.
func attachToWindow() {
guard webView.window == nil,
let window = UIApplication.shared.connectedScenes
@@ -51,10 +52,22 @@ final class ArticleRenderer {
webView.alpha = 0
window.addSubview(webView)
+ }
- // Keep attached (don't remove) so GPU process stays alive.
- // The webview will be reparented to the article container
- // via removeFromSuperview + addSubview in makeUIView.
+ /// Re-warm if the GPU process may have exited due to idle timeout.
+ /// Lightweight: only fires if >60s since last warm, and just reloads
+ /// a tiny HTML page + re-attaches to window if needed.
+ func reWarmIfNeeded() {
+ let elapsed = CFAbsoluteTimeGetCurrent() - lastWarmTime
+ guard elapsed > 60 else { return }
+
+ attachToWindow()
+ webView.loadHTMLString(
+ "
warm
", + baseURL: nil + ) + lastWarmTime = CFAbsoluteTimeGetCurrent() } } diff --git a/ios/Platform/Platform/Features/Reader/Views/ReaderTabView.swift b/ios/Platform/Platform/Features/Reader/Views/ReaderTabView.swift index ca0cf40..848e163 100644 --- a/ios/Platform/Platform/Features/Reader/Views/ReaderTabView.swift +++ b/ios/Platform/Platform/Features/Reader/Views/ReaderTabView.swift @@ -139,6 +139,9 @@ struct ReaderTabView: View { FeedManagementSheet(vm: vm) } } + .onAppear { + ArticleRenderer.shared.reWarmIfNeeded() + } } private var subTabs: [String] { ["Unread", "Starred", "All"] }