Visualizzazione web Android lenta


174

I miei android webviewssono lenti. Questo è su tutto, dai telefoni ai 3.0+tablet con specifiche più che adeguate

So che visualizzazioni dovrebbero essere "limitata" ma vedo Applicazioni Web fatto con gap telefono che deve utilizzare tutti i tipi di CSS3e JQuerystregoneria, corrono proprio bene e veloce

quindi mi manca qualcosa, c'è qualche tipo di myWebview.SPEEDHACK(1)che posso usare per accelerare le cose?

inoltre, a volte i contenuti della mia visualizzazione Web semplicemente non vengono caricati, invece di caricarsi lentamente, non vengono caricati. L'asset con cui sto testando viene archiviato localmente, senza errori.


3
Sembra che tu debba pubblicare del codice.
Jasoneer,

1
possibile duplicato delle prestazioni
Ken White,

1
@KenWhite tranne questa domanda ha più risposte, questa domanda ha risposte migliori e più complete, questa domanda ha il doppio delle visualizzazioni, entrambe le domande hanno più di due anni, la versione di Android entrambe le domande applicate sono obsolete ... cosa esci esattamente dal segnalare questo?
CQM,

@CQM: Questa domanda è stata contrassegnata automaticamente dal sistema a causa della risposta duplicata di George Mays di seguito. Se la sua risposta può essere ripetuta alla lettera come risposta a più post, uno di essi è un duplicato dell'altro. La domanda collegata è stata pubblicata (e risposta) prima in base alla data di pubblicazione. Un duplicato è un duplicato e il primo post era l'originale (e anche le risposte erano precedenti). Non ottengo nulla dalla segnalazione di questo (e non l'ho fatto in primo luogo).
Ken White,

1
Inoltre, non utilizzare l'evento click nelle tue app, aggiunge un ritardo di 300 ms per rispondere a ogni clic, per determinare che è un clic. Meglio usare invece il touchstart. Ho creato un clickhandler che utilizza due eventi e accetta il primo evento attivato. Uso 'touchstart click', quindi funziona anche senza touchscreen.
Codebeat

Risposte:


132

Dipende dall'applicazione Web caricata. Prova alcuni degli approcci di seguito:

Imposta una priorità di rendering più elevata (obsoleta dall'API 18+):

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

Abilita / disabilita l'accelerazione hardware:

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

Disabilita la cache (se hai problemi con i tuoi contenuti):

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

46
Capisco perché l'impostazione della priorità di rendering su alta lo renderebbe più veloce. ma perché disattivare la cache?
Dimas Kotvan,

39

6
Il link corretto per setRenderPriority è qui
Christopher Perry,

2
Dove inserisco questo codice nella mia app? Per favore
aiutatemi

6
perché spegni la cache?
Hassy31,

52

L'aggiunta di questo android:hardwareAccelerated="true"nel manifest è stata l'unica cosa che ha migliorato significativamente le prestazioni per me

Maggiori informazioni qui: http://developer.android.com/guide/topics/manifest/application-element.html#hwaccel


1
Questo è solo per API v11 / Android 3.xe successive
Ludwo,

6
Attenzione, c'è una WebView aperta con accelerazione hardware correlata ai bug, come indicato nella domanda stackoverflow.com/q/17059899/225341
Victor Ionescu

1
Ho notato che la disattivazione dell'accelerazione hardware rende la mia app più veloce. Con le android:hardwareAccelerated="true"animazioni CSS 3D i ritardi erano molto lunghi prima che iniziassero, lo scorrimento dei DIV all'interno di altri DIV scorrevoli non funzionava e l'app era più instabile.
Ernests Karlsons

1
il valore predefinito è "true" se hai impostato minSdkVersion o targetSdkVersion su "14" o superiore;
Vihaan Verma,

37

La soluzione per noi era l'opposto. Abbiamo disabilitato l'accelerazione hardware solo su WebView (anziché sull'intera app nel manifest) utilizzando questo codice:

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

Le animazioni CSS3 ora sono più fluide. Stiamo usando Android 4.0.

Maggiori informazioni qui: https://code.google.com/p/android/issues/detail?id=17352


4
Sfortunatamente, questo impedisce anche al componente video html5 di funzionare = /
Ja͢ck

Non ho notato. Abbiamo usato una visualizzazione video per riprodurre i video: fortunatamente avevamo solo bisogno di un video a schermo intero. Per ovviare al problema, è possibile avere la visualizzazione Web trasparente e una visualizzazione video in background, anche se so che non è la stessa cosa.
Ena,

1
C'è un altro problema con questa correzione. Mentre si tocca la visualizzazione Web, l'immagine diventa leggermente distorta. Ad esempio, se hai un'immagine con un cerchio, noterai dei piccoli quadrati (pixel) al posto della linea liscia. Posso dire che con Android 4.3 la correzione è inutile, non ha problemi di prestazioni.
Ena,

Mi dispiace un po 'nuovo per Android. Questo incollabile direttamente nel manifest di Android è che il file manifest è XML. O dovrebbe essere convalidato nel codice sorgente durante il caricamento della visualizzazione Web. Ci scusiamo per la domanda noob.
xMythicx,

1
Dopo aver aggiunto, ottenendo questo erroreWebView not displayed because it is too large to fit into a software layer (or drawing cache), needs 11534400 bytes, only 8294400 available
developer1011

14

Penso che quanto segue funzioni meglio:

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 ha il motore Chromium per WebView. Immagino che funzioni meglio con l'accelerazione hardware.


1
Questo ha funzionato per me su WebView con scarse animazioni e scrolling
cal

Sono io o il tuo "altro" fa lo stesso del tuo "se"?
Codebeat

Uno di Erwinus è per type_SOFTWARE e l'altro hardware
user2582318

9

Avevo lo stesso problema e ho dovuto risolverlo. Ho provato queste soluzioni, ma alla fine le prestazioni, almeno per lo scrolling, non sono migliorate affatto. Quindi ecco la soluzione che ho eseguito e la spiegazione del perché ha funzionato per me.

Se hai avuto la possibilità di esplorare gli eventi di trascinamento, solo un po ', creando una classe "MiWebView", sovrascrivendo il metodo "onTouchEvent" e almeno stampando il tempo in cui si verifica ogni evento di trascinamento, vedrai che sono separati in tempo per (fino a) 9ms di distanza. Questo è un tempo molto breve tra gli eventi.

Dai un'occhiata al codice sorgente di WebView e vedi solo la funzione onTouchEvent. È impossibile che sia gestito dal processore in meno di 9ms (Continua a sognare !!!). Ecco perché vedi costantemente "Miss un trascinamento mentre stiamo aspettando la risposta di WebCore per il touchdown". Messaggio. Il codice non può essere gestito in tempo.

Come sistemarlo? Innanzitutto, non è possibile riscrivere il codice onTouchEvent per migliorarlo, è semplicemente troppo. Ma puoi "deriderlo" per limitare la frequenza degli eventi per trascinare i movimenti, diciamo a 40ms o 50ms. (questo dipende dal processore).

Tutti gli eventi touch vanno così: ACTION_DOWN -> ACTION_MOVE ...... ACTION_MOVE -> ACTION_UP. Quindi dobbiamo mantenere i movimenti DOWN e UP e filtrare il MOVE rate (questi sono i cattivi).

Ed ecco un modo per farlo (puoi aggiungere altri tipi di eventi come il tocco di 2 dita, tutto ciò che mi interessa qui è lo scorrimento con un solo dito).

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

Naturalmente usa questa classe invece di WebView e vedrai la differenza durante lo scorrimento.

Questo è solo un approccio a una soluzione, ma non è ancora completamente implementato per tutti i casi di ritardo a causa del tocco dello schermo quando si utilizza WebView. Tuttavia è la migliore soluzione che ho trovato, almeno per le mie esigenze specifiche.


Vorrei sottolineare che il codice sorgente della webview che hai pubblicato è del 2010
CQM,

Questo non funziona, non scorre uniformemente, non riesco a sentire la differenza.
Neevek,

Ho implementato questa impostazione fino a 80, ma in realtà non sembra migliorare le prestazioni ma cattura alcuni eventi di movimento. Cosa fa per te?
Ragnar,

Ho letto che un evento clic è 6 volte più lento del touchstart dell'evento touch. Per evitare ritardi è possibile utilizzare $ ('pulsante #'). On ('clic touchstart', function () {azione qui; return false;});
Codebeat

Inoltre, non utilizzare l'evento click nelle tue app html, aggiunge un ritardo di 300 ms per rispondere a ogni clic, per determinare che è un clic. Meglio usare invece il touchstart. Ho creato un clickhandler che utilizza due eventi e accetta il primo evento attivato. Uso 'touchstart click', quindi funziona ancora senza touchscreen.
Codebeat

9

Ho provato tutte le proposte per risolvere il problema delle prestazioni di rendering nella mia app phonegap. Ma nulla ha funzionato davvero.

Alla fine, dopo un'intera giornata di ricerche, ce l'ho fatta. Ho impostato il tag (non il tag) del mio AndroidManifest

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

Ora l'app si comporta nello stesso modo veloce del mio browser web. Sembra che, se l'accelerazione hardware non è sempre la migliore funzionalità ...

Il problema dettagliato che ho avuto: https://stackoverflow.com/a/24467920/3595386


2
Disabilitare l'accelerazione hardware è stato orribile per me, la visualizzazione web è stata così lenta nello scorrimento
AbdelHady

5

Nessuna di queste risposte non mi è stata utile.

Finalmente ho trovato ragione e soluzione. Il motivo erano molti filtri CSS3 (filtro, filtro -webkit).

Soluzione

Ho aggiunto il rilevamento di WebView nello script della pagina Web per aggiungere la classe "bassa qualità" al corpo HTML. BTW. È possibile monitorare facilmente WebView impostando user-agent nelle impostazioni di WebView. Quindi ho creato una nuova regola CSS

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

Strano quando 5 anni dopo ci sono pochissimi motivi per usare la visualizzazione web nonostante i dispositivi siano più veloci, le prestazioni più compatibili con i browser mobili sono notevolmente migliorate e altri motivi. Grazie per averci esaminato!
CQM,

@CQM Ho avuto lo stesso problema, ho trovato una soluzione quindi volevo condividerla :)
l00k

Sono solo faceto, questa è una delle mie domande più antiche, grazie ancora!
CQM,

1
È assurdo che questo sia un problema nel 2016/2017. Nessuno dei filtri CSS dovrebbe essere impegnativo per qualsiasi GPU mobile.
Adam Leggett,

4

Se ci sono solo alcuni componenti della tua visualizzazione Web che sono lenti o lenti, prova ad aggiungere questo agli elementi css:

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

Questo è stato l'unico speedhack che ha davvero avuto un effetto sulla mia webview. Ma fai attenzione a non abusarne! (puoi leggere di più sull'hacking in questo articolo .)


1
Usa will-change: transform.
Adam Leggett,


3

Se stai vincolando l' onclickevento, potrebbe essere lento sui touchscreen.

Per renderlo più veloce, utilizzo fastclick , che utilizza gli eventi touch molto più veloci per imitare l'evento click.


fastclick non è più in fase di sviluppo ... sì, gli eventi tattili sono lenti e avevo solo bisogno che funzionasse e ho trovato con jquery che il problema della velocità può essere risolto usando $('#').on('touchstart', function() {...});al contrario di onclick
CrandellWS
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.