WKWebView
開発しているアプリにおいて、WKWebViewでページが表示されるまで結構時間がかかりストレスを感じていたので、パフォーマンスを改善できるポイントがないか色々と試していました。
その際、インスタンス化した直後のWKWebViewにload(_:)
メソッドでWebページを読み込ませた場合、実際に読み込み開始されるまで(WKNavigationDelegateのwebView(_:didStartProvisionalNavigation:)
が呼ばれるまで)に、私の環境では1秒近く遅延があることが分かりました。
検証方法
以下は検証した際のコードの本質的な部分の抜粋です。
func loadWebPage() {
//以下をコメントアウトをする場合・しない場合で検証
webView = WKWebView(frame: CGRect.zero)
webView.navigationDelegate = self
let url = URL(string: urlString)!
let req = URLRequest(url: url)
time = Date()
webView.load(req)
}
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
let diff = Date().timeIntervalSince1970 - time.timeIntervalSince1970
print("\(diff)")
}
検証ではボタンタップの度にloadWebPage
を実行していますが、このメソッドの中で毎回WKWebViewをインスタンス化するか、事前にインスタンス化したWKWebViewを使い回すかでWebページの読み込みが開始されるまでの時間に大きな違いが出ました。
都度インスタンス化 | 事前インスタンス化 |
---|---|
0.8821330070495605 | 0.008857965469360352 |
0.9119091033935547 | 0.013974189758300781 |
0.9316868782043457 | 0.024454116821289062 |
1.1122016906738281 | 0.0029480457305908203 |
1.060987949371338 | 0.003103017807006836 |
上の表はload(_:)
してからwebView(_:didStartProvisionalNavigation:)
が呼ばれるまでの遅延秒数です。
実際の秒数は端末によっても差がありますが、いずれにしろ都度インスタンス化するのと事前インスタンス化するのではかなり違いがあります。
Webページの読み込みを開始するまでの何かしらの事前処理を行なっていてこのような差が出ているのだと推察していますが、具体的には分かっていません。
パフォーマンスを改善するには
もし対象のアプリで、画面内に1度に表示されるWKWebViewが1つだけであるなら、そのViewControllerのクラスプロパティとして持たせて使い回すようにするだけでページが表示されるまでのパフォーマンスがそこそこ改善しそうです。
もし1つの画面に複数のWKWebViewを同時に表示させる必要があるなら、事前に十分な数のWKWebViewをインスタンス化し保持しておく等のやり方ができそうです。