自Lollipop以来,WebView加载速度变慢了。

9
事实上,我很惊讶在Stackoverflow上没有找到类似的问题,但是我真的无法想通。
首先,请注意这与在WebView中浏览网页的性能无关。它仅涉及充气甚至空的WebView,而不加载任何URL。
为了消除所有其他因素,我创建了一个全新的项目,其中只包含重现问题所必需的内容。
在这个几乎为空的项目中,我有一个布局,其中只包含一个WebView:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.testing.WebViewOnlyActivity">

    <WebView
        android:id="@+id/webview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</FrameLayout>

我有一个MainActivity,它只包含一个Button,用于启动这个WebViewOnlyActivity

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this, WebViewOnlyActivity.class);
                startActivity(intent);
            }
        });
    }
}

看起来很简单,对吧?

现在当我构建项目并点击按钮时,WebViewOnlyActivity弹出需要超过1秒的时间。但是,如果我按下返回按钮,然后再按下按钮,WebViewOnlyActivity将立即显示。显然,Android缓存了WebView的某些内容。

以下是我的测试设备:
1. Android 7.1.1:慢
2. Android 7.0.0:慢
3. Android 5.0.2:慢
4. Android 4.4.1:快

所以我认为这只发生在Lollipop版本之后。

然而,这样1.x秒的延迟对我来说仍然不可接受。有人知道如何解决吗?(嗯,我觉得很难,因为我没有对这个WebView做任何事情...也许我应该使用一些第三方WebView?)

P.S. 我还使用traceview查看了7.1.1设备和4.4.1设备之间的区别。很明显,WebView的init()方法占用了很多时间。

7.1.1: 7.1.1 Trace View 并进一步深入: 7.1.1 Deeper

4.4.1: 4.4.1 Trace View 并进一步深入: 4.4.1 Deeper

差别很大!


虽然它确实很空,但由于Axel的要求,我也会发布WebViewOnlyActivity的代码:

public class WebViewOnlyActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web_view_only);

    }
}


@XavierRubioJansana 实际上,即使我杀掉应用程序并重新启动,WebView 也比全新启动快一些。我认为这是因为 Android 缓存了 WebView 所需的某些资源在内存中,而杀死应用程序不会删除这些缓存。例如,如果我在应用程序 A 中打开了一个 WebView,则在应用程序 B 中打开 WebView 也会加速。但我认为上面显示的显著差异足以证明问题,所以我没有提到它。 - Sira Lam
1
我不知道该如何解决它,这似乎是一个操作系统问题,但我可以提出两种可能的解决方法。首先,你可以通过编写代码在之前的 Activity 中创建一个隐藏的 WebView,在适当的时刻(例如,在 onStart 之后)将其销毁。这样可以“激活”操作系统缓存。另一种选择是用 ViewStub 替换 WebView,以便在 onStart 之后延迟加载 WebView。用户会很快看到 Activity,然后 WebView 就会加载。 - Xavier Rubio Jansana
@XavierRubioJansana 我尝试过AsyncLayoutInflator,但它会崩溃,没有想到你提到的这两种方法。我会尝试一下,非常感谢! - Sira Lam
@AxelD。它确实很空。但是我还是更新了这篇帖子。 - Sira Lam
@XavierRubioJansana 我尝试使用ViewStub,但即使我将其放在onResume中,它仍然占用了活动创建时间。但是,如果我使用Handler加上postDelayed,活动会立即出现。非常感谢! - Sira Lam
显示剩余6条评论
1个回答

6

编辑于2017年12月21日

我甚至创建了一个库来轻松解决这个问题。
你可以在这里下载它。
如果你觉得有用,就给它点个赞吧 :P


感谢@XavierRubioJansana的提示,我尝试使用ViewStub来延迟膨胀。

然而,即使我将膨胀延迟到onResume(),它仍会减缓活动的创建速度。

但是,如果我使用一个HandlerpostDelay膨胀,活动会立即创建!

    Handler webViewInflateHandler = new Handler();
    webViewInflateHandler.postDelayed(new Runnable() {
        @Override
        public void run() {
            if (!webViewInflated) {
                webView = (WebView) webViewStub.inflate();
                webViewInflated = true;
            }
        }
    }, 50);

然后,您需要延迟所有种类的WebView的设置和加载,直到它被填充。我建议在此处使用RxJava来观察BehaviorSubject<Boolean>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接