web-dev-qa-db-fra.com

Android webview lent

Mes Android webviews sont lents. Cela concerne tout, des téléphones aux 3.0+ tablettes aux spécifications plus que suffisantes

Je sais que les vues Web sont censées être "limitées", mais je vois des applications Web réalisées avec une lacune téléphonique qui doit utiliser toutes sortes de CSS3 et JQuery rituels, elles fonctionnent parfaitement et rapidement.

alors il me manque quelque chose, y a-t-il une sorte de myWebview.SPEEDHACK(1) que je peux utiliser pour accélérer les choses?

de plus, parfois, le contenu de ma vue Web ne se charge tout simplement pas, au lieu de se charger lentement, il ne se charge tout simplement pas. L'actif avec lequel je teste est stocké localement, pas d'erreur.

164
CQM

Cela dépend de l'application Web en cours de chargement. Essayez certaines des approches ci-dessous:

Définir une priorité de rendu plus élevée (obsolète d'API 18 +):

webview.getSettings().setRenderPriority(RenderPriority.HIGH);

Activer/désactiver l'accélération matérielle:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KitKat) {
    // chromium, enable hardware acceleration
    webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
} else {
    // older Android version, disable hardware acceleration
    webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}

Désactive le cache (si vous avez des problèmes avec votre contenu):

webview.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
126
peceps

L'ajout de ce Android:hardwareAccelerated="true" dans le manifeste était la seule chose qui améliorait considérablement les performances pour moi.

Plus d'infos ici: http://developer.Android.com/guide/topics/manifest/application-element.html#hwaccel

50
Sender

La solution pour nous était le contraire. Nous avons désactivé l'accélération matérielle uniquement sur WebView (plutôt que sur l'ensemble de l'application dans le manifeste) en utilisant ce code:

if (Build.VERSION.SDK_INT >= 11){
    webview.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}

Les animations CSS3 sont plus fluides maintenant. Nous utilisons Android 4.0.

Plus d'infos ici: https://code.google.com/p/Android/issues/detail?id=17352

35
Ena

Je pense que ce qui suit fonctionne le mieux:

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

Android 19 a le moteur de chrome pour WebView. Je suppose que cela fonctionne mieux avec l'accélération matérielle.

13
Tedi

J'avais le même problème et je devais régler le problème. J'ai essayé ces solutions, mais à la fin, la performance, du moins pour le défilement, ne s'est pas améliorée du tout. Donc voici le workaroud que j'ai joué et l'explication de la raison pour laquelle cela a fonctionné pour moi.

Si vous avez eu l'occasion d'explorer un peu les événements de glisser en créant une classe "MiWebView", en écrasant la méthode "onTouchEvent" et en imprimant au moins l'heure à laquelle chaque événement de glisser se produit, vous verrez qu'ils sont séparés. à temps pour (jusqu'à) 9ms. C'est très peu de temps entre les événements.

Jetez un coup d'œil au Code source WebView , et voyez simplement la fonction onTouchEvent. Il est tout simplement impossible qu’il soit traité par le processeur en moins de 9 ms (Continuez à rêver !!!). C'est pourquoi vous voyez constamment le message "Mlle ratée, car nous attendons la réponse de WebCore pour le toucher." message. Le code ne peut tout simplement pas être traité à temps.

Comment le réparer? Premièrement, vous ne pouvez pas réécrire le code onTouchEvent pour l’améliorer, c’est trop. Mais vous pouvez "vous moquer" afin de limiter le taux d’événements pour les mouvements de déplacement, disons à 40 ms ou 50 ms. (cela dépend du processeur).

Tous les événements tactiles vont comme ceci: ACTION_DOWN -> ACTION_MOVE ...... ACTION_MOVE -> ACTION_UP. Il faut donc garder les mouvements DOWN et UP et filtrer le taux de MOVE (ce sont les méchants).

Et voici une façon de le faire (vous pouvez ajouter plus de types d’événements comme toucher deux doigts, tout ce qui m’intéresse ici, c’est le défilement à un doigt).

import Android.content.Context;
import Android.view.MotionEvent;
import Android.webkit.WebView;


public class MyWebView extends WebView{

    public MyWebView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    private long lastMoveEventTime = -1;
    private int eventTimeInterval = 40;

    @Override
    public boolean onTouchEvent(MotionEvent ev) {

        long eventTime = ev.getEventTime();
        int action = ev.getAction();

        switch (action){
            case MotionEvent.ACTION_MOVE: {
                if ((eventTime - lastMoveEventTime) > eventTimeInterval){
                    lastMoveEventTime = eventTime;
                    return super.onTouchEvent(ev);
                }
                break;
            }
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_UP: {
                return super.onTouchEvent(ev);
            }
        }
        return true;
    }
}

Bien sûr, utilisez cette classe au lieu de WebView et vous verrez la différence lors du défilement.

Il ne s’agit que d’une approche de solution, mais qui n’a pas encore été totalement implémentée pour tous les cas de latence, car les écrans se touchent lorsque WebView est utilisé. Cependant, c'est la meilleure solution que j'ai trouvée, du moins pour mes besoins spécifiques.

9
Nate Castro

J'ai essayé toutes les propositions pour résoudre le problème de performance de rendu dans mon application phonegap. Mais rien n'a vraiment fonctionné.

Finalement, après une journée entière de recherches, je l’ai faite. Je mets dans la balise (pas la balise) de mon AndroidManifest

<application Android:hardwareAccelerated="false" ...

Maintenant, l'application se comporte de la même manière rapide que mon navigateur Web. On dirait que si l'accélération matérielle n'est pas toujours la meilleure fonctionnalité ...

Le problème détaillé que j'ai eu: https://stackoverflow.com/a/24467920/3595386

8
user3595386

Aucune de ces réponses ne m'a été utile.

Enfin j'ai trouvé la raison et la solution. La raison en était beaucoup de filtres CSS3 (filtre, -webkit-filtre).

Solution

J'ai ajouté la détection de WebView dans un script de page Web afin d'ajouter la classe "lowquality" au corps HTML. BTW. Vous pouvez facilement suivre WebView en définissant l'agent utilisateur dans les paramètres WebView. Puis j'ai créé une nouvelle règle CSS

body.lowquality * { filter: none !important; }
4
l00k

S'il n'y a que quelques composants de votre vue Web qui sont lents ou lents, essayez d'ajouter ceci aux éléments css:

transform: translate3d(0,0,0);
-webkit-transform: translate3d(0,0,0);

Cela a été le seul speedhack qui a vraiment eu un effet sur ma visualisation Web. Mais attention à ne pas en abuser! (Vous pouvez en savoir plus sur le hack dans cet article .)

4
Erex

Essaye ça:

mWebView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
3
George Maisuradze

Si vous vous liez à l'événement onclick, il est possible qu'il soit lent sur les écrans tactiles.

Pour accélérer les choses, j'utilise fastclick , qui utilise les événements tactiles beaucoup plus rapides pour imiter l'événement click.

2
Tzach