Android WebViewが遅い


174

android webviewsは遅いです。これは、電話から3.0+タブレットまで、十分なスペック以上のものにすべてあります

私はwebviewsが「制限」することになっていることを知っているが、私はウェブは、電話のすべての種類を使用している必要があり、ギャップで行われたアプリを参照CSS3し、JQuery魔術、彼らはうまくかつ迅速に実行します

何かが足りないのですが、myWebview.SPEEDHACK(1)スピードアップに使用できるものはありますか?

また、時々、私のwebviewのコンテンツが単にロードされないだけで、ゆっくりとロードされるのではなく、ロードされません。私がテストしているアセットはローカルに保存され、エラーはありません。


3
コードを投稿する必要があるようです。
Jasoneer 2011


1
@KenWhiteこの質問以外の回答が多い、この質問の方がより包括的な回答がある、この質問は2倍のビューがあります正確にこれを報告することから抜け出しますか?
CQM 2014

@CQM:以下のジョージメイズの回答が重複しているため、この質問はシステムによって自動的にフラグが付けられました。彼の回答を複数の投稿への回答としてそのまま逐語的に繰り返すことができる場合、それらの1つは他の複製です。リンクされた質問は、投稿日に基づいて最初に投稿(および回答)されました。重複は重複であり、最初の投稿が元の投稿でした(回答も以前のものでした)。私はこれにフラグを立てることから何も得ません(そしてそもそもしませんでした)。
ケンホワイト

1
また、アプリでクリックイベントを使用しないでください。クリックであると判断するために、クリックごとに応答するために300ミリ秒の遅延が追加されます。代わりにtouchstartを使用することをお勧めします。2つのイベントを使用し、最初にトリガーされたイベントを取得するクリックハンドラーを作成しました。「タッチスタートクリック」を使用しているため、タッチスクリーンがなくても機能します。
Codebeat

回答:


132

ロードされるWebアプリケーションによって異なります。以下のアプローチのいくつかを試してください。

