안드로이드 웹뷰 느림


174

나는 android webviews느리다. 이것은 3.0+적절한 사양 이상의 전화기에서 태블릿 에 이르기까지 모든 것에 있습니다.

나는 웹뷰가 "제한적"이어야한다는 것을 알고 있지만 모든 종류 CSS3JQuery마법 을 사용해야하는 전화 갭으로 웹 앱을 볼 수 있습니다.

그래서 뭔가 빠졌 myWebview.SPEEDHACK(1)습니다. 속도를 높이기 위해 사용할 수있는 것이 있습니까?

또한 때로는 내 웹보기의 내용이 단순히로드되지 않고 단순히로드되지 않고로드되지 않습니다. 테스트중인 자산은 오류없이 로컬에 저장됩니다.


3
코드를 게시해야 할 것 같습니다.
Jasoneer


1
@KenWhite이 질문을 제외하고 더 많은 답변이 있습니다.이 질문은 더 좋고 더 포괄적 인 답변을 가지고 있습니다.이 질문은 두 배나 많은 조회수를 가지고 있습니다. 두 질문 모두 2 세 이상입니다.이 두 가지 질문 모두 안드로이드 버전은 더 이상 사용되지 않습니다 ... 이걸 정확히 표시하지 않습니까?
CQM

@CQM :이 질문은 아래의 George Mays 답변이 중복되어 시스템에서 자동으로 표시되었습니다. 여러 게시물에 대한 답변으로 그의 답변을 그대로 반복 할 수 있다면 그 중 하나는 다른 게시물과 중복됩니다. 링크 된 질문은 게시 날짜를 기준으로 먼저 게시 및 답변되었습니다. 복제본은 복제본이며 첫 번째 게시물은 원본이었습니다 (답변도 더 빠름). 나는 이것을 표시하는 것에서 아무것도 얻지 못했습니다 (처음에는 없었습니다).
Ken White

1
또한 앱에서 클릭 이벤트를 사용하지 마십시오. 클릭당 300m의 지연이 발생하여 클릭 여부를 결정합니다. 대신 터치 스타트를 사용하는 것이 좋습니다. 두 가지 이벤트를 사용하고 첫 번째 트리거 이벤트를 취하는 클릭 핸들러를 만들었습니다. '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
렌더링 우선 순위를 높게 설정하면 더 빨라지는 이유를 이해합니다. 그러나 왜 캐시를 끄는가?
Dimas Kotvan 2016 년

39
메소드 setRederPriority가되지 않습니다 참조 developer.android.com/reference/android/webkit/WebSettings.html
빅터 Ionescu

6
setRenderPriority에 대한 올바른 링크는 여기
크리스토퍼 페리

2
앱에서이 코드를 어디에 두어야합니까? 도와주세요-미션 크리티컬 WebView와 동일한 문제가 있습니다
Levchik

6
왜 캐시를 해제합니까?
Hassy31

52

android:hardwareAccelerated="true"매니페스트에 이것을 추가 하면 성능이 크게 향상되었습니다.

자세한 정보는 여기 : http://developer.android.com/guide/topics/manifest/application-element.html#hwaccel


1
API v11 / Android 3.x 이상에만 해당
Ludwo


1
하드웨어 가속을 끄면 실제로 앱이 더 빨라집니다. 로 android:hardwareAccelerated="true"가 시작되기 전에 CSS 3D 애니메이션, 긴 지연이 있었다 다른 스크롤 된 DIV 일을하지 않았다 내부는 div 스크롤 앱은 더 불안정했다.
Ernests Karlsons

1
minSdkVersion 또는 targetSdkVersion을 "14"이상으로 설정 한 경우 기본값은 "true"입니다.
Vihaan Verma 13:27에

37

우리를위한 해결책은 정반대였습니다. 이 코드를 사용하여 매니페스트의 전체 앱이 아닌 WebView에서만 하드웨어 가속을 비활성화했습니다.

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

