LoginSignup
5
1

More than 1 year has passed since last update.

UITabbarControllerのWebViewを先読み(プリロード)して、表示速度を高速化する。

Last updated at Posted at 2022-11-22

UITabbarControllerにWKWebViewを配置した場合、タブが切り替わってからロードが走りWebViewが表示されるのでロード待ちの時間が発生し、ページが表示されるまにで時間がかかってしまう。

これを改善するために裏側でロードを走らせてロード待ちの時間を短縮し、ページの表示速度を上げることが出来ましたのでご紹介します。

■ポイント

  1. initでwebViewを読み込んでおく。
    XibでViewを用意しておく。(あとでwebviewを追加する用)
  2. initの段階ではWebviewの制約は仮で設定しておく。
  3. viewDidLoadで用意していたXibのViewにWebViewを追加して、正しい制約をかける。

1. initでWebViewを読み込んでおく。

viewDidLoadでページをロードをしているからロード時間が発生していた。
└ initの段階でページのロードを走らせたい。

  • initでwebViewを使いたいのでwebViewだけはXibで作らない。
    (理由:Xibで作ったViewは、viewDidLoadから使えるようになるのでinitでは使えない為)
  • あとでwebViewをaddSubViewする為の箱を用意する。(webViewContainer)
    // webView入れる用の箱を用意する。
    @IBOutlet weak var webViewContainer: UIView!
    @IBOutlet weak var loadingView: UIActivityIndicatorView!
    @IBOutlet weak var errorView: UIView!
    // initでwebViewを使いたいのでXibで作らない。
    private var webView: WKWebView?

    init() {
        super.init(nibName: nil, bundle: nil)
        // イニシャライザでローディングする。
        preloadWebView()
    }

2. initの段階ではWebViewの制約は仮で設定しておく。(viewDidLoadで正しい制約をつける)

    private func preloadWebView() {
        let config = WKWebViewConfiguration()
        config.allowsInlineMediaPlayback = true
        config.mediaTypesRequiringUserActionForPlayback = []
        
        // 仮の制約をかける
        let width = UIScreen.main.bounds.size.width
        let height = UIScreen.main.bounds.size.height
        webView = WKWebView(frame: CGRect(x: 0, y: 0, width: width, height: height), configuration: config)

        loadWebView()
    }

    private func loadWebView() {
        guard let webView = webView else {
            return
        }
        guard let url = URL(string: "https://www.google.com") else {
            return
        }

        let request = URLRequest(
            url: url,
            cachePolicy: .reloadIgnoringLocalAndRemoteCacheData,
            timeoutInterval: 10
        )

        webView.navigationDelegate = self
        webView.load(request)
    }

3. viewDidLoadで用意していたXibのViewにWebViewを追加して、正しい制約をかける。

    override func viewDidLoad() {
        super.viewDidLoad()
        createWebView()
    }

    private func createWebView() {
        guard let webView = webView else {
            return
        }
        if !webView.isDescendant(of: webViewContainer) {
            // 用意していたview(webViewContainer)にWebViewをaddSubViewする。
            self.webViewContainer.addSubview(webView)
            webView.translatesAutoresizingMaskIntoConstraints = false

            // 正しい制約をかける。
            let constraints = [
                webView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor),
                webView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor),
                webView.trailingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.trailingAnchor),
                webView.leadingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leadingAnchor)
            ]
            NSLayoutConstraint.activate(constraints)
        }
    }

■全体のコード

WebViewController.swift
    @IBOutlet weak var webViewContainer: UIView!
    @IBOutlet weak var loadingView: UIActivityIndicatorView!
    @IBOutlet weak var errorView: UIView!
    private var webView: WKWebView?
    
    init(webViewConfig: WebViewConfig) {
        super.init(nibName: nil, bundle: nil)
        preloadWebView()
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        createWebView()
    }

    private func preloadWebView() {
        let config = WKWebViewConfiguration()
        config.allowsInlineMediaPlayback = true
        config.mediaTypesRequiringUserActionForPlayback = []

        let width = UIScreen.main.bounds.size.width
        let height = UIScreen.main.bounds.size.height
        webView = WKWebView(frame: CGRect(x: 0, y: 0, width: width, height: height), configuration: config)

        loadWebView()
    }

    private func createWebView() {
        guard let webView = webView else {
            return
        }
        if !webView.isDescendant(of: webViewContainer) {
            self.webViewContainer.addSubview(webView)
            webView.translatesAutoresizingMaskIntoConstraints = false

            let constraints = [
                webView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor),
                webView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor),
                webView.trailingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.trailingAnchor),
                webView.leadingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leadingAnchor)
            ]
            NSLayoutConstraint.activate(constraints)
        }
    }

    private func loadWebView() {
        guard let webView = webView else {
            return
        }
        guard let url = URL(string: "https://www.google.com") else {
            return
        }

        let request = URLRequest(
            url: url,
            cachePolicy: .reloadIgnoringLocalAndRemoteCacheData,
            timeoutInterval: 10
        )

        webView.navigationDelegate = self
        webView.load(request)
    }
5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1