I've written an app mostly in JS (Mootools) and HTML which is loaded into webview
in my app.
It's just one html file which show or hide parts (elements) of the page by adding or removing a nodisplay
class:
.nodisplay {display:none}
function showPage1()
{
$$('.pages').addClass('nodisplay');
$('page1').removeClass('nodisplay');
}
In android 4 (xperia arc and galaxy note 2) I see a strange late rendering, but I don't know how older versions behave. when I hide an element and show another one, it appears correct at first but during scrolling some parts of the old elements appears for milliseconds and disappears immediately. It's like the render of non visible area is postponed to drawing moment.
And also sometime it just do odd blinks during hiding and showing.
In chrome on PC it don't have any problem. Even in the AVD it works very sharp without any blinks.
I don't know if it's a problem of android and if there is any way to overcome it?!
I tried android:hardwareAccelerated="false"|"true"
, no effect.
and also ws.enableSmoothTransition()
which doesn't solve the problem neither.
I've written an app mostly in JS (Mootools) and HTML which is loaded into webview
in my app.
It's just one html file which show or hide parts (elements) of the page by adding or removing a nodisplay
class:
.nodisplay {display:none}
function showPage1()
{
$$('.pages').addClass('nodisplay');
$('page1').removeClass('nodisplay');
}
In android 4 (xperia arc and galaxy note 2) I see a strange late rendering, but I don't know how older versions behave. when I hide an element and show another one, it appears correct at first but during scrolling some parts of the old elements appears for milliseconds and disappears immediately. It's like the render of non visible area is postponed to drawing moment.
And also sometime it just do odd blinks during hiding and showing.
In chrome on PC it don't have any problem. Even in the AVD it works very sharp without any blinks.
I don't know if it's a problem of android and if there is any way to overcome it?!
I tried android:hardwareAccelerated="false"|"true"
, no effect.
and also ws.enableSmoothTransition()
which doesn't solve the problem neither.
5 Answers
Reset to default 10Here is my "Fix your webview app in one stack answer (first edition)":
Performance
Keep references to your page elements in JS to improve performance. $('.page1')
has to parse the DOM each time you change the page and this should only happen once. This also goes for $('.pages')
- it has to scan & perform operations on multiple elements. Instead i suggest you keep a active page reference. Maybe it should look something like this:
function showPage(page) { // receive active page; page is the jQuery ref to the next page
activePage.addClass('nodisplay'); // activePage is the jQuery ref to the previous page
page.removeClass('nodisplay'); // show the page
}
You should scan your entire app and fix this kind of problems. They may not seem like a big deal but i am confident they can make the difference in a mobile OS where resources are limited.
DOM management
If you aren't already, you should definitely use templates. Aside from helping you manage your app, templates help keeping the DOM as lightweight as possible: instead of having 100 page elements you can start with 0 and create them on the fly when needed. To achieve maximum performance make sure you render every template only once - before rendering check if the page already exists in the DOM. To see how this affects your app just google "browser reflow".
There are a lot of tools for this job. Considering you current setup you could opt for: http://mootools.net/forge/p/template. Here are some other options: http://mustache.github.com/ , http://underscorejs.org/#template , http://api.jquery.com/category/plugins/templates/ .
UI
Also very important but very vast. Some things to keep in mind:
- lightweight, semantic and valid markup
- js should only manage data & state. Animations and DOM updates will slow you down. Make use of the css3 friendly environment
- optimize images and try to use them only as visuals. If you can't avoid this, sprites are always a good idea.
Debugging
Can be painful. I found weinre very useful: http://people.apache.org/~pmuellr/weinre/docs/latest/ . The try ... catch
block rules!
Something to help with logcat output: http://jsharkey.org/blog/2009/04/22/modifying-the-android-logcat-stream-for-full-color-debugging/.
Bottom line, the webview is still a harsh environment and although lately it has become a feasible option, it requires a lot of thought and planning in order to "get it right".
Hope this helps.
I don't know much about html with webkit. But one of my project was having the same scroll issues with lag in hide and show scroll effects. I have enable hardware acceleration for the webview.
Probably you should try this.
.nodisplay {height:0; display:none; }
worked here...
try this code also, it helped me alot..
-webkit-transform: translateZ(0);
you can have a look at my code in which it helped me..
jquery toggle (show/hide) based on selector
Also have a look at the link below; http://www.html5rocks.com/en/mobile/optimization-and-performance/
Ajay answer gave me a hint of something I used in another project so I could make WebView
background transparent. Till now I didn't know that code turns off hardware acceleration. I tested that peace of code in this project and there is no late rendering anymore. although scrolling the page is not as smooth as before but it's better than late rendering.
This is the code to fix all of this:
if (Build.VERSION.SDK_INT >= 11) wv.setLayerType(WebView.LAYER_TYPE_SOFTWARE, null);
By the way, it's like defining android:hardwareAccelerated="false"
doesn't affect webview
!