Android Webview langsam

174

Meine android webviewssind langsam. Dies gilt für alle Geräte, von Telefonen bis hin zu 3.0+Tablets mit mehr als angemessenen technischen Daten

Ich weiß , dass WebViews soll „begrenzt“ werden , aber ich sehe , Web - Anwendungen mit Telefon Lücke durchgeführt , die alle möglichen verwenden müssen CSS3und JQueryZauberei, laufen sie einfach gut und schnell

Ich vermisse also etwas. Gibt es eine Art, mit der myWebview.SPEEDHACK(1)ich die Dinge beschleunigen kann?

Außerdem wird der Inhalt meiner Webansicht manchmal einfach nicht geladen, anstatt langsam zu laden, wird er einfach nicht geladen. Das Asset, mit dem ich teste, wird lokal gespeichert, keine Fehler.

CQM
quelle
3
Klingt so, als müssten Sie Code posten.
Jasoneer
1
Mögliches Duplikat der Android WebView-Leistung
Ken White
1
@ KenWhite außer diese Frage hat mehr Antworten, diese Frage hat bessere und umfassendere Antworten, diese Frage hat doppelt so viele Ansichten, beide Fragen sind über zwei Jahre alt, die Version von Android, auf die beide Fragen angewendet wurden, sind veraltet ... was Genau das schaffen Sie es, dies zu melden?
CQM
@CQM: Diese Frage wurde vom System aufgrund der doppelten Antwort von George Mays unten automatisch markiert. Wenn seine Antwort wörtlich als Antwort auf mehrere Beiträge wiederholt werden kann, ist einer von ihnen ein Duplikat des anderen. Die verknüpfte Frage wurde zuerst basierend auf dem Veröffentlichungsdatum veröffentlicht (und beantwortet). Ein Duplikat ist ein Duplikat, und der erste Beitrag war das Original (und die Antworten waren auch früher). Ich habe nichts davon, dies zu melden (und habe es überhaupt nicht getan).
Ken White
1
Verwenden Sie das Klickereignis auch nicht in Ihren Apps. Es wird eine Verzögerung von 300 ms hinzugefügt, um auf jeden Klick zu reagieren und festzustellen, ob es sich um einen Klick handelt. Verwenden Sie stattdessen lieber Touchstart. Ich habe einen Clickhandler erstellt, der zwei Ereignisse verwendet und das erste ausgelöste Ereignis ausführt. Ich benutze 'Touchstart Click', daher funktioniert es auch ohne Touchscreen.
Codebeat

Antworten:

132

Dies hängt von der geladenen Webanwendung ab. Probieren Sie einige der folgenden Ansätze aus:

Legen Sie eine höhere Renderpriorität fest (veraltet von API 18+):

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

Aktivieren / Deaktivieren der Hardwarebeschleunigung:

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);
}

Deaktivieren Sie den Cache (wenn Sie Probleme mit Ihrem Inhalt haben):

webview.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
Peceps
quelle
46
Ich verstehe, warum das Setzen der Renderpriorität auf hoch es schneller machen würde. aber warum den Cache ausschalten?
Dimas Kotvan
39
Die Methode setRederPriority ist veraltet, siehe developer.android.com/reference/android/webkit/WebSettings.html
Victor Ionescu
6
Der richtige Link für setRenderPriority ist hier
Christopher Perry
2
Wo füge ich diesen Code in meine App ein? Bitte helfen Sie - ich habe das gleiche Problem auf Mission Critical WebView
Levchik
6
Warum schaltest du den Cache aus?
Hassy31
52

Das Hinzufügen android:hardwareAccelerated="true"in das Manifest war das einzige, was die Leistung für mich signifikant verbessert hat

Weitere Informationen hier: http://developer.android.com/guide/topics/manifest/application-element.html#hwaccel

Absender
quelle
1
Dies ist nur für API v11 / Android 3.x und höher
Ludwo
6
Seien Sie vorsichtig, es gibt einen offenen Fehler im Zusammenhang mit hardwarebeschleunigten WebViews, wie in der Frage stackoverflow.com/q/17059899/225341
Victor Ionescu
1
Ich habe festgestellt, dass das Deaktivieren der Hardwarebeschleunigung meine App tatsächlich schneller macht. Mit android:hardwareAccelerated="true"CSS hatten 3D-Animationen lange Verzögerungen, bevor sie gestartet wurden. Das Scrollen von DIVs in anderen scrollbaren DIVs funktionierte nicht und die App war instabiler.
Ernests Karlsons
1
Der Standardwert ist "true", wenn Sie entweder minSdkVersion oder targetSdkVersion auf "14" oder höher festgelegt haben.
Vihaan Verma
37

