iOS应用中的WKWebView需要很长时间才能加载

时间:2018-05-25 22:06:29

标签: ios wkwebview

我有一个UWiew,它有一个WKWebView作为子视图。 Web视图显示正确,但显示HTML文档需要很长时间(超过一秒)。该文档是一个本地文件(项目中的HTML文件),因此没有Internet延迟,它是一个相对简单的HTML文档。 HTML文档上有八个小图像,但是另一个没有任何图像的HTML文档存在类似的问题。

以下是将HTML文档加载到Web视图中的代码:

override func viewDidLoad() {
    super.viewDidLoad()
    let localHtmlFile = Bundle.main.url(forResource: "place", withExtension: "html");
    let request = URLRequest(url: localHtmlFile!);
    webView.load(request);
}

我正在使用Xcode 9.3,Swift 4.1和iOS 11.2。

每次进入该屏幕时都会发生延迟。如果第一次无法阻止延迟,是否可以保持网络视图,以便延迟只发生一次?

2 个答案:

答案 0 :(得分:2)

显然,延迟是由创建WKWebView的新实例所花费的时间引起的,而不是加载HTML文档所需的时间。为了避免这种延迟,我想出了一种重用Web视图的方法。

首先,我从故事板场景中删除了Web视图,这样每次加载视图时都不会创建新的Web视图。我创建了一个名为container的通用视图,其大小与我想要的Web视图大小相同。

然后我创建了一个静态变量来保持指向Web视图的指针:
     static var webView: WKWebView? = nil
在我的例子中,这个静态变量位于一个名为GameController的类中。

接下来我更改了代码以检查静态webView变量是否为零。如果webView为nil,则代码会创建一个新的Web视图,并将静态变量设置为指向该Web视图。然后,代码以编程方式将Web视图添加为故事板场景中容器视图的子视图。

要设置故事板并编写此代码,我使用了以下网站上的说明:
http://www.onebigfunction.com/ios/2016/12/14/iOS-javascript-communication/

使用Web视图(我的代码中为WebViewController)的场景的视图控制器中的基本代码如下所示:

override func loadView() {
    super.loadView()
    if GameController.webView == nil {
        var webFrame = self.container!.frame
        webFrame.origin.x = 0
        webFrame.origin.y = 0
        let config = WKWebViewConfiguration()
        webView = WKWebView(frame: webFrame,
                            configuration: config)
        GameController.webView = webView
    } else {
        webView = GameController.webView
    }
    self.container!.addSubview(webView)
}

在我的情况下,我想将Web视图中的JavaScript代码信息发送到我的应用程序中的Swift代码,因此我必须更多地使用配置。我还希望Web视图是透明的,所以我添加了一个声明来做到这一点。

override func loadView() {
    super.loadView()
    if GameController.webView == nil {
        var webFrame = self.container!.frame
        webFrame.origin.x = 0
        webFrame.origin.y = 0
        let config = WKWebViewConfiguration()
        config.userContentController.add(self, name: "scriptHandler")
        webView = WKWebView(frame: webFrame,
                            configuration: config)
        webView.isOpaque = false
        GameController.webView = webView
    } else {
        webView = GameController.webView
        webView.configuration.userContentController.removeScriptMessageHandler(
            forName: "scriptHandler")
        webView.configuration.userContentController.add(self,
             name: "scriptHandler")
    }
    self.container!.addSubview(webView)
}

最初我只是在第一次创建Web视图时设置了脚本处理程序,但这并不起作用。显然每次加载场景时都会生成一个新的视图控制器对象,因此旧的脚本处理程序不起作用。此代码删除指向旧视图控制器的脚本处理程序,并添加指向新视图控制器的脚本处理程序。

答案 1 :(得分:0)

只需保留对ViewController的引用,可能是在父控制器,应用程序委托,甚至单例/全局中。在后续加载时它应该更快一些。