Предыстория
При разработке мобильного приложения для крупной международной компании возникла необходимость отобразить 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, благодаря который мы можем использовать сторонние браузеры, скорость которых заметно выше.
Bringoff
thelushpen
Распаралелить WebView нельзя. Статья направлена на сокращение времени, потраченного на бесполезные попытки добиться скорости соизмеримой с Chrome и больше не на что не претендует.
alexpp
Я конечно не представляю особенностей, почему страница такого размера должна отдаваться целиком, возможно на то есть свои причины — но как раз для таких объемов информации придуман и пейджинг, и динамическая подгрузка контента. Целиком и полностью моё имхо — надо бороться не скоростью webview, а перерабатывать архитектуру приложения.
thelushpen
Да, я тоже был не очень рад таким объёмам информации, но заказчик всегда прав.
awsi
Что мешает, сначала, загрузить контент в локальные ресурсы в любом режиме, а затем, передать его для отображения в WebView? Зачем использовать средства самого WebView для загрузки страницы в этом случае? Вы и кэширование можете свое использовать и динамически редактировать контент и т.п.
thelushpen
Было бы интересно посмотреть на ваше решение данной проблемы.
Zoomskij
Простите, это что, на главной Хабра?
MzMz
Локальный узко-специализированный проксик должен помочь
kemsky
Вопрос только в одном, есть ли такая реализация?
MzMz
Что значит «есть»? Берете Apache HttpComponents и делаете :)