より高いレンダリング優先度を設定します(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 2013年

39

6
setRenderPriorityの正しいリンクはこちら
クリストファーペリー14

2
このコードをアプリのどこに配置すればよいですか?助けてください-私はミッションクリティカルなWebViewで同じ問題を抱えています
Levchik

6
なぜキャッシュをオフにするのですか?
Hassy31 2016年

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のスクロール、およびアプリはより不安定でした。
アーネストカールソン2014年

1
minSdkVersionまたはtargetSdkVersionを「14」以上に設定した場合、デフォルト値は「true」です。
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/issues/detail?id=17352


4
残念ながら、これはまた仕事にHTML5のビデオコンポーネントを防ぎ= /
ジャック

気づかなかった。ビデオビューを使用してビデオを再生しました。幸いなことに、フルスクリーンビデオが必要でした。回避策として、ウェブビューを透明にして、ビデオビューをバックグラウンドで再生することもできますが、同じではないことはわかっています。
恵那

1
この修正には別の問題があります。ウェブビューに触れると、グラフィックが少し歪んでしまいます。たとえば、円形の画像がある場合、滑らかな線ではなく小さな正方形(ピクセル)が表示されます。Android 4.3の修正では役に立たないことがわかります。パフォーマンスの問題はありません。
Ena

アンドロイドに少し新しい申し訳ありません。これは、Androidマニフェストに直接貼り付けることができますか?マニフェストファイルはXMLです。または、これはウェブビューをロードするときにソースコードで検証されることになっていますか?noobの質問でごめんなさい。
xMythicx 14

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
これは、アニメーションとスクロールが不十分なWebViewで私にとってはうまくいった
cal

それは私ですか、それとも「その他」は「もし」と同じですか?
Codebeat

Erwinusの1はtype_SOFTWAREおよびその他のハードウェアのためである
user2582318

9

私はこれと同じ問題を抱えていて、解決しなければなりませんでした。私はこれらの解決策を試しましたが、少なくともスクロールのパフォーマンスは最後にはまったく改善されませんでした。だからここで私が行ったworkaroudとそれが私のために働いた理由の説明。

「MiWebView」クラスを作成し、「onTouchEvent」メソッドを上書きして、少なくともすべてのドラッグイベントが発生する時間を出力することにより、ドラッグイベントを少しだけ調べる機会があった場合、それらが分離されていることがわかります。 9ミリ秒離れたところまで それは、イベント間の非常に短い時間です。

見てみましょうWebViewのソースコードを、そしてちょうどonTouchEvent機能を参照してください。プロセッサーが9ミリ秒未満で処理することは不可能です(夢を見続ける!!!)。そのため、「タッチダウンに対するWebCoreの応答を待機しているため、ドラッグに失敗しました」が常に表示されます。メッセージ。コードは時間どおりに処理できません。

それを修正するには?まず、onTouchEventコードを書き換えて改善することはできません。ただし、ドラッグムーブメントのイベントレートを、たとえば40ミリ秒または50ミリ秒に制限するために、「模擬」することができます。(これはプロセッサによって異なります)。

すべてのタッチイベントは、ACTION_DOWN-> ACTION_MOVE ...... ACTION_MOVE-> ACTION_UPのようになります。したがって、DOWNとUPの動きを維持し、MOVEレートをフィルタリングする必要があります(これらは悪者です)。

そして、これを行う方法があります(2本の指のタッチなどのイベントタイプをさらに追加できます。ここで興味があるのは、1本の指のスクロールだけです)。

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を使用しているときに画面がタッチするため、すべての遅延ケースに対して完全に実装されていません。しかし、それは私が見つけた最良の解決策であり、少なくとも私の特定のニーズにとってはそうです。


あなたが投稿したwebviewソースコードは2010年からのものであることを指摘したいと思います
CQM

これは機能せず、スムーズにスクロールできません。違いを感じることができません。
neevek '19

私はこの設定を最大80に設定しましたが、実際にはパフォーマンスは向上しないようですが、いくつかの移動イベントをキャッチします。それはあなたのために何をしますか?
ラグナー

クリックイベントはタッチイベントタッチスタートの6倍遅いことを読んでください。遅延を回避するには、$( '#button')。on( 'touchstart click'、function(){action here; return false;});を使用できます。
Codebeat、2014年

また、HTMLアプリでクリックイベントを使用しないでください。クリックであると判断するために、クリックごとに応答するために300ミリ秒の遅延が追加されます。代わりにtouchstartを使用することをお勧めします。2つのイベントを使用し、最初にトリガーされたイベントを取得するクリックハンドラーを作成しました。「タッチスタートクリック」を使用しているため、タッチスクリーンがなくても機能します。
Codebeat

9

電話ギャップアプリのレンダリングパフォーマンスの問題を修正するための提案をすべて試しました。しかし、実際には何も機能しませんでした。

最後に、丸一日の検索の後、私はそれを作りました。私はAndroidManifestのタグではなくタグ内に設定しました

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

これで、アプリは私のWebブラウザーと同じように高速に動作します。ハードウェアアクセラレーションが常に最良の機能であるとは限らないようです...

私が抱えていた詳細な問題:https : //stackoverflow.com/a/24467920/3595386


2
ハードウェアアクセラレーションを無効にすることは恐ろしいことでした。Webビューのスクロールが非常に遅かった
AbdelHady

5

これらの答えはどれも私にとって役に立たなかった。

最後に私は理由と解決策を見つけました。その理由は、多くのCSS3フィルター(filter、-webkit-filter)でした。

解決

HTMLボディに「低品質」クラスを追加するために、WebページスクリプトにWebViewの検出を追加しました。ところで。WebView設定でユーザーエージェントを設定することにより、WebViewを簡単に追跡できます。次に、新しいCSSルールを作成しました

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

5年後、デバイスが高速であるにも関わらず、Webviewを使用する理由がほとんどなく、モバイルブラウザーと互換性のあるパフォーマンスが大幅に向上したなど、厄介な理由があります。ご覧いただきありがとうございます。
CQM

@CQM同じ問題がありました。解決策を見つけたので、共有したいと思いました:)
l00k

私は面白くて、これは私の最も古い質問の1つです、もう一度ありがとう!
CQM 2016年

1
これが2016/2017年の問題であることはばかげています。どのCSSフィルターも、どのモバイルGPUにとっても難しいものではありません。
Adam Leggett 2017

4

遅いか遅れているウェブビューのいくつかのコンポーネントしかない場合は、要素cssにこれを追加してみてください:

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

これは、私のWebビューに本当に影響を与えた唯一のスピードハックです。ただし、使いすぎないように注意してください。(ハックについて詳しくは、この記事をご覧ください。)


1
を使用しwill-change: transformます。
Adam Leggett 2017


3

にバインドしている場合 onclickイベントに場合、タッチスクリーンでは遅くなる可能性があります。

高速化するために、私はfastclickを使用します。これは、はるかに高速なタッチイベントを使用してクリックイベントを模倣します。


fastclickはもう開発されていません...はい、タッチイベントは遅く、動作するために必要なだけでした。jqueryを使用$('#').on('touchstart', function() {...});すると、onclickとは対照的に速度の問題を回避できます
CrandellWS
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.