17
votes

In my app, I am loading a list of external url's in webview and allow user to flip through them. Webviews are loaded on to a view flipper. I find the performance is really bad in webview load url. I have tried everything from using the frame layout to limiting the number of webviews to load. Still the performance is not satisfactory.

How do I optimize the performance of webview? This should be a common usage. Am I missing something obvious.

My Webview settings are -

    webView.setInitialScale(WEBVIEW_SCALE);
    webView.getSettings().setJavaScriptEnabled(true);
    webView.getSettings().setBuiltInZoomControls(false);
    webView.setWebViewClient(new MyWebViewClient());    
    webView.setOnTouchListener( new OnTouchListener());
4
Are you sure it's not loading the data from the internet the problem? - Falmarri
Nope. Data is loaded. But it takes long time. - Usha
Loading multiple pages at a time is costly - even loading a single webpage is a costly operation. Putting aside all the processing of things like images, scaling of the view port etc. There are also limitations on performance of many concurrent socket connections. Finally I'd guess that if you watch the log you will see a lot of GC thrash. It is not really advisable to have many WebView's active at once. With out a quantitative description of "performance is not satisfactory" or the handset you are running on, I can only guess that there is not much you can do to improve it. - cistearns
I spent a decent amount of time trying to optimize the same sort of idea, and found that it really wasn't a good solution. There's just too much overhead between the page loads and viewflipper. In my case, I was able to get okay performance by loading each of the pages into one page sorted by CSS3 columns, and using fling to go between the columns. There's still a delay as the one big page gets rendered, but it was several times faster than loading each page into a viewflipper. That really wouldn't work with complicated html documents, though... mine just had text and a few images. - Turnsole

4 Answers

4
votes

Try this:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    webView.setLayerType(View.LAYER_TYPE_HARDWARE, null); 
} else {
    webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
3
votes

I think the following works best:

if (Build.VERSION.SDK_INT >= 19) {
    webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}       
else {
    webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}

Android 19 has Chromium engine for WebView. I guess it works better with hardware acceleration.

For more info Android 4.4 KitKat, the browser and the Chrome WebView

1
votes

This has already been discussed here: Enhance webView performance (should be the same performance as native Web Browser)

I ran into a similar issue, and after some heavy debugging noticed the native browser and WebView browser seem to be using different caches.

This code can be used to disable the WebView cache, and made WebView much faster for me (though at the expense of not caching). Note that it uses private APIs, so by using it you're risking the code will break in future releases:

try
{
  Method m = CacheManager.class.getDeclaredMethod("setCacheDisabled", boolean.class);
  m.setAccessible(true);
  m.invoke(null, true);
}
catch (Throwable e)
{
  Log.i("myapp","Reflection failed", e);
}
0
votes

Improvise Answer: The above Solution mentioned CacheManager.class is not supported.

 try {
            val m: Method = ServiceWorkerWebSettingsCompat.CacheMode::class.java.getDeclaredMethod(
                "setCacheDisabled",
                Boolean::class.javaPrimitiveType
            )
            m.isAccessible = true
            m.invoke(null, true)
        } catch (e: Throwable) {
            Log.i("myapp", "Reflection failed", e)
        }