web-dev-qa-db-ja.com

UIWebViewの最初のリクエストが遅すぎる

UIWebViewを使用して、アプリケーションでWebコンテンツをレンダリングしています。アプリの起動時の最初のリクエスト、つまりloadRequestは、コンテンツのレンダリングに長い時間がかかることを確認しました。しかし、私が追跡していない後続のリクエストははるかに高速です。
これを確認するために、UIWebViewだけを持つスタンドアロンアプリケーションを作成しました。これは私が追加した1行のコードです:

[wkBrowser loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.yahoo.com"]]];

結果は同じです。ページの読み込みには約15-2秒かかります。ただし、Webページ上のリンクをタップすると、次のページをロードするのに-5秒かかります。 UIWebViewデリゲート関数didFailLoadWithErrorを配置しましたが、エラーは発生しません。
質問

  1. 最初のWebリクエストが非常に遅いのはなぜですか?
  2. キャッシュ以外の速度を上げるにはどうすればよいですか?
13
Nitish

主な理由は、最初にURL要求を呼び出すときに、受信側のサーバーが要求されたデバイスブラウザー(モバイル、デスクトップなど)に従って情報を表示しようとするためです。ここで少し遅れが見られます。

  • サーバーには時間がかかりますリクエストのオリジンブラウズタイプを解決し、ブラウザタイプに応じて応答するため。この値は、ブラウザから内部的に送信されます。 モバイルサファリとデスクトップサファリには違いがあります。
  • サーバーはリクエストを受信すると、デバイスタイプと互換性のあるページで応答します(ほとんどすべてのドメインサーバーがこれを内部で実装しています、レスポンシブページ)。
  • 「遅延なしの状況」が必要な場合は、問題のポータルの正確なモバイルバージョンに電話してみてください。
  • 後続のリクエストは既知のタイプのブラウザから処理されるため、応答の遅延が減少します。

これが疑問を解決することを願っています。

5
Balram Tiwari

最初のロードが後続のロードよりも遅くなる理由は複数あります。

まず、アプリケーションは動的フレームワークにリンクしています。動的リンク解決は遅延して実行されます。したがって、UIWebViewを初めて使用するときはいつでも、ダイナミックライブラリから使用したシンボルの解決に伴う非常に小さなオーバーヘッドがあります。 UIWebView自体は、動的にリンクする必要のあるいくつかの内部ライブラリに依存する可能性があり、そのオーバーヘッドが増加します。

次に、UIWebView自体の実装もあります。 UIWebViewの内部には、遅延初期化されたデータ構造が含まれている可能性があります。

次に、メモリ割り当ての側面があります。最初のページをロードすると、アプリケーションのメモリ使用量は2番目のページのロード時よりもはるかに高くなります。ページの読み込みを処理するのに十分なメモリを割り当てるとオーバーヘッドが増加しますが、それが完了すると、iOSは、アプリケーションを高速化するために、メモリの割り当てが解除された時点を超える期間、このメモリをアプリケーションに委託します。メモリ使用量のピークに達します。

誰かがあなたの2つのページの間にキャッシュされたリソースがあるかもしれないと提案しました。両方のページが異なり、初めて読み込まれる場合でも、共通のcssファイルまたはjQueryなどの共通のjavascriptファイルを共有している可能性があります。その後、ブラウザはそれらのキャッシュされたリソースを再利用できます。

全体として、最初のページの読み込みが後続のページの読み込みよりも遅い理由を説明する、これらのような多くの要因があります。両方のページの読み込み中にアプリケーションをプロファイリングすることで、UIWebViewが実際に何をしているのかを知ることができます。

3
Dalzhim

最初の質問の答えは次のとおりです。
リクエストを初めてロードするとき、webviewはcss、画像などのすべてのファイルをダウンロードしてキャッシュします...その後、同じの別のページに移動するURLをクリックするとウェブサイトでは、基本的に再度ダウンロードするのではなく、キャッシュからロードし、時間を大幅に節約します。

3
arturdev

最初の質問の答え:リクエストを初めてロードするとき、webviewはcss、画像などのすべてのファイルをダウンロードしてキャッシュします...その後、別のページに移動するURLをクリックすると同じウェブサイトで、基本的には再度ダウンロードするのではなくキャッシュからロードし、時間を大幅に節約します。

1
user4861095

アプリの起動時に、ダミーページを画面外にUIWebViewで読み込むだけです。これは、実際のデバイスでうまく機能します。 AppDelegates内didFinishLaunchingWithOptionsメソッド。

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        self.loadInitialWebView()
        return true
    }

func loadInitialWebView() {
        var dummyWebView : UIWebView? = UIWebView(frame: UIScreen.main.bounds)
        let htmlString = "<!doctype html><html lang=en><head><meta charset=utf-8><title>dummy</title></head><body><p>dummy content</p></body></html>"
        dummyWebView?.loadHTMLString(htmlString, baseURL: nil)
        dummyWebView = nil;
    }
0
Ved Rauniyar

ここで何が起こっているかを確認するためにできることの1つは、次のリンクのようなNSURLProtocolを実装することです。 http://www.raywenderlich.com/59982/nsurlprotocol-tutorial

canInitWithRequestメソッドでリクエストをインターセプトします。

これは、少なくともリクエストで何が起こっているかを示すだけです。

0
Ahmed Ebaid