【问题标题】:JavaScript constructs/patterns to avoid on iOS Safari?在 iOS Safari 上要避免的 JavaScript 构造/模式?
【发布时间】:2015-08-19 14:23:52
【问题描述】:

我有一个包含大量生成的 JavaScript 的网络应用程序。在桌面上的 Chrome 中运行网络应用程序与在(更新的)iPad 上在UIWebView 中运行网络应用程序相比,内存消耗相差 6 倍。

为了让 iOS 上的内存消耗与 Chrome 相当,我应该避免哪些构造或模式?

生成的 JavaScript 的特征:

  • 代码由Haxe生成。
  • 代码是“面向对象”的,因为它大量使用prototype,但在civilized way 中。
  • 代码大量使用 JavaScript 对象上的命名索引来实现哈希表。
  • 有很多字符串,但几乎没有任何字符串连接。

似乎没有任何内存泄漏; iOS 上过多的内存消耗会在构造(固定的)Javascript 对象时立即显示出来。

【问题讨论】:

  • 请注意,UIWebView 使用较旧的 Javascript 引擎,它在 iOS 上执行 JS 的速度比 Safari 慢。如果你在 Safari 中运行代码,运行速度够快吗?
  • 网络应用程序应该从 Safari 运行,我只使用 UIWebView 让 XCode 查看内存消耗,这就是问题所在(即 Safari 不时重新加载页面)。执行速度不是问题。
  • Mobile safari 使用 WKWebView,因此您的应用应该实例化其中之一来进行比较。您可能还想将 v8javascriptcore 添加到标签中,以便这两个 JS 引擎的专家可以参与进来。
  • 您是否尝试在专用 github 上打开问题? github.com/HaxeFoundation/haxe/issues
  • 我认为没有任何模式可用于解决有缺陷的实现。它可能只需要比 V8 更多的内存。

标签: javascript ios v8 haxe javascriptcore


【解决方案1】:

由于您的代码在桌面上运行良好,这可能是 iOS 中的一些潜在问题。我怀疑您可以使用更面向对象的编程方式来解决这个问题。当然,这可能会稍微减少内存占用,但不会减少 6 倍。

UIWebView 因创建内存泄漏而臭名昭著,您可以尝试使用较新的 (iOS 8+) WKWebView 具有很多更好的垃圾收集功能。

Apple WKWebView Reference

【讨论】:

    【解决方案2】:

    我的建议是查看应用程序的 DOM 部分。 我不认为您的 JavaScript 结构可以进行很多优化。 手机/平板中的薄弱环节通常是渲染过程。 如果您的目标是减少内存消耗,您可以更改 DOM 的工作方式。 尽量保持尽可能少的 DOM 节点,隐藏隐藏 DOM 节点的内容(节点内容)。 这种 DOM 操作在过去帮助我使我的网络应用程序更具响应性,并尽可能降低内存使用率。

    Virtual Scroll,对于保持 dom 尽可能小很有用,virtual-scroll

    【讨论】:

      【解决方案3】:

      您可以尝试优化代码的一种潜在方法是通过 GWT(我相信它的编译器是比 haxe 的 js 编译器更优化的编译器)。

      我会先把你所有的haxe代码编译成java,然后通过GWT把它转换成js,看看内存需求是否同样高。

      如果转换成 java,那么转换成 GWT 太难了,一个近似的方法是在通过 haxe 生成的 javascript 上使用 google 闭包编译器。我不确定 haxe 是否能够以与 ADVANCED_OPTIMIZATION 模式 (https://developers.google.com/closure/compiler/docs/compilation_levels#advanced_optimizations) 兼容的方式输出 javascript,这是您需要做的(否则,关闭并不比简单的代码最小化器好)。

      【讨论】:

        【解决方案4】:

        您提到它大量使用原型。 这可能是一个原因:如果您认为您的对象可以共享相同的原型,请尝试这样做;例如:

        baz.Bar = function () {
            // constructor
        };
        
        baz.Bar.prototype = {
            fooProp: ["bar", "foo"],
            foo : function (){
                //method
            }
        };
        
        baz.Bar2.prototype = baz.Bar.prototype;
        

        您会注意到 baz.Bar2.prototype 指向 baz.Bar.prototype。 有了这个概念,您可以节省 baz.Bar2 分配的内存,因为它与 baz.Bar 共享。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-09-21
          • 2017-09-05
          • 2015-11-19
          • 1970-01-01
          • 1970-01-01
          • 2016-03-21
          • 1970-01-01
          相关资源
          最近更新 更多