Die Lösung für uns war das Gegenteil. Wir haben die Hardwarebeschleunigung nur in WebView (und nicht in der gesamten App im Manifest) mithilfe dieses Codes deaktiviert:

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

CSS3-Animationen sind jetzt flüssiger. Wir verwenden Android 4.0.

Weitere Informationen finden Sie hier: https://code.google.com/p/android/issues/detail?id=17352

Ena
quelle
4
Leider verhindert dies auch, dass die HTML5-Videokomponente funktioniert = /
Ja͢ck
Ich habe es nicht bemerkt. Wir haben eine Videoansicht verwendet, um Videos abzuspielen: Zum Glück brauchten wir nur ein Vollbildvideo. Um dieses Problem zu umgehen, ist es möglich, dass die Webansicht transparent ist und eine Videoansicht im Hintergrund abgespielt wird, obwohl ich weiß, dass dies nicht dasselbe ist.
Ena
1
Es gibt ein weiteres Problem mit diesem Fix. Beim Berühren der Webansicht wird die Grafik etwas verzerrt. Wenn Sie beispielsweise ein Bild mit einem Kreis haben, werden Sie anstelle der glatten Linie kleine Quadrate (Pixel) darauf bemerken. Ich kann sagen, dass mit Android 4.3 Fix nutzlos ist, es hat keine Leistungsprobleme.
Ena
Sorry ein bisschen neu bei Android. Ist dies direkt im Android-Manifest einfügbar, da die Manifest-Datei XML ist? Oder soll dies beim Laden der Webansicht im Quellcode überprüft werden? Entschuldigung für die Noob-Frage.
xMythicx
1
Nach dem Hinzufügen erhalten Sie diesen FehlerWebView not displayed because it is too large to fit into a software layer (or drawing cache), needs 11534400 bytes, only 8294400 available
Entwickler1011
14

Ich denke, das funktioniert am besten:

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 verfügt über eine Chromium-Engine für WebView. Ich denke, es funktioniert besser mit Hardwarebeschleunigung.

Tedi
quelle
1
Das ist für mich gearbeitet WebViews mit schlechten Animationen und Scrollen
cal
Bin ich es oder macht dein "Sonst" dasselbe wie dein "Wenn"?
Codebeat
Erwinus eins ist für type_SOFTWARE und die andere Hardware
user2582318
9

Ich hatte das gleiche Problem und musste es klären. Ich habe diese Lösungen ausprobiert, aber am Ende hat sich die Leistung, zumindest beim Scrollen, überhaupt nicht verbessert. Also hier die Arbeit, die ich gemacht habe und die Erklärung, warum es für mich funktioniert hat.

Wenn Sie die Möglichkeit hatten, die Drag-Ereignisse ein wenig zu erkunden, indem Sie eine "MiWebView" -Klasse erstellt, die "onTouchEvent" -Methode überschrieben und zumindest die Zeit gedruckt haben, in der jedes Drag-Ereignis auftritt, werden Sie feststellen, dass sie getrennt sind rechtzeitig für (bis zu) 9ms entfernt. Das ist eine sehr kurze Zeit zwischen den Ereignissen.

Schauen Sie sich den WebView-Quellcode an und sehen Sie sich nur die Funktion onTouchEvent an. Es ist einfach unmöglich, dass es vom Prozessor in weniger als 9 ms gehandhabt wird (Träumen Sie weiter !!!). Aus diesem Grund wird ständig die Meldung "Miss a Drag, während wir auf die Antwort von WebCore auf das Aufsetzen warten" angezeigt. Botschaft. Der Code kann einfach nicht rechtzeitig verarbeitet werden.

Wie man es repariert? Erstens können Sie den onTouchEvent-Code nicht neu schreiben, um ihn zu verbessern. Er ist einfach zu viel. Sie können es jedoch "verspotten", um die Ereignisrate für das Ziehen von Bewegungen auf 40 ms oder 50 ms zu begrenzen. (Dies hängt vom Prozessor ab).

Alle Berührungsereignisse sehen folgendermaßen aus: ACTION_DOWN -> ACTION_MOVE ...... ACTION_MOVE -> ACTION_UP. Also müssen wir die DOWN- und UP-Bewegungen beibehalten und die MOVE-Rate filtern (das sind die Bösen).

Und hier ist eine Möglichkeit, dies zu tun (Sie können weitere Ereignistypen hinzufügen, z. B. 2 Finger berühren. Alles, was mich hier interessiert, ist das Scrollen mit einem Finger).

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;
    }
}

Wenn Sie diese Klasse anstelle von WebView verwenden, werden Sie beim Scrollen den Unterschied feststellen.

Dies ist nur ein Lösungsansatz, der jedoch aufgrund von Bildschirmberührungen bei Verwendung von WebView noch nicht für alle Verzögerungsfälle vollständig implementiert ist. Es ist jedoch die beste Lösung, die ich gefunden habe, zumindest für meine spezifischen Bedürfnisse.

