Конструкции/шаблоны JavaScript, которых следует избегать в iOS Safari?

У меня есть веб-приложение, которое содержит огромное количество сгенерированного JavaScript. Потребление памяти отличается в 6 раз при запуске веб-приложения в Chrome на рабочем столе по сравнению с запуском веб-приложения в UIWebView на (обновленном) iPad.

Каких конструкций или шаблонов следует избегать, чтобы потребление памяти в iOS было наравне с Chrome?

Характеристика сгенерированного JavaScript:

  • Код генерируется Haxe.
  • Код является "объектно-ориентированным" в том смысле, что он активно использует prototype, но цивилизованно.
  • В коде интенсивно используются именованные индексы объектов JavaScript для реализации хэш-таблиц.
  • Есть много строк, но почти нет конкатенаций строк.

Утечек памяти не наблюдается; чрезмерное потребление памяти в iOS проявляется сразу после создания (фиксированного набора) объектов Javascript.


person J P    schedule 19.08.2015    source источник
comment
Обратите внимание, что UIWebView использует более старый движок Javascript, он выполняет JS медленнее, чем Safari на iOS. Если вы запускаете код в Safari, достаточно ли быстро он работает?   -  person Mark Knol    schedule 19.08.2015
comment
Предполагается, что веб-приложение запускается из Safari, я использую UIWebView только для того, чтобы XCode мог видеть потребление памяти, в чем и заключается проблема (т.е. Safari время от времени перезагружает страницу). Скорость выполнения на самом деле не проблема.   -  person J P    schedule 20.08.2015
comment
Мобильное сафари использует WKWebView, поэтому ваше приложение должно создавать экземпляр одного из них, чтобы выполнить сравнение. Вы также можете добавить v8 и javascriptcore к тегам, чтобы эксперты по этим двум JS-движкам могли оценить ситуацию.   -  person Ed Ballot    schedule 28.08.2015
comment
Вы пытались открыть вопрос на выделенном github? github.com/HaxeFoundation/haxe/issues   -  person lifeisfoo    schedule 01.09.2015
comment
Я не думаю, что есть какие-либо шаблоны, которые можно применить для обхода ошибочной реализации. Возможно, ему просто нужно больше памяти, чем V8.   -  person Bergi    schedule 02.09.2015
comment
Если вы используете NSURLRequest, в соответствии со следующим ответом вы захотите поиграть с политикой кэширования, чтобы получить более репрезентативные числа. stackoverflow.com/a/22940315/3802077   -  person user3802077    schedule 08.09.2015
comment
Если у вас нет утечек памяти, как вы сказали, то здесь мало что можно сделать. Я не очень хорошо знаком с haxe, но похоже, что это корень вашей огромной памяти. Можно ли посмотреть откуда берутся барахла памяти?   -  person Eduard Jacko    schedule 04.11.2015


Ответы (4)


Поскольку ваш код хорошо работает на рабочем столе, вероятно, это какая-то особенность iOS. Что я сомневаюсь, что вы можете исправить, используя более объектно-ориентированный способ программирования. Конечно, это может немного уменьшить объем памяти, но не в 6 раз.

UIWebView довольно известен своими утечками памяти, которые вы можете попробовать использовать в более новой (iOS 8+) версии WKWebView, которая гораздо лучше справляется со сборкой мусора.

Справочник по Apple WKWebView

person Niels    schedule 30.12.2015

Мое предложение заключается в том, что вы должны изучить часть DOM вашего приложения. Я не думаю, что можно много оптимизировать в вашей структуре JavaScript. Слабым звеном в мобильных устройствах/планшетах обычно является процесс рендеринга. Если ваша цель — уменьшить потребление памяти, вы можете изменить способ работы DOM. постарайтесь сохранить как можно меньше узлов DOM, скройте содержимое (node-content) скрытых узлов DOM. такого рода манипуляции с DOM помогли мне в прошлом сделать мое веб-приложение более отзывчивым и максимально снизить использование памяти.

Виртуальная прокрутка полезна для того, чтобы дом был как можно меньше, " rel="nofollow">виртуальная прокрутка

person doron aviguy    schedule 28.01.2016

Потенциальный способ, которым вы можете попробовать оптимизировать свой код, - через GWT (чей компилятор, я полагаю, является более оптимизирующим компилятором, чем компилятор haxe js).

Я бы сначала скомпилировал весь ваш haxe-код в java, затем преобразовал его в js через GWT и посмотрел, остаются ли требования к памяти такими же высокими.

Если преобразование в java, а затем в GWT слишком сложно, близким приближением является использование компилятора закрытия Google для результирующего javascript, сгенерированного с помощью haxe. Я не уверен, что haxe способен выводить javascript способом, совместимым с режимом ADVANCED_OPTIMIZATION (https://developers.google.com/closure/compiler/docs/compilation_levels#advanced_optimizations), что вам и нужно сделать (иначе замыкание ничем не лучше простого минимизатора кода) .

person Chii    schedule 21.09.2015

Вы упомянули, что он активно использует прототип. Это может быть причиной: если вы думаете, что ваши объекты могут использовать один и тот же прототип, попробуйте сделать это; Например:

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.

person Lucman Abdulrachman    schedule 06.10.2015