UIWebView第一次请求太慢

时间:2015-05-11 06:47:54

标签: ios iphone uiwebview uiwebviewdelegate

我正在使用UIWebView在我的应用中呈现网页内容。我观察到应用程序启动时的初始请求,即loadRequest,需要很长时间才能呈现内容。然而,我不跟踪的后续请求要快得多 为了确认这一点,我创建了一个只有UIWebView的独立应用程序。这是我添加的单行代码:

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

结果是一样的。加载页面大约需要 15-20 秒。但是,点击网页上的任何链接,加载下一页需要 3-5 秒。我确实把UIWebView委托函数didFailLoadWithError,但从来没有错误 问题

  1. 为什么第一个网络请求这么慢?
  2. 除了缓存之外,我怎样才能让它更快?

6 个答案:

答案 0 :(得分:4)

主要原因是,当您调用第一次URL请求时,接收端的服务器会尝试按照请求的设备浏览器(如移动设备,桌面设备)显示信息。这是你看到一点延迟的地方。

  • 服务器需要一些时间来解析请求源浏览类型&根据浏览器类型进行回复。该值在内部从浏览器发送。 移动safari&桌面游猎
  • 服务器收到请求后,会回复设备类型兼容页面(大多数所有域服务器都在内部实现响应页面)。
  • 如果您想要一个"没有延迟的情况",请尝试调用相关的门户网站的确切移动版本。
  • 后续请求由已知类型浏览器处理,因此减少了响应延迟。

希望这能解决疑问。

答案 1 :(得分:3)

您的第一个问题的答案如下:
当您第一次加载请求时,webview会下载并缓存所有文件,如CSS,图像等...之后,当您点击一个将您带到同一网站的另一个页面的网址时,它会& #39; s基本上是从缓存中加载而不是再次下载,这样可以节省大量时间。

答案 2 :(得分:3)

第一次加载可能比后续加载慢。有多种原因。

首先,您的应用程序正在链接到动态框架。懒惰地执行动态链接解析。因此,无论何时第一次使用UIWebView,解析您在动态库中使用的符号都会产生非常小的开销。 UIWebView本身可能依赖于一些需要进行动态链接的内部库,从而增加了开销。

然后还有UIWebView本身的实现。 UIWebView内部最有可能涉及懒惰初始化的数据结构。

然后是内存分配方面。无论何时加载第一页,应用程序的内存使用量都会比第二页加载时的内存使用量上升得多。分配足够的内存来处理页面加载会增加开销,但一旦完成,iOS会将此内存委托给您的应用程序一段时间,超过内存被释放的时间点,以便在应用程序更快时使应用程序运行它的内存使用量达到峰值。

有人建议您的两个页面之间可能存在缓存资源。即使两个页面都不同并且是第一次加载,它们也可能共享一个公共的css文件或一个常见的javascript文件,例如jQuery。然后浏览器就可以重用这些缓存的资源。

总的来说,有很多这样的因素可以解释为什么第一页加载可能比后续页面加载慢。您可以通过在两个页面加载期间分析应用程序来了解UIWebView实际执行的操作的更多信息。

答案 3 :(得分:1)

你的第一个问题的答案: 当您第一次加载请求时,webview会下载并缓存所有文件,如CSS,图像等...之后,当您点击一个将您带到同一网站的另一个页面的网址时,它基本上会加载它来自缓存而不是再次下载,它节省了大量时间。

答案 4 :(得分:0)

您可以在此处查看正在发生的事情是实现类似于以下链接的NSURLProtocol:http://www.raywenderlich.com/59982/nsurlprotocol-tutorial

并在canInitWithRequest方法中拦截您的请求。

这只会向您显示您的请求至少发生了什么。

答案 5 :(得分:0)

在您的应用启动过程中,只需在屏幕外加载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;
    }