UIWebView
を使用して、アプリケーションでWebコンテンツをレンダリングしています。アプリの起動時の最初のリクエスト、つまりloadRequest
は、コンテンツのレンダリングに長い時間がかかることを確認しました。しかし、私が追跡していない後続のリクエストははるかに高速です。
これを確認するために、UIWebView
だけを持つスタンドアロンアプリケーションを作成しました。これは私が追加した1行のコードです:
[wkBrowser loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.yahoo.com"]]];
結果は同じです。ページの読み込みには約15-2秒かかります。ただし、Webページ上のリンクをタップすると、次のページをロードするのに-5秒かかります。 UIWebViewデリゲート関数didFailLoadWithErrorを配置しましたが、エラーは発生しません。
質問:
主な理由は、最初にURL要求を呼び出すときに、受信側のサーバーが要求されたデバイスブラウザー(モバイル、デスクトップなど)に従って情報を表示しようとするためです。ここで少し遅れが見られます。
これが疑問を解決することを願っています。
最初のロードが後続のロードよりも遅くなる理由は複数あります。
まず、アプリケーションは動的フレームワークにリンクしています。動的リンク解決は遅延して実行されます。したがって、UIWebView
を初めて使用するときはいつでも、ダイナミックライブラリから使用したシンボルの解決に伴う非常に小さなオーバーヘッドがあります。 UIWebView
自体は、動的にリンクする必要のあるいくつかの内部ライブラリに依存する可能性があり、そのオーバーヘッドが増加します。
次に、UIWebView
自体の実装もあります。 UIWebView
の内部には、遅延初期化されたデータ構造が含まれている可能性があります。
次に、メモリ割り当ての側面があります。最初のページをロードすると、アプリケーションのメモリ使用量は2番目のページのロード時よりもはるかに高くなります。ページの読み込みを処理するのに十分なメモリを割り当てるとオーバーヘッドが増加しますが、それが完了すると、iOSは、アプリケーションを高速化するために、メモリの割り当てが解除された時点を超える期間、このメモリをアプリケーションに委託します。メモリ使用量のピークに達します。
誰かがあなたの2つのページの間にキャッシュされたリソースがあるかもしれないと提案しました。両方のページが異なり、初めて読み込まれる場合でも、共通のcssファイルまたはjQueryなどの共通のjavascriptファイルを共有している可能性があります。その後、ブラウザはそれらのキャッシュされたリソースを再利用できます。
全体として、最初のページの読み込みが後続のページの読み込みよりも遅い理由を説明する、これらのような多くの要因があります。両方のページの読み込み中にアプリケーションをプロファイリングすることで、UIWebView
が実際に何をしているのかを知ることができます。
最初の質問の答えは次のとおりです。
リクエストを初めてロードするとき、webviewはcss、画像などのすべてのファイルをダウンロードしてキャッシュします...その後、同じの別のページに移動するURLをクリックするとウェブサイトでは、基本的に再度ダウンロードするのではなく、キャッシュからロードし、時間を大幅に節約します。
最初の質問の答え:リクエストを初めてロードするとき、webviewはcss、画像などのすべてのファイルをダウンロードしてキャッシュします...その後、別のページに移動するURLをクリックすると同じウェブサイトで、基本的には再度ダウンロードするのではなくキャッシュからロードし、時間を大幅に節約します。
アプリの起動時に、ダミーページを画面外に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;
}
ここで何が起こっているかを確認するためにできることの1つは、次のリンクのようなNSURLProtocolを実装することです。 http://www.raywenderlich.com/59982/nsurlprotocol-tutorial
canInitWithRequestメソッドでリクエストをインターセプトします。
これは、少なくともリクエストで何が起こっているかを示すだけです。