I'm writing a game with javascript. This app runs well on my browser (fast), but I have some trouble to run that with android webview.
In the menu of the game I have a method like:
this.showCredits = function() {
document.getElementById('core-credits-layer').style.display = 'block';
document.getElementById('core-credits').style.display = 'block';
var parent = this;
$.ajax({
url: 'content/credits.html',
dataType: 'html',
success: function(data, status, response) {
var now = new Date();
var s = now.getSeconds()-parent.test.getSeconds();
console.log('success ajax: '+s);
document.getElementById('core-credits').scrollTop = 0;
document.getElementById('core-credits').innerHTML = response.responseText;
console.log('finished');
},
error: function() {
console.error('failed fetch credits');
}
});
}
So the console log ("finished", last line in success()), comes immediately after clicking the menu "credits". But it can takes 6s (more or less) until I see the the div #core-credits. In my browser, I see #core-credits immediately after clicking. But the 2nd time clicking on that menu point I get the div after 1-2s. I don't now what that is, I don't think so, that is a caching thing, because I get into the success() callback really fast.
Java side:
public void onCreate(Bundle savedInstanceState)
{
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Context context = this.getApplicationContext();
SharedPreferences wmbPreference = PreferenceManager.getDefaultSharedPreferences(this);
boolean isFirstRun = wmbPreference.getBoolean("FIRSTRUN", true);
if(isFirstRun) {
this.copyAudioFiles(context);
}
WebView mWebView = (WebView) findViewById(R.id.webview);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setDomStorageEnabled(true);
mWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
String data = context.getFilesDir().getPath();
mWebView.getSettings().setDatabasePath(data+"data/"+this.getPackageName()+"/databases/");
mWebView.getSettings().setAllowFileAccess(true);
mWebView.setWebChromeClient(new WebChromeClient());
String data_root = Environment.getExternalStorageDirectory()+"/"
+this.getPackageName();
mWebView.loadUrl("file:///android_asset/www/index.html?system=android&" +
"data_root="+data_root);
}
I have this performance problems on my virtual tablet device in eclipse and also on my real asus tablet.
Also animations (jquery show('slow')) are sometimes really slow or broken. For example (It is a card game), a player becomes 9 cards with the show('slow') animation, every 2nd or 3rd time I get 3 or 8 cards but not 9^^.
All this things above are working well on browsers like chromium or firefox. I'm working with Android 4.1.
Activate hardware acceleration didn't help. There are various posts about this rendering problem with webview, but only with the hardware accelaration solution, which didn't help.
I read about how to increase performance of WebView by implementing Caching web resources like JS, CSS and image files. You can also static resources in your native application, and by intercepting the Resource requests you can override the default behaviour of WebView.
setAppCacheEnabled(false); webview. getSettings(). setCacheMode(WebSettings. LOAD_NO_CACHE);
This interface was deprecated in API level 12. This interface is now obsolete.
UI Rendering is the act of generating a frame from your app and displaying it on the screen. To ensure that a user's interaction with your app is smooth, your app should render frames in under 16ms to achieve 60 frames per second (why 60fps?).
Forget about HW acceleration in this case - it's a false friend. In most cases it's even slower than software rendering.
But there are many small things you can optimise:
document.getElementById('core-credits')
in your codesetTimeout
directly) code execution and DOM manipulation (which always triggers redraws on single elements or - even worse - a reflow of the document)(-webkit-)box-shadow
, text-shadow and all kinds of gradients (which again one can exchange for old-school png's)Hope this helps - will try to elaborate more, resp. rectify information as i continue to fight android webview sluggishness in my own apps currently.
Having gone through the process of developing several apps using Hybrid Mobile App frameworks in HTML5/JS on Android, i'm afraid there isn't a silver bullet that will fix all performance issues. Generally speaking, Javascript performance is not the problem, the problem is frequent and maybe even wasteful changes/modifications to the DOM and a over-use of CSS3 effects which slow the FPS down like box-shadow on Android.
Something which might help, is to use CrossWalk as your WebView rather than the stock WebView component. This means you can get the latest version of Chrome inside your app without having to rely on older versions of the system WebView component. You should observe a performance and stability improvement as you can gain all the benefits of the software improvements to WebKit.
https://crosswalk-project.org
Secondly, consider using a framework which avoids frequent changes to the DOM like React which has a virtual DOM.
http://facebook.github.io/react/
React isn't the only framework to provide this and there are other solutions which aim to provide performance improvements in this area like Famous.
http://famous.org
Lastly, choosing your frameworks to build your app on top of is for me, the most important step. Despite all the investment in improving performance of browsers, they all vary in performance in different areas, so best to hedge your bets at the beginning and pick frameworks which suit the problem you are trying to solve.
Appreciate you may have moved on from this, so hoping this advice will help others.
#lovejavascript, #hatebrowsers
did you enable hardware accelaration in your manifest?: http://developer.android.com/guide/topics/graphics/hardware-accel.html ?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With