简体   繁体   English

预加载多个本地 WebView

[英]Preload multiple local WebViews

Because I could just find some outdated information / not working solutions to my problem I decided to ask this kind of question again.因为我只能找到一些过时的信息/无法解决我的问题,所以我决定再次提出此类问题。 (See outdated / wrong solutions:) (参见过时/错误的解决方案:)


My app is separated in one native part and one HTML part.我的应用程序分为一个本机部分和一个 HTML 部分。 The HTML is saved as a local file (index.html) and should be load into the myWebView view. HTML 保存为本地文件 (index.html),应该加载到myWebView视图中。

@IBOutlet weak var myWebView: UIWebView!
func loadWebview() {
    let url = Bundle.main.url(forResource: "index", withExtension: "html")
    let request = URLRequest(url: url!)
    myWebView.loadRequest(request)
    myWebView.scrollView.isScrollEnabled = false
    myWebView.allowsLinkPreview = false
    myWebView.delegate = self
}

Because my DOM tree is very large, switching from the native part to the web part (on button click) takes quite a long time at - least for the first time switching - because afterward, I'm sure the webView-request gets cached.因为我的 DOM 树非常大,所以从本机部分切换到Web 部分(点击按钮时)至少需要很长时间 -至少第一次切换- 因为之后,我确定webView-request被缓存。

To my question : How can I preload the WebView on app init to avoid the white screen ( maybe 0.5s - 1s duration ) when switching from the native to the Web part? To my question :从本机切换到 Web 部件时,如何在app init预加载 WebView以避免出现白屏(可能是 0.5s - 1s 持续时间)?

EDIT:编辑:

The WKWebView is displaying the scrollbar while the UIWebView was not! WKWebView 正在显示滚动条,而 UIWebView 没有!

Using (like with UIWebView) this styles:使用(与 UIWebView 一样)这种样式:

::-webkit-scrollbar {
     display: none;
}

is not working and adding these lines:不工作并添加这些行:

webview.scrollView.showsHorizontalScrollIndicator = false
webview.scrollView.showsVerticalScrollIndicator = false

is also not working at all.也根本不工作。

Firstly, you should switch to WKWebView , UIWebView is no longer recommended to be used by Apple.首先,你应该切换到WKWebViewUIWebView不再被苹果推荐使用。

Secondly, you can create a pool of web views that get created and asked to load when the app starts.其次,您可以创建一个 Web 视图池,这些视图会在应用程序启动时被创建并要求加载。 This way by the time the user switches to the web interface the web view might've got a chance to fully load.这样,当用户切换到 Web 界面时,Web 视图可能有机会完全加载。

For this you can use a class like this:为此,您可以使用这样的类:

/// Keeps a cache of webviews and starts loading them the first time they are queried
class WebViewPreloader {
    var webviews = [URL: WKWebView]()


    /// Registers a web view for preloading. If an webview for that URL already
    /// exists, the web view reloads the request
    ///
    /// - Parameter url: the URL to preload
    func preload(url: URL) {
        webview(for: url).load(URLRequest(url: url))
    }

    /// Creates or returns an already cached webview for the given URL.
    /// If the webview doesn't exist, it gets created and asked to load the URL
    ///
    /// - Parameter url: the URL to prefecth
    /// - Returns: a new or existing web view
    func webview(for url: URL) -> WKWebView {
        if let cachedWebView = webviews[url] { return cachedWebView }

        let webview = WKWebView(frame: .zero)
        webview.load(URLRequest(url: url))
        webviews[url] = webview
        return webview
    }
}

and ask it to preload the url sometimes during the app startup:并要求它有时在应用程序启动期间预加载 url:

// extension added for convenience, as we'll use the index url in at least
// two places
extension Bundle {
    var indexURL: URL { return self.url(forResource: "index", withExtension: "html")! }
}

webviewPreloader.preload(url: Bundle.main.indexURL)

Thirdly, you might need to use a container view instead of the actual web view, in your controller:第三,您可能需要在控制器中使用容器视图而不是实际的 Web 视图:

@IBOutlet weak var webviewContainer: UIView!

What remains is to add the preloaded web view to the container when needed:剩下的就是在需要时将预加载的 web 视图添加到容器中:

func loadWebview() {
    // retrieve the preloaded web view, add it to the container
    let webview = webviewPreloader.webview(for: Bundle.main.indexURL)
    webview.frame = webviewContainer.bounds
    webview.translatesAutoresizingMaskIntoConstraints = true
    webview.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    webviewContainer.addSubview(webview)
}

And not lastly, be aware that keeping alive instances of web views, might carry performance penalties - memory and CPU-wise.最后一点,请注意保持 Web 视图的活动实例可能会带来性能损失 - 内存和 CPU 方面。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM