Предыстория


При разработке мобильного приложения для крупной международной компании возникла необходимость отобразить Web страничку в WebView. Страница на Java Script и содержит DOM контент порядка 10-15 Мб. В связи с большим размером страница загружается порядка 30 — 50 секунд, в зависимости от интернет соединения. Такие результаты не радовали, поэтому возникла необходимость тщательного исследования данной проблемы.

Кэширование в WebView


Единственным найденным решением было использование кэширования для загружаемого контента:
webview.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);

Скорость загрузки увеличилась вдвое. Однако, для поддержания актуальности контента, WebView проверяет каждый файл в отдельности на его валидность. Хоть скорость и выросла, время загрузки данной страницы внутри WebView по сравнению с мобильным браузером Chrome уступало в несколько раз.

Однопоточность WebView


После тщательного исследования пришел к выводу, что WebView использует всего один поток для загрузки данных. Это верно как для WebView построенном на собственном WebKit (SDK < 19) так и для WebView с Chromium движком (SDK>=19). Chrome в отличии от WebView использует много потоков (число зависит от процессора) и не использует в себе WebView. Поэтому сравнивать WebView с Chrome тоже самое, что сравнивать запорожец с Lamborghini, нет смысла. Разработчики нативного компонента Cromium для WebView не предполагают внедрение многопоточности и считают, что один поток гарантирует стабильную работу.

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

Intent browserIntent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(browserIntent);

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

1. Twitter отказался открывать страницу и сразу предложил использовать браузер.
2. Facebook предложил использовать браузер, но все равно открыл страницу в WebView с такой же скоростью, что и мое решение.

К счастью этого было достаточно и на меня прекратилось давление.

Вывод


Не стоит использовать WebView для отображения больших и сложных страниц. Рекомендованное использование WebView:

1. Для авторизации на каких либо сервисах.
2. Для отображения простых страниц.
3. Для выравнивания текста по ширине (Стандартное TextView не имеет данной функции, но это уже совсем другая история).

Не будем забывать, что в Android используется система Intent, благодаря который мы можем использовать сторонние браузеры, скорость которых заметно выше.

Комментарии (10)


  1. Bringoff
    27.08.2015 11:30
    +2

    Скрытый текст
    НЛО, вы как-то странно выбираете посты для предоставления инвайтов.


    1. thelushpen
      27.08.2015 12:00
      +1

      Распаралелить WebView нельзя. Статья направлена на сокращение времени, потраченного на бесполезные попытки добиться скорости соизмеримой с Chrome и больше не на что не претендует.


  1. alexpp
    27.08.2015 17:49
    +1

    Я конечно не представляю особенностей, почему страница такого размера должна отдаваться целиком, возможно на то есть свои причины — но как раз для таких объемов информации придуман и пейджинг, и динамическая подгрузка контента. Целиком и полностью моё имхо — надо бороться не скоростью webview, а перерабатывать архитектуру приложения.


    1. thelushpen
      27.08.2015 18:34
      +1

      Да, я тоже был не очень рад таким объёмам информации, но заказчик всегда прав.


  1. awsi
    27.08.2015 22:52
    +1

    Что мешает, сначала, загрузить контент в локальные ресурсы в любом режиме, а затем, передать его для отображения в WebView? Зачем использовать средства самого WebView для загрузки страницы в этом случае? Вы и кэширование можете свое использовать и динамически редактировать контент и т.п.


    1. thelushpen
      28.08.2015 03:57

      Было бы интересно посмотреть на ваше решение данной проблемы.


  1. Zoomskij
    28.08.2015 08:49
    +1

    Простите, это что, на главной Хабра?


  1. MzMz
    28.08.2015 14:53
    +1

    Локальный узко-специализированный проксик должен помочь


    1. kemsky
      28.08.2015 15:30

      Вопрос только в одном, есть ли такая реализация?


      1. MzMz
        28.08.2015 15:36

        Что значит «есть»? Берете Apache HttpComponents и делаете :)