179 votes

Android webview lent

Mon android webviews sont lents. C'est le cas sur tout, des téléphones aux 3.0+ des tablettes aux spécifications plus qu'adéquates

Je sais que les webviews sont censés être "limités", mais je vois des applications web réalisées avec un gap de téléphone qui doivent utiliser toutes sortes de CSS3 y JQuery la sorcellerie, ils fonctionnent très bien et rapidement

donc je rate quelque chose, est-ce qu'il y a 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. La ressource que je teste est stockée localement, sans erreur.

3 votes

On dirait que vous avez besoin de poster du code.

1 votes

Duplication possible de Performances des WebViews Android

1 votes

@KenWhite sauf que cette question a plus de réponses, cette question a des réponses meilleures et plus complètes, cette question a deux fois plus de vues, les deux questions ont plus de deux ans, la version d'Android à laquelle ces deux questions s'appliquaient sont obsolètes... qu'est-ce que ça vous apporte exactement de signaler ça ?

136voto

peceps Points 7246

Cela dépend de l'application web qui est chargée. Essayez certaines des approches ci-dessous :

Définir une priorité de rendu plus élevée (déprécié à partir de l'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ésactivez le cache (si vous avez des problèmes avec votre contenu) :

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

47 votes

Je comprends pourquoi mettre la priorité de rendu à un niveau élevé le rendrait plus rapide. Mais pourquoi désactiver le cache ?

42 votes

La méthode setRederPriority est obsolète, voir developer.Android.com/reference/Android/webkit/WebSettings.html

6 votes

Le lien correct pour setRenderPriority est le suivant aquí

54voto

Sender Points 191

En ajoutant ceci android:hardwareAccelerated="true" dans le manifeste est la seule chose qui a amélioré significativement les performances pour moi.

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

1 votes

Ceci est seulement pour API v11/Android 3.x et plus.

6 votes

Faites attention, il y a un bogue ouvert lié au matériel WebViews accéléré, comme indiqué dans la question. stackoverflow.com/q/17059899/225341

1 votes

J'ai remarqué que la désactivation de l'accélération matérielle rendait mon application plus rapide. Avec android:hardwareAccelerated="true" Les animations CSS 3D avaient de longs délais avant de démarrer, le défilement de DIVs à l'intérieur d'autres DIVs déroulants ne fonctionnait pas, et l'application était plus instable.

37voto

Ena Points 797

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

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

Les animations CSS3 sont désormais plus fluides. Nous utilisons Android 4.0.

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

4 votes

Malheureusement, cela empêche également le composant vidéo html5 de fonctionner =/

0 votes

Je n'ai pas remarqué. Nous avons utilisé une vue vidéo pour lire des vidéos : heureusement, nous n'avions besoin que d'une vidéo en plein écran. Comme solution de contournement, il est possible d'avoir la vue Web transparente et une vue vidéo en arrière-plan, même si je sais que ce n'est pas la même chose.

1 votes

Il y a un autre problème avec cette solution. Lorsque l'on touche le webview, le graphique est un peu déformé. Par exemple, si vous avez une image avec un cercle, vous remarquerez des petits carrés (pixels) à la place de la ligne lisse. Je peux dire qu'avec Android 4.3 le correctif est inutile, il n'a pas de problèmes de performance.

10voto

user3595386 Points 16

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 recherche, j'ai réussi. J'ai placé dans le tag (pas le tag) de mon AndroidManifest

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

Maintenant l'application se comporte de la même façon rapide que mon navigateur web. Il semble 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

2 votes

La désactivation de l'accélération matérielle n'a rien donné, le défilement de la vue web était très lent.

9voto

Nate Castro Points 71

J'avais le même problème et je devais le résoudre. J'ai essayé ces solutions, mais à la fin les performances, au moins pour le défilement, ne se sont pas améliorées du tout. Voici donc le travail que j'ai effectué et l'explication de la raison pour laquelle cela a fonctionné pour moi.

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

Jetez un coup d'œil à la Code source du WebView et voir la fonction onTouchEvent. Il est tout simplement impossible qu'elle soit traitée par le processeur en moins de 9ms (Continuez à rêver ! !!). C'est pourquoi vous voyez constamment le message "Miss a drag as we are waiting for WebCore's response for touch down". Le code ne peut tout simplement pas être traité à temps.

Comment le réparer ? Tout d'abord, vous ne pouvez pas réécrire le code onTouchEvent pour l'améliorer, c'est tout simplement trop. Mais vous pouvez le "simuler" afin de limiter la fréquence des événements pour les mouvements de glisser, disons à 40 ms ou 50 ms (cela dépend du processeur).

Tous les événements de contact se passent comme ça : ACTION_DOWN -> ACTION_MOVE......ACTION_MOVE -> ACTION_UP. Nous devons donc conserver les mouvements DOWN et UP et filtrer le taux de MOVE (ce sont les mauvais élèves).

Et voici une façon de le faire (vous pouvez ajouter d'autres types d'événements comme le toucher à deux doigts, tout ce qui m'intéresse ici est le défilement à un seul 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 à la place de WebView et vous verrez la différence lors du défilement.

Il ne s'agit que d'une approche de la solution, qui n'est pas encore totalement mise en œuvre pour tous les cas de décalage dus au toucher de l'écran lors de l'utilisation de WebView. Cependant, c'est la meilleure solution que j'ai trouvée, du moins pour mes besoins spécifiques.

0 votes

Je tiens à souligner que le code source de webview que vous avez posté est de 2010

0 votes

Cela ne fonctionne pas, cela ne lisse pas le défilement, je ne sens pas la différence.

0 votes

J'ai mis en place ce système en fixant la limite à 80, mais cela ne semble pas améliorer les performances, mais cela permet d'attraper certains événements de déplacement. Qu'est-ce que cela fait pour vous ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X