Custom WebView HTTP IO is Bad

Custom WebView HTTP IO is Bad
Melpomene (muse of tragedy) sculpture of Twelve Paths (Dvenadtsat Dorozhek) in Old Sylvia in Pavlovsk Park. Pavlovsk, suburb of Saint Petersburg, Russia, Photo December 31, 2015.

Previously I wrote a post OkHttp as HTTP Engine for WebView.

Now, I definitely can say that it was bad idea. And it's not an OkHttp's fault.

WebView problems
  1. If you can avoid WebView — avoid it.
  2. WebView calls shouldInterceptRequest() synchronously in a single IO thread, so resources will be loaded synchronously one after another. Though, OkHttp is fast enough (SPDY, HTTP/2) that it may give better results on a good connection in compare to native loading of the resources via WebView.
  3. Looks like WebView blocks JavaScript execution until you load all resources in shouldInterceptRequest(). Also looks like native resources loading in the WebView somehow integrated into JavaScript execution queue so JS can do its work "in parallel" to native resources loading.

Unfortunately, most of integrated WebViews on Android < 5 and Android System WebView from Google Play affected with these problems.

But I still want to load resources myself!

If you still want to manually load resources of pages that you're displaying you can do it.

Suggested algorithm (suitable for email clients btw):

  1. Load resources in background before WebView even displayed (for example if email app receives a new message in background, it can start pre-fetching images from the message even before user opens the app, of course with respect to connection quality and battery level).
  2. Override shouldInterceptRequest() and return result from pre-fetched cache if it exists, otherwise you can either return false and leave loading of the resource to the WebView or synchronously load it manually, but as mentioned before — WebView may stuck on a bad connection.

Another approach if you can't pre-fetch resources is to override shouldInterceptRequest(), immediately return some fake result and start async load of the requested resource, then when the resource will be downloaded you can trigger it's reload via JavaScript and return content from cache!


Bonus info

If you need relatively fast WebView with support for "new" web features and your app supports Android versions that can not use Android System WebView from the Google Play — take a look at Crosswalk project.
TL;TR: Crosswalk is a WebView based on relatively fresh versions of Chromium which you can include into your apk statically or dynamically as a shared library.