javascript Android webview 性能下降
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15720426/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android webview slow performance
提问by raffis
I'm writing a game with javascript. This app runs well on my browser (fast), but I have some trouble to run that with android webview.
我正在用javascript编写游戏。这个应用程序在我的浏览器上运行良好(快速),但我在使用 android webview 运行它时遇到了一些麻烦。
- The time to start the app takes 5s or more (I think that is kind of slow, but maybe that is normal?)
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.
- 启动应用程序的时间需要 5 秒或更长时间(我认为这有点慢,但也许这是正常的?)
在游戏菜单中,我有一个方法,如:
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 side:
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);
}
I have this performance problems on my virtual tablet device in eclipse and also on my real asus tablet.
我在 eclipse 中的虚拟平板电脑设备和真正的华硕平板电脑上都遇到了这种性能问题。
Also animations (jquery show('slow')) are sometimes really slow or broken. For example (It is a card game), a player becomes 9 cards with the show('slow') animation, every 2nd or 3rd time I get 3 or 8 cards but not 9^^.
此外动画(jquery show('slow'))有时真的很慢或损坏。例如(这是一个纸牌游戏),一个玩家通过 show('slow') 动画变成 9 张牌,每 2 或 3 次我得到 3 或 8 张牌,但不是 9^^。
All this things above are working well on browsers like chromium or firefox. I'm working with Android 4.1.
以上所有内容在 Chrome 或 firefox 等浏览器上运行良好。我正在使用 Android 4.1。
Activate hardware acceleration didn't help. There are various posts about this rendering problem with webview, but only with the hardware accelaration solution, which didn't help.
激活硬件加速没有帮助。有很多关于 webview 渲染问题的帖子,但仅限于硬件加速解决方案,这没有帮助。
回答by Philzen
Forget about HW acceleration in this case - it's a false friend. In most cases it's even slower than software rendering.
在这种情况下忘记硬件加速 -这是一个虚假的朋友。在大多数情况下,它甚至比软件渲染还要慢。
But there are many small things you can optimise:
但是你可以优化很多小东西:
Write faster javascript
编写更快的javascript
- Always use selector caching, where applicable (there should be only a single occurence of
document.getElementById('core-credits')
in your code - Group / decouple (see next point or use
setTimeout
directly) code execution and DOM manipulation (which always triggers redraws on single elements or - even worse - a reflow of the document) - In some apps i saw good results using the requestAnimationFrame Polyfillfor dom manipulations - won't necessarily lead to a higher framerate, but in my case it allowed me to properly "fling" an openlayers map (instead of the device just not reacting to the touchmove)
- 在适用的情况下始终使用选择器缓存(
document.getElementById('core-credits')
在您的代码中应该只出现一次 - 分组/解耦(参见下一点或
setTimeout
直接使用)代码执行和 DOM 操作(它总是触发对单个元素的重绘,或者——更糟糕的是——文档的重排) - 在某些应用程序中,我看到使用requestAnimationFrame Polyfill进行 dom 操作的良好结果- 不一定会导致更高的帧率,但在我的情况下,它允许我正确地“抛出”一个 openlayers 地图(而不是设备只是不响应触摸移动)
Be Android friendly
对安卓友好
- Just like intel appframework (formerly jqmobi ui) does, make heavy use of css3 transformations rather than trying to jquery-style "tick" animations
- Removing border-radius and instead utilising a transparent png approach
- Other costly renderings on Android are supposed to be:
(-webkit-)box-shadow
, text-shadow and all kinds of gradients (which again one can exchange for old-school png's)
- 就像 intel appframework(以前的 jqmobi ui)一样,大量使用 css3 转换而不是尝试 jquery 风格的“滴答”动画
- 删除边界半径,而是使用透明的 png 方法
- Android 上其他昂贵的渲染应该是:
(-webkit-)box-shadow
、文本阴影和各种渐变(这又可以换成老式的 png)
Hope this helps - will try to elaborate more, resp. rectify information as i continue to fight android webview sluggishness in my own apps currently.
希望这会有所帮助 - 将尝试详细说明,分别。纠正信息,因为我目前继续在我自己的应用程序中与 android webview 缓慢作斗争。
回答by Daniel Maclean
Having gone through the process of developing several apps using Hybrid Mobile App frameworks in HTML5/JS on Android, i'm afraid there isn't a silver bullet that will fix all performance issues. Generally speaking, Javascript performance is not the problem, the problem is frequent and maybe even wasteful changes/modifications to the DOM and a over-use of CSS3 effects which slow the FPS down like box-shadow on Android.
在 Android 上使用 HTML5/JS 中的混合移动应用程序框架开发多个应用程序后,恐怕没有解决所有性能问题的灵丹妙药。一般来说,Javascript 性能不是问题,问题很频繁,甚至可能是对 DOM 的浪费性更改/修改以及过度使用 CSS3 效果,这会像 Android 上的 box-shadow 一样降低 FPS。
Something which might help, is to use CrossWalk as your WebView rather than the stock WebView component. This means you can get the latest version of Chrome inside your app without having to rely on older versions of the system WebView component. You should observe a performance and stability improvement as you can gain all the benefits of the software improvements to WebKit.
可能有帮助的方法是使用 CrossWalk 作为您的 WebView 而不是常用的 WebView 组件。这意味着您可以在您的应用程序中获取最新版本的 Chrome,而无需依赖旧版本的系统 WebView 组件。您应该观察到性能和稳定性的改进,因为您可以获得 WebKit 软件改进的所有好处。
Secondly, consider using a framework which avoids frequent changes to the DOM like React which has a virtual DOM.
其次,考虑使用避免频繁更改 DOM 的框架,例如具有虚拟 DOM 的 React。
http://facebook.github.io/react/
http://facebook.github.io/react/
React isn't the only framework to provide this and there are other solutions which aim to provide performance improvements in this area like Famous.
React 不是唯一提供此功能的框架,还有其他解决方案旨在提供该领域的性能改进,例如 Famous。
Lastly, choosing your frameworks to build your app on top of is for me, the most important step. Despite all the investment in improving performance of browsers, they all vary in performance in different areas, so best to hedge your bets at the beginning and pick frameworks which suit the problem you are trying to solve.
最后,选择你的框架来构建你的应用程序对我来说是最重要的一步。尽管在提高浏览器性能方面进行了所有投资,但它们在不同领域的性能各不相同,因此最好在开始时对冲您的赌注,并选择适合您要解决的问题的框架。
Appreciate you may have moved on from this, so hoping this advice will help others.
感谢您可能已经从这里开始,所以希望这个建议能帮助其他人。
#lovejavascript, #hatebrowsers
#lovejavascript, #hatebrowsers
回答by Mikael
did you enable hardware accelaration in your manifest?: http://developer.android.com/guide/topics/graphics/hardware-accel.html?
您是否在清单中启用了硬件加速?:http: //developer.android.com/guide/topics/graphics/hardware-accel.html?
回答by Erex
For the animations try adding this to the elements css:
对于动画,尝试将其添加到元素 css 中:
transform: translate3d(0,0,0);
-webkit-transform: translate3d(0,0,0);
This has been the only speedhack that really had a effect on my webview. But be careful not to overuse it! (you can read more about the hack in this article.)
这是唯一真正对我的 webview 产生影响的 speedhack。但要注意不要过度使用它!(您可以在本文中阅读有关 hack 的更多信息。)
I would also recomend doing the animations i css
我也建议做动画我 css
回答by Chromonav
Browser has to repaint the ui in Dom alterations. It doesn't affect us much on desktops but really clogs animations on mobiles. You should consider using css3 transitions as they are handled by gpu and are more performant. If you don't mind using a javascript library I would recommend you to try out famo.us It claims to bebe able to give 60fps animations. Which seems to be indeed true.
浏览器必须在 Dom 更改中重新绘制 ui。它在台式机上对我们没有太大影响,但确实会阻碍移动设备上的动画。您应该考虑使用 css3 转换,因为它们由 gpu 处理并且性能更高。如果您不介意使用 javascript 库,我建议您尝试使用 famo.us 它声称能够提供 60fps 的动画。这似乎确实是真的。