CSS3 애니메이션이 더 매끄 럽습니다. 우리는 안드로이드 4.0을 사용하고 있습니다.

자세한 내용은 https://code.google.com/p/android/issues/detail?id=17352


4
불행히도, 이것은 또한 html5 비디오 컴포넌트가 작동하지 못하게합니다 = /
Ja͢ck

눈치 채지 못했습니다. 비디오보기를 사용하여 비디오를 재생했습니다. 다행히도 전체 화면 비디오가 필요했습니다. 해결 방법으로 웹 뷰를 투명하게하고 비디오 뷰를 백그라운드에서 재생하는 것이 가능하지만 동일한 것은 아닙니다.
Ena

1
이 수정에는 또 다른 문제가 있습니다. 웹뷰를 터치하면 그래픽이 약간 왜곡됩니다. 예를 들어, cirle이있는 이미지가 있으면 부드러운 선 대신 작은 사각형 (픽셀)이 나타납니다. Android 4.3 수정으로 쓸모가 없으며 성능 문제가 없음을 알 수 있습니다.
Ena

안 드 로이드 조금 새로운 죄송합니다. 매니페스트 파일이 XML이라는 Android 매니페스트에 직접 붙여 넣을 수 있습니까? 또는 webview를로드 할 때 소스 코드에서 유효성을 검사해야합니까? 멍청한 질문 죄송합니다.
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에는 WebView 용 Chromium 엔진이 있습니다. 하드웨어 가속으로 더 잘 작동한다고 생각합니다.


1
이것은 저조한 애니메이션과 스크롤이있는 WebViews에서 작동했습니다.
cal

나입니까, 아니면 '다른'것이 'if'와 똑같습니까?
Codebeat

Erwinus 하나는 type_SOFTWARE와 다른 하드웨어를위한 것입니다
user2582318

9

나는이 같은 문제가 있었고 그것을 해결해야했습니다. 나는이 솔루션을 시도했지만 결국 스크롤링의 성능은 전혀 향상되지 않았습니다. 그래서 여기에 내가 수행 한 작업과 그것이 나를 위해 일한 이유에 대한 설명이 있습니다.

"MiWebView"클래스를 작성하고 "onTouchEvent"메소드를 덮어 쓰고 최소한 모든 드래그 이벤트가 발생하는 시간을 인쇄하여 드래그 이벤트를 탐색 할 기회가있는 경우, 분리 된 것을 볼 수 있습니다 9ms 떨어진 시간까지. 이벤트 사이에 아주 짧은 시간입니다.

WebView 소스 코드를 살펴보고 onTouchEvent 함수를 참조하십시오. 프로세서가 9ms 미만으로 처리하는 것은 불가능합니다. 그렇기 때문에 "WebCore의 터치 다운에 대한 응답을 기다리는 동안 드래그가 발생하지 않습니다." 메시지. 코드는 제 시간에 처리 할 수 ​​없습니다.

고치는 방법? 첫째, onTouchEvent 코드를 다시 작성하여 향상시킬 수는 없습니다. 그러나 움직임을 드래그하는 이벤트 속도를 40ms 또는 50ms로 제한하기 위해 "모의"할 수 있습니다. (프로세서에 따라 다름)

모든 터치 이벤트는 다음과 같습니다 : ACTION_DOWN-> ACTION_MOVE ...... ACTION_MOVE-> ACTION_UP. 따라서 우리는 DOWN 및 UP 움직임을 유지하고 MOVE 비율을 필터링해야합니다 (이것은 나쁜 사람들입니다).

그리고 여기에 그것을하는 방법이 있습니다 (두 손가락 터치와 같은 더 많은 이벤트 유형을 추가 할 수 있습니다. 여기서 관심있는 것은 단일 손가락 스크롤뿐입니다).

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까지 구현했지만 실제로 성능을 향상 시키지는 않지만 일부 이동 이벤트를 잡습니다. 당신을 위해 무엇을합니까?
Ragnar

