Веб-перегляд Android повільно


174

Мої android webviewsповільні. Це є на всьому, від телефонів до 3.0+планшетів із більш ніж адекватними характеристиками

Я знаю, що веб-перегляди повинні бути "обмеженими", але я бачу, що веб-додатки робляться з розривом у телефоні, який повинен використовувати всілякі CSS3та JQueryчаклунські роботи, вони працюють просто чудово і швидко

тому я щось пропускаю, чи є щось таке, myWebview.SPEEDHACK(1)що я можу використати для прискорення речей?

Крім того, іноді вміст мого веб-перегляду просто не завантажується, а не повільно завантажується, він просто не завантажується. Актив, з яким я тестую, зберігається локально, помилок немає.


3
Здається, вам потрібно опублікувати якийсь код.
Jasoneer

1
можливий дублікат продуктивності Android WebView
Кен Уайт

1
@KenWhite, окрім цього питання має більше відповідей, це питання має кращі та вичерпніші відповіді, це питання має вдвічі більше переглядів, обидва питання старше двох років, версія андроїда обидва ці запитання застосовуються до застарілого ... що точно ви не позначите це?
CQM

@CQM: Це питання було позначено системою автоматично через дублювану відповідь Джорджа Мейса нижче. Якщо його відповідь можна повторити дослівно як відповідь на кілька дописів, один з них є дублікатом іншого. Пов'язане запитання було розміщено (і відповіли) спочатку на основі дати публікації. Дублікат - це дублікат, і перша публікація була оригінальною (а відповіді були і раніше). Я нічого не отримую від позначення цього (і не в першу чергу).
Кен Уайт

1
Крім того, не використовуйте подію натискання у своїх додатках, вона додає затримку 300 мс, щоб відповісти на кожен клік, щоб визначити, що це клацання. Краще замість цього використовувати сенсорний запуск. Я створив clickhandler, який використовує дві події та приймає перше запускається подія. Я використовую "touchstart click", тому він все ще працює без сенсорного екрана.
Codebeat

Відповіді:


132

Це залежить від завантаженої веб-програми. Спробуйте декілька підходів нижче:

Встановити більш високий пріоритет візуалізації (застарілий від API 18+):

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

Увімкнути / вимкнути апаратне прискорення:

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

Вимкніть кеш-пам'ять (якщо у вас є проблеми зі своїм вмістом):

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

46
Я розумію, чому встановлення пріоритету візуалізації на високе зробило б це швидше. але чому вимкнути кеш?
Дімас Котван

39
Метод setRederPriority застарілий, див. Developer.android.com/reference/android/webkit/WebSettings.html
Віктор Іонеску

6
Правильне посилання для setRenderPriority є тут
Christopher Perry

2
Де я можу помістити цей код у своєму додатку? Будь ласка, допоможіть - У мене така ж проблема в критичному місії WebView
Левчик

6
чому ви вимикаєте кеш?
Hassy31

52

Додавання цього android:hardwareAccelerated="true"до маніфесту було єдиним, що значно покращило продуктивність для мене

Більше інформації тут: http://developer.android.com/guide/topics/manifest/application-element.html#hwaccel


1
Це лише для API v11 / Android 3.x та вище
Ludwo

6
Будьте уважні, є веб-перегляди, пов’язані з апаратними прискореними помилками, як зазначено у питанні stackoverflow.com/q/17059899/225341
Віктор Іонеску

1
Я помітив, що відключення апаратного прискорення насправді робить моє додаток швидшим. З android:hardwareAccelerated="true"3D-анімацією CSS були тривалі затримки до їх запуску, прокрутка DIV в інших DIV-колах, що прокручуються, не працювала, а додаток було більш нестабільним.
Ернестс Карлсонс

1
значення за замовчуванням - "true", якщо для minSdkVersion або targetSdkVersion встановлено значення "14" або вище;
Vihaan Verma

37

Рішення для нас було протилежним. Ми відключили апаратне прискорення лише в WebView (а не на всій програмі в маніфесті) за допомогою цього коду:

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

Анімації CSS3 зараз плавніші. Ми використовуємо Android 4.0.

Більше інформації тут: https://code.google.com/p/android/isissue/detail?id=17352


4
На жаль, це також перешкоджає роботі відео компонента html5 = /
Ja͢ck

Не помітив. Ми використовували перегляд відео для відтворення відео: на щастя, нам просто було потрібно повноекранне відео. Як вирішення, веб-перегляд може бути прозорим і перегляд відео у фоновому режимі, хоча я знаю, що це не одне й те саме.
Ена

1
Існує ще одна проблема з цим виправленням. Під час дотику до веб-перегляду графіка дещо зменшується. Наприклад, якщо у вас є зображення з колом, ви помітите на ньому невеликі квадрати (пікселі) замість плавної лінії. Я можу сказати, що виправити Android 4.3 марно, він не має проблем із продуктивністю.
Ена

Вибачте трохи нового для Android. Чи є це вставним безпосередньо в маніфесті Android, оскільки файл маніфесту XML. Або це має бути підтверджено у вихідному коді під час завантаження веб-перегляду. Вибачте за питання про noob.
xMythicx

1
Після додавання, отримання цієї помилкиWebView not displayed because it is too large to fit into a software layer (or drawing cache), needs 11534400 bytes, only 8294400 available
developer1011

14

Я думаю, що найкраще працює наступне:

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 має Chromium engine для WebView. Я думаю, це краще працює з апаратним прискоренням.


1
Це працювало для мене в WebViews з поганою анімацією та прокруткою
кал

Це я чи ваш «інший» робить те саме, що і ваше «якщо»?
Codebeat

