安卓Webview性能缓慢

6

我正在使用JavaScript编写一款游戏。在我的浏览器上,这个应用程序运行良好(速度快),但是我在Android WebView上运行时遇到了一些问题。

  1. The time to start the app takes 5s or more (I think that is kind of slow, but maybe that is normal?)
  2. In the menu of the game I have a method like:

    this.showCredits = function() {
    document.getElementById('core-credits-layer').style.display = 'block';
    document.getElementById('core-credits').style.display = 'block';
    var parent = this;
    
    $.ajax({
        url: 'content/credits.html',
        dataType: 'html',
        success: function(data, status, response) {
            var  now = new Date();
            var s = now.getSeconds()-parent.test.getSeconds();
            console.log('success ajax: '+s);
            document.getElementById('core-credits').scrollTop = 0;
            document.getElementById('core-credits').innerHTML = response.responseText;
            console.log('finished');
        },
        error: function() {
            console.error('failed fetch credits');  
        }
    });
    }
    

    So the console log ("finished", last line in success()), comes immediately after clicking the menu "credits". But it can takes 6s (more or less) until I see the the div #core-credits. In my browser, I see #core-credits immediately after clicking. But the 2nd time clicking on that menu point I get the div after 1-2s. I don't now what that is, I don't think so, that is a caching thing, because I get into the success() callback really fast.

Java端:

    public void onCreate(Bundle savedInstanceState)
{
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    Context context = this.getApplicationContext();

    SharedPreferences wmbPreference = PreferenceManager.getDefaultSharedPreferences(this);
    boolean isFirstRun = wmbPreference.getBoolean("FIRSTRUN", true);
    if(isFirstRun) {
        this.copyAudioFiles(context);
    }

    WebView mWebView = (WebView) findViewById(R.id.webview);
    mWebView.getSettings().setJavaScriptEnabled(true);
    mWebView.getSettings().setDomStorageEnabled(true);
    mWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);

    String data = context.getFilesDir().getPath();
    mWebView.getSettings().setDatabasePath(data+"data/"+this.getPackageName()+"/databases/");
    mWebView.getSettings().setAllowFileAccess(true);
    mWebView.setWebChromeClient(new WebChromeClient());
    String data_root = Environment.getExternalStorageDirectory()+"/"
        +this.getPackageName();
    mWebView.loadUrl("file:///android_asset/www/index.html?system=android&" +
        "data_root="+data_root);  
}

我在eclipse虚拟平板设备和真实的华硕平板上遇到了性能问题。同时,动画效果(如jquery show('slow'))有时会非常缓慢或出现故障。例如(这是一款卡牌游戏),玩家通过show('slow')动画获得9张牌,但每第二次或第三次我只能获得3张或8张牌,而不是9张^^。所有这些问题在像Chromium或Firefox这样的浏览器中运行良好。我正在使用Android 4.1。启用硬件加速也没有帮助。有关此渲染问题的各种帖子都提到了硬件加速解决方案,但这并没有起到帮助作用。
5个回答

5
“我曾使用HTML5/JS混合移动应用框架在安卓上开发多个应用程序,但很遗憾,并没有一种万能的解决方案来解决所有性能问题。通常来说,JavaScript的性能不是问题,问题在于DOM频繁而且甚至浪费地进行改变/修改以及过多地使用CSS3效果,如在安卓上使用box-shadow导致FPS下降。”
“有一点可以帮助提高性能,就是使用CrossWalk作为WebView而不是原始的WebView组件。这意味着您可以在应用程序中获得最新版本的Chrome,而不必依赖于旧版本的系统WebView组件。您应该会观察到性能和稳定性的改善,因为您可以获得对WebKit软件改进的所有好处。”

https://crosswalk-project.org

其次,考虑使用避免频繁更改DOM的框架,例如具有虚拟DOM的React。

http://facebook.github.io/react/

React并不是唯一一个提供此功能的框架,还有其他旨在提供此领域性能改进的解决方案,如Famous。

http://famous.org

最后,选择构建应用程序的框架对我来说是最重要的步骤。尽管在改善浏览器性能方面进行了大量投资,但它们在不同领域的性能仍然存在差异,因此最好在开始时押注并选择适合解决问题的框架。
感谢您可能已经从中走出,希望这些建议能帮助其他人。
# 热爱JavaScript,厌恶浏览器

4

在这种情况下,忘记硬件加速-它是一个假朋友。在大多数情况下,它甚至比软件渲染更慢。

但有许多小细节可以优化:

编写更快的JavaScript

  • 始终使用选择器缓存(如果适用)(您的代码中应该只有一个document.getElementById('core-credits')出现)
  • 分组/解耦(请参见下一个点或直接使用setTimeout)代码执行和DOM操作(这总是会触发单个元素的重绘或更糟糕的是文档的回流)
  • 在某些应用程序中,我看到了使用requestAnimationFrame Polyfill进行dom操作的良好结果-不一定会导致更高的帧率,但在我的情况下,它使我能够正确地“投掷”openlayers地图(而不是设备不响应touchmove)

友好对待Android

  • 像 Intel AppFramework(前身为 jqmobi ui)一样,大量使用 CSS3 变换,而不是尝试 jQuery 风格的“滴答”动画。
  • 去掉 border-radius,改用透明 png 方法。
  • Android 上的其他昂贵渲染应该是:(-webkit-)box-shadow、text-shadow 和各种渐变效果(再次可以用老式的 png 替代)。

希望这有所帮助 - 我将继续在自己的应用程序中解决 Android WebView 的缓慢问题,并尽可能详细地阐述或更正信息。


嗯,像border-radius或box-shadow这样的css3东西并不是那么棘手。巨大的问题在于$.show('slow')或类似的东西。此外,滚动内容或仅搜索dom中的id并设置style.display ='block'也有点慢... - raffis
我不认为我可以写出更好/更快的代码(也许需要更多的选择器缓存),我猜Android webview就是这么慢。真遗憾!HTML5应用的未来不妙。 - raffis
具有渐变、边框半径等滚动内容肯定会很慢。 默认选择器操作(获取元素和显示/隐藏/更改样式)应该非常快,至少根据我使用 jQMobi 或 JQuery 2.x 的经验来看是这样的(其他所有内容肯定会更慢,因为在仅限于 Webkit 的环境中这是代码和性能的巨大浪费)。 - Philzen

1

是的,我做了,但没有帮助。 - raffis

0

对于动画效果,请将以下内容添加到元素的CSS中:

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

这是唯一一个真正对我的 Webview 产生影响的速度优化。但要小心不要过度使用它!(您可以在this article中了解更多有关此优化的信息。)

我还建议在 CSS 中执行动画。


0

浏览器必须在DOM更改时重新绘制UI。这对桌面设备影响不大,但会严重影响移动设备上的动画效果。 您应该考虑使用CSS3过渡效果,因为它们由GPU处理,性能更佳。 如果您不介意使用JavaScript库,我建议您尝试一下famo.us。 它声称能够提供60fps的动画效果。这似乎确实是真的。


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