클릭 이벤트가 터치 이벤트 터치 시작보다 6 배 느리다는 것을 읽으십시오. 지연을 피하기 위해 $ ( '# button'). on ( 'touchstart click', function () {action here; return false;});
Codebeat

또한 html 앱에서 클릭 이벤트를 사용하지 마십시오. 클릭 할 때마다 300ms의 지연이 발생하여 클릭 여부를 결정합니다. 대신 터치 스타트를 사용하는 것이 좋습니다. 두 가지 이벤트를 사용하고 첫 번째 트리거 이벤트를 취하는 클릭 핸들러를 만들었습니다. 'touchstart click'을 사용하므로 여전히 터치 스크린없이 작동합니다.
Codebeat

9

phonegap 앱에서 렌더링 성능 문제를 해결하기 위해 모든 제안을 시도했습니다. 그러나 실제로는 효과가 없었습니다.

마지막으로, 하루 종일 검색을 한 후 검색했습니다. 내 AndroidManifest의 태그 (태그 아님) 내에 설정했습니다.

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

이제 앱이 웹 브라우저와 동일한 방식으로 작동합니다. 하드웨어 가속이 항상 가장 좋은 기능은 아닌 것 같습니다 ...

내가 가진 자세한 문제 : https : //.com/a/24467920/3595386


2
하드웨어 가속을 비활성화하면 나에게 끔찍한 일이 있었는데, 웹뷰가 너무 느리게 스크롤되었습니다.
AbdelHady

5

그 답변 중 어느 것도 나에게 도움이되지 않았습니다.

마지막으로 이유와 해결책을 찾았습니다. 그 이유는 CSS3 필터 (필터, -webkit-filter)가 많기 때문입니다.

해결책

HTML 본문에 "저품질"클래스를 추가하기 위해 웹 페이지 스크립트에 WebView 감지 기능을 추가했습니다. BTW. WebView 설정에서 user-agent를 설정하여 WebView를 쉽게 추적 할 수 있습니다. 그런 다음 새로운 CSS 규칙을 만들었습니다.

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

5 년 후 장치 속도가 빠르더라도 웹뷰를 사용해야하는 이유가 거의없고, 더 많은 모바일 브라우저 호환 성능이 크게 향상되었습니다. 그것을 조사해 주셔서 감사합니다!
CQM

@ CQM 나는 같은 문제가 있었고, 해결책을 찾았으므로 그것을 공유하고 싶었다. :)
l00k

나는 단지 뻔뻔 스럽습니다. 이것은 가장 오래된 질문 중 하나입니다. 다시 한번 감사드립니다!
CQM

1
2016/2017 년에 이것이 문제라는 것은 의심의 여지가 있습니다. CSS 필터 중 어느 것도 모바일 GPU에 도전해서는 안됩니다.
Adam Leggett

4

느리거나 게으른 webview의 구성 요소가 거의 없다면 css 요소에 추가하십시오.

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

이것은 실제로 내 웹보기에 영향을 미치는 유일한 스피드 핵이었습니다. 그러나 그것을 과도하게 사용하지 않도록주의하십시오! ( 이 기사 에서 해킹에 대해 자세히 읽을 수 있습니다 .)


1
사용하십시오 will-change: transform.
Adam Leggett


3

onclick이벤트에 바인딩하는 경우 터치 스크린에서 느려질 수 있습니다.

빠른 클릭을 위해 훨씬 빠른 터치 이벤트를 사용하여 클릭 이벤트를 모방 한 fastclick 을 사용합니다.


fastclick은 더 이상 개발되지 않습니다 ... 예 터치 이벤트가 느리고 작동하기 위해 필요했고 jquery를 사용 $('#').on('touchstart', function() {...});하여 onclick과 달리 사용하여 속도 문제를 해결할 수 있습니다.
CrandellWS
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.