【问题标题】:Android webview slow performanceAndroid webview 性能慢
【发布时间】:2013-03-30 15:49:47
【问题描述】:

我正在用 javascript 编写游戏。这个应用程序在我的浏览器上运行良好(快速), 但我在使用 android webview 运行它时遇到了一些麻烦。

  1. 启动应用程序需要 5 秒或更长时间(我认为这有点慢,但也许这很正常?)
  2. 在游戏的菜单中我有一个类似的方法:

    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');  
        }
    });
    }
    

    所以控制台日志(“finished”,success() 中的最后一行)在单击菜单“credits”后立即出现。但在我看到 div #core-credits 之前可能需要 6 秒(或多或少)。 在我的浏览器中,单击后我会立即看到#core-credits。 但是第二次点击那个菜单点我在 1-2 秒后得到了 div。 我现在不知道那是什么,我不这么认为,这是一个缓存的东西,因为我很快就进入了 success() 回调。

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 张卡片,每 2 次或第 3 次我得到 3 或 8 张卡片,但不是 9^^。

以上所有这些都在 chromium 或 firefox 等浏览器上运行良好。 我正在使用 Android 4.1。

激活硬件加速没有帮助。有很多关于 webview 渲染问题的帖子,但只有硬件加速解决方案,这没有帮助。

【问题讨论】:

    标签: javascript android


    【解决方案1】:

    在这种情况下忘记硬件加速 - it's a false friend。在大多数情况下,它甚至比软件渲染还要慢。

    但是有很多小事情可以优化:

    编写更快的 javascript

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

    对 Android 友好

    • 就像 intel appframework(以前的 jqmobi ui)一样,大量使用 css3 转换而不是尝试 jquery 样式的“tick”动画
    • 移除边框半径,改为使用透明 png 方法
    • Android 上其他昂贵的渲染应该是:(-webkit-)box-shadow、text-shadow 和各种渐变(同样可以换成老式 png)

    希望这会有所帮助 - 将尝试详细说明,分别。纠正信息,因为我目前在自己的应用程序中继续与 android webview 迟缓作斗争。

    【讨论】:

    • 嗯,css3 诸如border-radius 或box-shadow 之类的东西并没有那么大的问题。巨大的问题是 $.show('slow') 或类似的事情。滚动内容或仅在 dom 中搜索 id 并设置 style.display = 'block' 有点慢...
    • 我不这么认为,我可以更好/更快地编写代码,(也许更多的选择器缓存),我猜Android webview就是那么慢。无赖!糟糕的 html5 应用未来。
    • 滚动具有渐变、边框半径等的内容肯定很慢。默认选择器操作(获取元素和显示/隐藏/更改样式)应该非常快,至少根据我使用 jQMobi 或 JQuery 2.x 的经验(其他一切肯定会更慢,因为它完全浪费了代码和性能仅限 webkit 的环境)
    【解决方案2】:

    在经历了在 Android 上使用 HTML5/JS 中的混​​合移动应用程序框架开发多个应用程序的过程之后,恐怕没有可以解决所有性能问题的灵丹妙药。一般来说,Javascript 性能不是问题,问题很频繁,甚至可能是对 DOM 的浪费性更改/修改以及过度使用 CSS3 效果,这会像 Android 上的 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

    最后,选择框架来构建应用程序对我来说是最重要的一步。尽管在提高浏览器性能方面进行了所有投资,但它们在不同领域的性能各不相同,因此最好在一开始就对冲您的赌注,并选择适合您要解决的问题的框架。

    感谢您可能已经从这里继续前进,因此希望此建议对其他人有所帮助。

    #lovejavascript, #hatebrowsers

    【讨论】:

      【解决方案3】:

      您是否在清单中启用了硬件加速?:http://developer.android.com/guide/topics/graphics/hardware-accel.html

      【讨论】:

      • 是的,我做了,但没有帮助。
      【解决方案4】:

      对于动画,尝试将其添加到元素 css:

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

      这是唯一对我的 webview 产生影响的 speedhack。但要注意不要过度使用它! (您可以在this article 中阅读有关该黑客攻击的更多信息。)

      我也推荐做动画 i css

      【讨论】:

        【解决方案5】:

        浏览器必须在 Dom 更改中重新绘制 ui。它在台式机上对我们影响不大,但确实会阻塞手机上的动画。 您应该考虑使用 css3 转换,因为它们由 gpu 处理并且性能更高。 如果您不介意使用 javascript 库,我建议您尝试一下 famo.us 它声称能够提供60fps的动画。这似乎是真的。

        【讨论】:

          猜你喜欢
          • 2015-11-25
          • 2023-03-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多