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

标签 ios wkwebview

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

这是将 HTML 文档加载到 Web View 中的代码:

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。

每次我进入该屏幕时都会发生延迟。如果无法在第一时间防止延迟,是否可以保留 Web View 以便延迟仅发生一次?

最佳答案

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

首先,我从 Storyboard 场景中删除了 WebView ,这样就不会在每次加载 View 时都创建一个新的 WebView 。我制作了一个名为 container 的通用 View ,它的大小与我希望的 Web View 相同。

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

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

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

使用 Web View 的场景的 View Controller 中的基本代码(我的代码中的 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 View 中的 JavaScript 代码发送到我的应用程序中的 Swift 代码,因此我不得不在配置方面做更多的工作。我还希望 Web View 是透明的,所以我添加了一条语句来做到这一点。

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)
}

最初我只在第一次制作 WebView 时设置脚本处理程序,但那没有用。显然,每次加载场景时都会创建一个新的 View Controller 对象,因此旧的脚本处理程序不起作用。此代码删除指向旧 View Controller 的脚本处理程序并添加指向新 View Controller 的脚本处理程序。

关于ios - iOS 应用程序中的 WKWebView 需要很长时间才能加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50537421/

相关文章:

ios - MPMoviePlayerController:Seek Button 点击​​卡住视频 - 黑屏

ios - 刽子手计划

ios - 对象未显示在模拟器中

iphone - 为 iphone 创建图标的工具

ios - WKWebView 加载 html 代码而不是内容 (iOS)

javascript - 从源 WKWebView (window.opener) 访问 JavaScript 函数

swift - 为 TableView 启用 3D Touch 预览

ios - 在类的范围内显式创建 View 对象与 loadView 函数之间有区别吗?

ios - 在 WKWebView 中使用自定义本地字体

iOS Cordova 将本地文件设置为 img src