Nate Castro
quelle
Ich möchte darauf hinweisen, dass der von Ihnen veröffentlichte Webview-Quellcode aus dem Jahr 2010 stammt
CQM
Dies funktioniert nicht, es funktioniert nicht reibungslos, ich kann den Unterschied nicht spüren.
Neevek
Ich habe diese Einstellung implementiert, um das Limit auf 80 zu setzen, aber es scheint die Leistung nicht zu verbessern, aber es fängt einige Bewegungsereignisse ab. Was macht es für Sie?
Ragnar
Habe gelesen, dass ein Klickereignis sechsmal langsamer ist als das Berührungsereignis. Um Verzögerungen zu vermeiden, können Sie $ ('# button') verwenden. On ('touchstart click', function () {Aktion hier; return false;});
Codebeat
Verwenden Sie das Klickereignis auch nicht in Ihren HTML-Apps. Es wird eine Verzögerung von 300 ms hinzugefügt, um auf jeden Klick zu reagieren und festzustellen, ob es sich um einen Klick handelt. Verwenden Sie stattdessen lieber Touchstart. Ich habe einen Clickhandler erstellt, der zwei Ereignisse verwendet und das erste ausgelöste Ereignis ausführt. Ich verwende 'Touchstart-Klick', daher funktioniert es immer noch ohne Touchscreen.
Codebeat
9

Ich habe alle Vorschläge ausprobiert, um das Renderleistungsproblem in meiner Phonegap-App zu beheben. Aber nichts hat wirklich funktioniert.

Nach einem ganzen Tag der Suche habe ich es endlich geschafft. Ich setze innerhalb des Tags (nicht des Tags) meines AndroidManifest

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

Jetzt verhält sich die App genauso schnell wie mein Webbrowser. Scheint so, als ob Hardwarebeschleunigung nicht immer die beste Funktion ist ...

Das detaillierte Problem, das ich hatte: https://stackoverflow.com/a/24467920/3595386

user3595386
quelle
2
Das Deaktivieren der Hardwarebeschleunigung war für mich schrecklich, die Webansicht war beim Scrollen so langsam
AbdelHady
5

Keine dieser Antworten war für mich nicht hilfreich.

Endlich habe ich Grund und Lösung gefunden. Der Grund waren viele CSS3-Filter (Filter, -webkit-Filter).

Lösung

Ich habe die Erkennung von WebView im Webseiten-Skript hinzugefügt, um dem HTML-Body die Klasse "lowquality" hinzuzufügen. Übrigens. Sie können WebView einfach verfolgen, indem Sie den Benutzeragenten in den WebView-Einstellungen festlegen. Dann habe ich eine neue CSS-Regel erstellt

body.lowquality * { filter: none !important; }
100k
quelle
Umständlich, wenn es 5 Jahre später nur sehr wenige Gründe gibt, die Webansicht zu verwenden, obwohl die Geräte schneller sind, die Leistung mit mobilen Browsern kompatibel ist und andere Gründe erheblich verbessert wurden. Vielen Dank, dass Sie sich damit befasst haben!
CQM
@CQM Ich hatte das gleiche Problem, ich fand eine Lösung, also wollte ich es teilen :)
100k
Ich bin nur scherzhaft, dies ist eine meiner ältesten Fragen, nochmals vielen Dank!
CQM
1
Es ist absurd, dass dies 2016/2017 ein Problem ist. Keiner der CSS-Filter sollte für eine mobile GPU eine Herausforderung darstellen.
Adam Leggett
4

Wenn nur einige wenige Komponenten Ihrer Webansicht langsam oder verzögert sind, fügen Sie diese zu den Elementen CSS hinzu:

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

Dies war der einzige Speedhack, der sich wirklich auf meine Webansicht ausgewirkt hat. Aber achten Sie darauf, es nicht zu überbeanspruchen! (Weitere Informationen zum Hack finden Sie in diesem Artikel .)

Erex
quelle
1
Verwenden Sie will-change: transform.
Adam Leggett
3

Versuche dies:

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

Wenn Sie an das onclickEreignis gebunden sind , kann es auf Touchscreens langsam sein.

Um es schneller zu machen, verwende ich fastclick , das die viel schnelleren Berührungsereignisse verwendet, um das Klickereignis nachzuahmen.

Tzach
quelle
Fastclick wird nicht mehr entwickelt ... Ja, die Touch-Ereignisse sind langsam und ich brauchte es nur, um zu funktionieren. Mit jquery konnte das Geschwindigkeitsproblem $('#').on('touchstart', function() {...});im Gegensatz zu onclick umgangen werden
CrandellWS