Maintain a queue of "prepared" web views for use in DetailWebViewController.
WKWebView has an awful behavior of a flash to white on first load when in dark mode. Keep a queue of WebViews where we've already done a trivial load so that by the time we need them in the UI, they're past the flash-to-shite part of their lifecycle.
This commit is contained in:
parent
a5b2c759ec
commit
f7b53283d6
|
@ -237,6 +237,9 @@ class AppCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
|
|||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(userDefaultsDidChange(_:)), name: UserDefaults.didChangeNotification, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(accountDidDownloadArticles(_:)), name: .AccountDidDownloadArticles, object: nil)
|
||||
|
||||
// Force lazy initialization of the web view provider so that it can warm up the queue of prepared web views
|
||||
let _ = DetailViewControllerWebViewProvider.shared
|
||||
}
|
||||
|
||||
func start() -> UIViewController {
|
||||
|
|
|
@ -26,10 +26,16 @@ class DetailViewController: UIViewController {
|
|||
|
||||
weak var coordinator: AppCoordinator!
|
||||
|
||||
deinit {
|
||||
webView.removeFromSuperview()
|
||||
DetailViewControllerWebViewProvider.shared.enqueueWebView(webView)
|
||||
webView = nil
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
webView = WKWebView(frame: webViewContainer.bounds)
|
||||
webView = DetailViewControllerWebViewProvider.shared.dequeueWebView()
|
||||
webView.translatesAutoresizingMaskIntoConstraints = false
|
||||
webView.navigationDelegate = self
|
||||
|
||||
|
@ -237,3 +243,48 @@ private extension DetailViewController {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
/// WKWebView has an awful behavior of a flash to white on first load when in dark mode.
|
||||
/// Keep a queue of WebViews where we've already done a trivial load so that by the time we need them in the UI, they're past the flash-to-shite part of their lifecycle.
|
||||
class DetailViewControllerWebViewProvider {
|
||||
static var shared = DetailViewControllerWebViewProvider()
|
||||
|
||||
func dequeueWebView() -> WKWebView {
|
||||
if let webView = queue.popLast() {
|
||||
replenishQueueIfNeeded()
|
||||
return webView
|
||||
}
|
||||
|
||||
assertionFailure("Creating WKWebView in \(#function); queue has run dry.")
|
||||
let webView = WKWebView(frame: .zero)
|
||||
return webView
|
||||
}
|
||||
|
||||
func enqueueWebView(_ webView: WKWebView) {
|
||||
webView.uiDelegate = nil
|
||||
webView.navigationDelegate = nil
|
||||
|
||||
let html = ArticleRenderer.noSelectionHTML(style: .defaultStyle)
|
||||
webView.loadHTMLString(html, baseURL: nil)
|
||||
|
||||
queue.insert(webView, at: 0)
|
||||
}
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private let minimumQueueDepth = 3
|
||||
private var queue: [WKWebView] = []
|
||||
|
||||
private init() {
|
||||
replenishQueueIfNeeded()
|
||||
}
|
||||
|
||||
private func replenishQueueIfNeeded() {
|
||||
while queue.count < minimumQueueDepth {
|
||||
let webView = WKWebView(frame: .zero)
|
||||
enqueueWebView(webView)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue