6

我正在用 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');  
        }
    });
    }
    

    因此,控制台日志(“完成”,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 渲染问题的帖子,但只有硬件加速解决方案没有帮助。

4

5 回答 5

4

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

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

编写更快的 javascript

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

对 Android 友好

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

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

于 2013-06-05T16:42:43.910 回答
4

在经历了在 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://着名的.org

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

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

#lovejavascript,#hatebrowsers

于 2015-09-04T10:08:45.953 回答
1

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

于 2013-04-02T09:40:02.510 回答
0

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

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

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

我也建议做动画我的 css

于 2014-04-09T21:05:43.170 回答
0

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

于 2015-10-04T13:10:42.173 回答