Один Erwinus призначений для type_SOFTWARE, а інший Обладнання
користувач2582318

9

У мене виникло те саме питання, і мені довелося його розробити. Я спробував ці рішення, але в кінці продуктивності, принаймні, для прокрутки зовсім не покращився. Отож, тут я працюю, і я пояснюю, чому це працювало для мене.

Якщо ви мали змогу вивчити події перетягування лише трохи, створивши клас "MiWebView", перезаписавши метод "onTouchEvent" і принаймні надрукувавши час, коли відбувається кожна подія перетягування, ви побачите, що вони розділені вчасно (за до) до 9мс. Це дуже короткий час між подіями.

Погляньте на вихідний код WebView і просто подивіться функцію onTouchEvent. Це просто неможливо, щоб обробляти процесор менше ніж за 9 мс (продовжуйте мріяти !!!). Ось чому ви постійно бачите "Пропустіть перетягування, коли ми чекаємо відповіді WebCore на притиснення". повідомлення. Код просто не вдається вчасно впоратися.

Як це виправити? По-перше, ви не можете переписати код onTouchEvent, щоб поліпшити його, це просто занадто. Але ви можете «знущатися над ним», щоб обмежити частоту подій для перетягування рухів, скажімо, до 40 мс або 50 мс. (це залежить від процесора).

Усі події на дотик проходять так: ACTION_DOWN -> ACTION_MOVE ...... ACTION_MOVE -> ACTION_UP. Тому нам потрібно тримати рухи вниз і вгору і фільтрувати швидкість руху (це погані хлопці).

І ось спосіб це зробити (ви можете додати більше типів подій, як-от дотик до двох пальців, мені тут цікаво лише прокручування одним пальцем).

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

Звичайно, використовуйте цей клас замість WebView, і ви побачите різницю при прокручуванні.

Це лише підхід до рішення, але все ще не повністю реалізований для всіх випадків відставання через торкання екрана при використанні WebView. Однак це найкраще рішення, яке я знайшов, принаймні для моїх конкретних потреб.


Я хотів би зазначити, що вихідний код веб-перегляду, який ви опублікували, починається з 2010 року
CQM

Це не працює, не згладжує прокрутку, я не відчуваю різниці.
neevek

Я реалізував цю межу встановлення до 80, але це, схоже, не покращує продуктивність, але воно сприймає деякі похідні дії. Що це робить для вас?
Рагнар

Прочитали, що подія клацання в 6 разів повільніше, ніж сенсорний старт події. Щоб уникнути затримок, ви можете скористатися $ ('# кнопка'). On ('clickstart click', function () {action here; return false;});
Codebeat

Крім того, не використовуйте подію натискання у своїх програмах html, вона додає затримку 300 мс, щоб відповісти на кожен клік, щоб визначити, що це клацання. Краще замість цього використовувати сенсорний запуск. Я створив clickhandler, який використовує дві події та приймає перше запускається подія. Я використовую "touchstart click", тому він як і раніше працює без сенсорного екрана.
Codebeat

9

Я спробував усі пропозиції виправити проблему з ефективністю візуалізації в додатку phonegap. Але нічого реально не вийшло.

Нарешті, після цілого дня пошуку, я встиг. Я встановлюю тег (не тег) свого AndroidManifest

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

Тепер додаток поводиться так само швидко, як і мій веб-браузер. Схоже, якщо апаратне прискорення не завжди є найкращою характеристикою ...

Детальна проблема у мене була: https://stackoverflow.com/a/24467920/3595386


2
Відключення апаратного прискорення зробило мене жахливим, веб-перегляд прокручувався так повільно
АбдельХаді

5

Жодна з цих відповідей мені не була корисною.

Нарешті я знайшов причину та рішення. Причиною стало багато CSS3-фільтрів (filter, -webkit-filter).

Рішення

Я додав виявлення WebView в сценарій веб-сторінки, щоб додати клас "низька якість" до HTML-тіла. До речі. Ви можете легко відстежувати WebView, встановлюючи користувальницький агент у налаштуваннях WebView. Тоді я створив нове правило CSS

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

Незручно, коли через 5 років є дуже мало причин використовувати веб-перегляд, незважаючи на те, що пристрої швидші, продуктивність, сумісніша мобільному браузеру, значно покращилась та інші причини. Дякуємо, що заглянули в це!
CQM

@CQM У мене була така ж проблема, я знайшов рішення, тому хотів поділитися нею :)
l00k

Я просто пильний, це одне з моїх найстаріших питань, ще раз дякую!
CQM

1
Абсурдно, що це питання у 2016/2017 році. Жоден з фільтрів CSS не повинен бути складним для будь-якого мобільного графічного процесора.
Адам Леггетт

4

Якщо є лише кілька компонентів вашого веб-перегляду, який повільно чи мляво, спробуйте додати це до елементів css:

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

Це був єдиний скорохід, який дійсно вплинув на моє перегляд в Інтернеті. Але будьте обережні, щоб не зловживати цим! (ви можете прочитати більше про хак в цій статті .)


1
Використовуйте will-change: transform.
Адам Леггетт


3

Якщо ви зобов’язуєтесь до onclick події, це може бути повільним на сенсорних екранах.

Щоб зробити це швидше, я використовую fastclick , який використовує набагато швидші торкання подій, щоб імітувати подію натискання.


fastclick більше не розробляється ... так, сенсорні події повільні, і я просто потрібен, щоб він працював, і я знайшов за допомогою jquery питання про швидкість можна вирішити, використовуючи $('#').on('touchstart', function() {...});на відміну від onclick
CrandellWS
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.