16

I am using UIWebView to render web content in my application. I observed that the initial request when the app launches i.e. loadRequest, takes a long time to render the contents. However the subsequent requests which I don't track of, are much faster.
To confirm this, I created a standalone application which just has a UIWebView. This is the single line of code which I have added :

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

The result is same. It takes around 15-20 seconds to load the page. However on tapping any link on web page, it takes 3-5 seconds to load the next page. I did put the UIWebView delegate function didFailLoadWithError, but there is never an error.
Question:

  1. Why is the first web request so slow ?
  2. How may I make it faster other than caching ?
Nitish
  • 13,845
  • 28
  • 135
  • 263
  • You are working on simulator or any device? may be there is some proxy open on your device. – aBilal17 May 11 '15 at 07:19
  • @aBilal17 : I am testing this on device. Not just one. I tested this on 3 different devices. – Nitish May 11 '15 at 07:22
  • Please add this line as well and then check. web.scrollView.delaysContentTouches = NO; – aBilal17 May 11 '15 at 07:30
  • @aBilal17 : Didn't make difference. – Nitish May 11 '15 at 07:49
  • Does it happen only with https://www.yahoo.com? How about other websites? – lambao May 11 '15 at 08:59
  • @lambao : It varies. I tried with 4-5 url's. Least taken was by google.com of 4-5 seconds. – Nitish May 11 '15 at 09:07
  • Maybe MainThread was blocked, try open urls in blank UIViewController and see what happen. – lambao May 11 '15 at 09:34
  • @lambao : As I mentioned, the sample project I created to confirm this, has just a UIWebView and nothing else. Can you explain how may I load url in **blank UIViewController** ? – Nitish May 11 '15 at 09:37
  • Sorry, I'm misreading. Blank UIViewController here I mean a UIView with only UIWebView, and just load url when viewDidLoad. Aw, strange situation I thinks. Is Safari or Chrome slowly as well? – lambao May 11 '15 at 09:49
  • @Nitish : The issue is all about the server spending time in resolving the browser type so as to respond back with the right compatibility page. Kindly see my answer below. – Balram Tiwari May 18 '15 at 15:37
  • Try using the Charles application to proxy and record your web server interaction. That should show you which transactions, if any, are being delayed to help you figure out if its your app, the server or a combination of both. – Rory McKinnel May 19 '15 at 13:41

6 Answers6

5

The main reason is because, when you invoke the first time URL request, the server on the receiving end tries to display the information as per the requested device browser, ( like mobile, desktop). This is where you see a bit of delay.

  • The server take some time to resolve the request origin browse type & respond according to the browser type. This value is internally send from the browser. There is a difference in mobile safari & desktop safari.
  • The Server upon receiving the request, responds you back with the device type compatible page, ( mostly all domain servers are implementing this internally, the responsive pages).
  • If you want a "no delay situation", try calling the exact mobile version of the portal in concern.
  • The sub-sequent requests are treated from a known type browser, hence reducing the delay in response.

Hope this solves the doubt.

Balram Tiwari
  • 5,657
  • 2
  • 23
  • 41
  • Does this matter when most websites use a responsive approach where the interface just adjusts to the screen size, so that there is no "other" version of the portal for mobile to call? – Bourne Aug 07 '15 at 12:13
  • 4
    I disagree. I have a static page being displayed from the app's bundle: `let bundlePath = Bundle.main.bundlePath.stringByAppendingPathComponent("description.html")` `let url = URL(fileURLWithPath: bundlePath)` `let request = URLRequest(url: requestURL)` `webView.loadRequest(request)` So where's network & server delay? – One In a Million Apps Nov 04 '16 at 15:23
3

The answer of your first question is following:
When you're loading request for the first time, the webview downloads and caches all the files like css, images, etc... After, when you click on a url that brings you to another page of the same website, it's basically loads it from the cache instead of downloading again, and it saves a lot of time.

arturdev
  • 10,884
  • 2
  • 39
  • 67
  • But the second page is also loaded for the first time when the app is first launched. There is no cache at that time for that page. It is only when the page is visited again, page is loaded from cache. – Nitish May 14 '15 at 13:19
3

There are multiple reasons the first load might be slower than subsequent loads.

First of all, your application is linking to dynamic frameworks. Dynamic link resolution is performed lazily. So whenever you use the UIWebView for the first time, there is a very small overhead involved with resolving the symbols you have used from the dynamic library. The UIWebView itself could depend on some more internal libraries that need to be dinamically linked, adding to that overhead.

Then there is also the implementation of the UIWebView itself. The UIWebView's internal most likely involve data structures that are initialized lazily.

Then there is the memory allocation aspect. Whenever you make your first page load, the memory usage of your application rises much more than what it does upon the second page load. Allocating sufficient memory to process a page load adds to the overhead, but once that is done, iOS will entrust this memory to your application for some period of time that exceeds the point where the memory was deallocated in order to make your application faster when it hits peaks in its memory usage.

Someone suggested that there might be cached resources between your two pages. Even if both pages are different and are being loaded for the first time, they might share a common css file or a common javascript file such as jQuery. Then the browser is able to reuse those cached resources.

Overall, there are a lot of factors like these that explain why the first page load might be slower than subsequent page loads. You could get to know more about what the UIWebView is actually doing by profiling the application during both page loads.

Dalzhim
  • 1,970
  • 1
  • 17
  • 34
1

The answer of your first question: When you're loading request for the first time, the webview downloads and caches all the files like css, images, etc... After, when you click on a url that brings you to another page of the same website, it's basically loads it from the cache instead of downloading again, and it saves a lot of time.

0

One thing you can do here to see what is going on is to implement an NSURLProtocol similar to the following link: http://www.raywenderlich.com/59982/nsurlprotocol-tutorial

and intercept your requests in the canInitWithRequest method.

This will only show you what is going on with your requests at least.

Ahmed Ebaid
  • 417
  • 6
  • 21
0

Just load UIWebView with a dummy page off-screen, during your app's launch.This will work well on real devices. In AppDelegates didFinishLaunchingWithOptions method.

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;
    }
Ved Rauniyar
  • 1,539
  • 14
  • 21