Android веб-браузер медленный


174

Мои android webviewsмедленные. Это на всех, от телефонов до 3.0+планшетов с более чем адекватными характеристиками

Я знаю, что веб-просмотры должны быть «ограниченными», но я вижу, что веб-приложения сделаны с пробелом в телефоне, который должен использовать все виды CSS3и JQueryколдовство, они работают просто отлично и быстро

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

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


3
Похоже, вам нужно опубликовать код.
Жасонир

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

1
@KenWhite, кроме этого вопроса, есть больше ответов, на этот вопрос есть лучшие и более полные ответы, у этих вопросов в два раза больше просмотров, оба вопроса старше двух лет, версия Android, к которым оба эти вопроса применяются, устарела ... что точно вы получаете от пометки это?
CQM

@CQM: Этот вопрос был помечен системой автоматически из-за дублированного ответа Джорджа Мейса ниже. Если его ответ можно повторить дословно как ответ на несколько постов, один из них является дубликатом другого. Связанный вопрос был опубликован (и получен ответ) в первую очередь на основе даты публикации. Дубликат является дубликатом, и первый пост был оригинальным (и ответы были также раньше). Я ничего не получаю от пометки этого (и не сделал в первую очередь).
Кен Уайт

1
Кроме того, не используйте событие click в своих приложениях, оно добавляет 300 мс задержки для ответа на каждый клик, чтобы определить, что это клик. Вместо этого лучше использовать Touchstart. Я сделал обработчик кликов, который использует два события и принимает первое запущенное событие. Я использую «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

6
Правильная ссылка для setRenderPriority здесь
Кристофер Перри

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
Будьте осторожны, есть открытая ошибка, связанная с аппаратным ускорением WebViews, как указано в вопросе stackoverflow.com/q/17059899/225341
Виктор Ионеску,

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

1
значение по умолчанию равно "true", если вы установили minSdkVersion или targetSdkVersion на "14" или выше;
Вихан Верма

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/issues/detail?id=17352.


4
К сожалению, это также мешает работе видео компонента html5 = /
Ja͢ck

Не заметил. Для воспроизведения видео мы использовали просмотр видео: к счастью, нам просто нужно было полноэкранное видео. В качестве обходного пути можно сделать веб-видение прозрачным и просмотр видео в фоновом режиме, хотя я знаю, что это не одно и то же.
Эна

1
Есть еще одна проблема с этим исправлением. При прикосновении к веб-сайту изображение немного искажается. Например, если у вас есть изображение с кружочком, вы заметите маленькие квадраты (пиксели) на нем вместо плавной линии. Я могу сказать, что с Android 4.3 исправление бесполезно, у него нет проблем с производительностью.
Эна

Извините, немного нового для Android. Может ли это быть вставлено непосредственно в манифест Android, что файл манифеста является XML. Или это должно быть проверено в исходном коде при загрузке веб-просмотра. Извините за вопрос нуба.
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 для WebView. Я думаю, это работает лучше с аппаратным ускорением.


1
Это сработало для меня в WebView с плохой анимацией и прокруткой
cal

Это я или ваш «другой» делает то же самое, что и «если»?
Codebeat

Erwinus one предназначен для type_SOFTWARE, а другой Hardware
user2582318

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

Кроме того, не используйте событие click в ваших html-приложениях, оно добавляет 300 мс задержки для ответа на каждый клик, чтобы определить, что это клик. Вместо этого лучше использовать Touchstart. Я сделал обработчик кликов, который использует два события и принимает первое запущенное событие. Я использую «touchstart click», поэтому он все еще работает без сенсорного экрана.
Codebeat

9

Я попробовал все предложения, чтобы исправить проблему производительности рендера в моем приложении phonegap. Но на самом деле ничего не получалось.

Наконец, после целого дня поисков я сделал это. Я установил в тег (а не тег) моего AndroidManifest

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

Теперь приложение работает так же быстро, как и мой веб-браузер. Похоже, если аппаратное ускорение не всегда лучшая функция ...

Подробная проблема у меня была: https://stackoverflow.com/a/24467920/3595386


2
Отключение аппаратного ускорения сделало меня ужасным, веб-просмотр был настолько медленным при прокрутке
AbdelHady

5

Ни один из этих ответов не помог мне.

Наконец я нашел причину и решение. Причиной было много фильтров CSS3 (filter, -webkit-filter).

Решение

Я добавил обнаружение WebView в скрипт веб-страницы, чтобы добавить класс «lowquality» в тело HTML. КСТАТИ. Вы можете легко отслеживать WebView, установив user-agent в настройках 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.