Pull to refresh

Почему мобильные веб-приложения такие медленные?

Reading time 13 min
Views 28K
Original author: Drew Crawford


Добрый день. Наша команда, которая занимается созданием курсов Java на Hexlet, решила заняться переводом статей, которые нам показались очень интересными. Занявшись этим делом мы обнаружили, что на Хабре еще не пробегал перевод великолепнейшей статьи под названием: "Почему мобильные веб приложения такие медленные?". Именно перевод ее части мы и предлагаем Вашему вниманию сегодня. Статья весьма не нова и от того еще больше удивило, что на Хабре не встретили ее перевода, но представляется актуальной (в своих идеях) и по сей день, хотя, само собой, много бенчмарков устарели. Если Хабра-сообществу понравилось начало, то мы опубликуем и вторую часть, а также начнем публикацию переводов других статей, которые нам показались весьма интересными и не представленными на Хабре.

Моя предыдущая статья, где я доказывал, что мобильные веб-приложения работают медленно, вызвала необычайно много интересных разговоров. Завязалась дискуссия, как онлайн, так и в реальной жизни, но, увы, она не была настолько основана на фактах, насколько бы мне этого хотелось.

В связи с этим, в данном посте я собираюсь представить реальные доказательства для обсуждения этой проблемы, а не просто устроить голословное перекрикивание. Вы увидите ключевые моменты, услышите мнения специалистов и даже прочитаете кристально честные журнальные статьи на данную тему. В данном посте содержится свыше 100 цитат, и это не шутка. Я не гарантирую, что данная статья убедит вас, или что абсолютно вся представленная информация не содержит ошибок (это невозможно для статьи такого объема), но я могу гарантировать, что это – наиболее полный и подробный анализ мнения многих разработчиков iOS о том, что мобильные веб-приложения работают и будут работать медленно в обозримом будущем.

Предупреждаю вас: это очень занудная и длинная статья почти на 10 тысяч слов. Таков формат. С недавнего времени я отдаю предпочтение хорошим, а не популярным статьям. Это – моя попытка написать хорошую статью, а также осуществить на практике то, к чему я ранее призывал: поощрять интересную дискуссию, основанную на фактах, и воздерживаться от остроумных комментариев.

Я пишу эту статью отчасти и по той причине, что данная тема обсуждается бесконечно (в форме обмена колкими фразами). Это не очередная статья на избитую тему, так что если вы ищете 30-секундную болтовню в духе «Нет, реально веб-приложения – отстой!» «Нет, не отстой», то эта статья не для вас. В Сети полно таких дискуссий в духе «О, прекратите это, не могу дышать, пожалуйста, остановитесь, так много мнений и мало фактов» и т.д. С другой стороны, насколько я могу судить, в настоящее время нигде не найти подробного, информативного и адекватного обсуждения данного вопроса. Это может показаться очень глупой идеей, но данная статья представляет собой мою попытку спокойно обсудить тему, которая уже породила совершенно бессмысленные банальные споры, заполненные флеймом. Моя позиция такова: проблема заключается скорее в том, что люди, способные более адекватно обсуждать вопрос, не участвуют в дискуссии, а не в самом предмете обсуждения. Думаю, мы выясним, так ли это.

Так что, если вы хотите узнать, какого рода помешательство нашло на ваших друзей-разработчиков, продолжающих писать злосчастные собственные приложения накануне уже очевидной веб-революции, или же узнать что-то еще, добавьте эту страницу в закладки, заварите себе чашку кофе, найдите свободный вечер, сядьте в удобное кресло, и вот, мы оба готовы к дискуссии.

Краткий обзор


В своем предыдущем посте я утверждал на примере SunSpider, что на сегодняшний день мобильные веб-приложения работают медленно.

«Конечно, если под «веб-приложением» вы подразумеваете «вебсайт с одной-двумя кнопками», то можно послать все жалкие тесты производительности вроде SunSpider куда подальше. Если же вы подразумеваете «быструю обработку текстов, редактирование фотографий, локальное хранилище и анимацию между экранами», то с мобильным приложением на ARM этого делать не следует, если только вы не самоубийца».

Данную статью действительно стоит прочитать, но я все же покажу вам тест производительности:

В целом данный сравнительный тест критикуется с трех позиций:

  1. Не секрет, что код JS медленнее, чем собственный код: все узнали об этом в CS1, когда сравнивали компилируемые, JIT и интерпретируемые языки. Вопрос в том, насколько его медленная работа влияет на программы, которые вы пишете, а подобные тесты производительности не могут решить эту проблему тем или иным способом.
  2. Да, JS работает медленнее, и это имеет значение, но его производительность постоянно растет, и однажды мы впервые заметим, что разница в скорости уже незначительна, так что начинайте инвестировать в JS уже сейчас.
  3. Я пишу серверную программу на Python/PHP/Ruby и мне без разницы, что вы там гоните. Я знаю, что мои серверы быстрее ваших мобильных устройств, но, в самом деле, мне не составляет особого труда обслуживать X000 пользователей, используя фактически интерпретируемый язык, но можете ли вы, ребята, представить себе, как обслуживать одного пользователя в языке с высокопроизводительным компилятором JIT? Насколько трудно это может быть?

Я поставил перед собой довольно амбициозную цель: опровергнуть в данной статье все три претензии. Да, JS работает медленно, и это действительно имеет значение. Нет, в ближайшем будущем он не станет заметно быстрее. Нет, ваш опыт с серверным программированием не подготовит вас должным образом к тому, чтобы «начать с малого» и грамотно рассуждать о производительности мобильных приложений.

Главная же проблема заключается в том, что во всех статьях на данную тему редко приводятся цифры, показывающие, насколько медленно работает код JS, или приводится какой-нибудь действительно полезный критерий сравнения (медленно… по сравнению с чем?). Для того чтобы это исправить, я в данной статье приведу не один, а три эквивалента производительности для JavaScript. Поэтому я не только опровергну «старые песни» о «медленной работе JS», но и покажу в цифрах, насколько медленно он работает, и сравню со многими показателями из реального программирования, чтобы, когда вы столкнетесь с необходимостью выбора платформы, вы смогли бы самостоятельно быстро произвести вычисления и определить, эффективен ли JavaScript для решения вашей конкретной проблемы.

Все это хорошо, но как именно сравнивать производительность JS с производительностью собственных приложений?


Хороший вопрос. Чтобы ответить на него, я выбрал произвольный тест производительности из Benchmarks Game. Затем я нашел более старую программу на C, которая выполняет тот же тест (более старую, так как у новых имеется множество деталей, зависящих от x86). После этого я сравнил Nitro с LLVM на моем проверенном iPhone 4S. Весь этот код можно найти на GitHub.

Все это очень произвольно, но ведь и код, который вы выполняете в реальной жизни, является таким же произвольным. Если вам нужен эксперимент получше, что ж, экспериментируйте. Это всего лишь мой эксперимент, поскольку других экспериментов для сравнения LLVM и Nitro пока нет.

Так или иначе, в данном синтетическом тесте производительности LLVM неизменно оказывается в 4,5 раза быстрее, чем Nitro:

Так что, если вам интересно, насколько быстрее ограниченная процессором функция в собственном коде по сравнению с Nitro JS, ответом будет «примерно в 5 раз». Этот результат в целом совпадает с результатами Benchmarks Game с x86/GCC/V8, согласно которым, GCC/x86 в целом в 2 – 9 раз быстрее, чем V8/x86. Таким образом, результат, судя по всему, близок к истине и не зависит от того, используете ли вы ARM или x86.

Но разве 1/5 производительности недостаточно?


Достаточно для x86. В самом деле, насколько сильно нагружает процессор визуализация таблицы? Не так уж и сильно. Проблема в том, что ARM – это не x86.

По данным GeekBench, сравнение последней модели MBP с последней моделью iPhone показал коэффициент 10, так что все нормально, таблицы не такие уж и тяжелые. Можно работать и с производительностью в 10%. И вы еще хотите разделить её на пять? Браво, дружище! Теперь у нас получилась производительность в 2% от настольного компьютера (Я произвольно оперирую единицами, однако мы имеем дело с порядком величин. Ладно, сойдет).

Хорошо, но насколько трудна обработка текстов на самом деле? Разве нельзя делать это на процессоре типа m68k, присоединив к нему еще один процессор? Что ж, на этот вопрос можно ответить. Возможно, вы не помните, но взаимодействие с Google Docs в реальном времени на самом деле не было просто функцией запуска. Они очень многое переписали заново к апрелю 2010 года. Давайте посмотрим, какова была производительность браузеров в апреле 2010 года.



Судя по данному графику, совершенно очевидно, что iPhone 4S абсолютно не сопоставим с веб-браузерами в эпоху взаимодействия с Google Docs в реальном времени. Впрочем, он может конкурировать с IE8, с чем я его и поздравляю.

Рассмотрим другое серьезное приложение JavaScript: Google Wave. По данным Google, Wave никогда не поддерживал IE8, так как тот работал слишком медленно.



(Для использования Google Wave в Internet Explorer необходимо установить плагин для браузера Google Chrome Frame. Как вариант, можно использовать один из следующих браузеров: Google Chrome, Safari 4, Firefox 3.5. Если вы хотите продолжить работу на свой страх и риск, перейдите к следующему шагу).

Видите, насколько эти браузеры быстрее, чем iPhone 4S?

Видите, как все поддерживаемые браузеры показывают результат ниже 1000, а тот, что показал результат 3800, исключен из-за низкой скорости? iPhone показывает результат 2400. Как и IE8, он работает недостаточно быстро, чтобы запускать Wave.

Внесем ясность: можно работать в реальном времени на мобильном устройстве, но нельзя делать это в JavaScript. Разница в производительности между собственными и веб-приложениями сопоставима с разницей в производительности между FireFox и IE8. Это слишком большая разница для серьезной работы.

Но я думал, что производительность V8 / современного JS почти не уступает C!


Все зависит от того, что подразумевается под «почти». Если ваша программа на C выполняется за 10 мс, то скорость в 50 мс у программы на JavaScript будет «почти» равна скорости C. Если же ваша программа на C исполняется за 10 секунд, то 50 секунд программы на JavaScript для большинства обычных людей явно не будут скоростью, почти равной C.

Аппаратный аспект


И все же коэффициент 5 приемлем для x86, прежде всего потому, что x86 в 10 раз быстрее, чем ARM. Имеется много пространства для маневра. Это решение явно предназначено лишь для ускорения ARM в 10 раз, так что оно сопоставимо с x86, а затем можно добиться производительности, как у JS на настольном компьютере без лишних усилий!

Будет ли это работать, зависит от вашей веры в закон Мура касательно попытки зарядить чип аккумулятором весом 3 унции. Я не инженер по аппаратуре, но когда-то я работал в крупной компании-производителе полупроводников, и ее работники говорили мне, что в настоящее время производительность зависит в основном от технологического процесса (т. е., величины, измеряемой в нанометрах). Впечатляющая производительность iPhone 5 связана большей частью с уменьшением технологического процесса с 45 нм до 32 нм, то есть, уменьшением примерно на треть, но чтобы повторить это, Apple пришлось бы ужать техпроцесс до 22 нм.

Просто для справки: версия 22 нм x86 Atom Bay Trail от Intel в настоящее время не существует. Intel пришлось изобретать совершенно новую разновидность проводника, так как стандартная разновидность не работала в масштабе 22 нм. Думаете, они продадут ARM лицензию на нее? Подумайте еще раз. В мире всерьез планируется построить лишь несколько предприятий по производству интегральных схем 22 нм, и большинство из них контролирует Intel.

На самом деле, ARM, судя по всему, стремится уменьшить техпроцесс до 28 нм или около того (см. A7), а Intel между тем стремится к 22 нм, а возможно даже к 20 нм. Если рассматривать только аппаратный аспект, то мне кажется гораздо более вероятным, что чип x86 с производительностью класса x86 найдет применение в смартфоне гораздо раньше, чем появится возможность уменьшить чип ARM с производительностью класса x86.

Примечание от бывшего инженера Intel, приславшего мне письмо по электронной почте:

«Я – бывший инженер Intel работавший над линией микропроцессоров для мобильных устройств, а затем в Atoms. Как бы то ни было, по моему невероятно предвзятому мнению, проще будет установить x86 на телефон с «набором функций» из более крупных ядер, чем ARM догнать по производительности x86, разрабатывая эти функции с нуля».

Примечание от бывшего инженера Robotics, приславшего мне письмо по электронной почте:

«Вы совершенно правы в том, что они ненамного увеличат производительность, и что у Intel через несколько лет может появиться более быстрый процессор для мобильных устройств. По сути, в настоящее время мобильные процессоры испытывают то же ограничение, что и процессоры настольных компьютеров, когда достигли 3 ГГц: дальнейшее увеличение тактовой частоты нецелесообразно без кардинального увеличения мощности. Это справедливо и для следующих узлов процесса, хотя они должны иметь возможность немного увеличить IPC (возможно, на 10-20%). Когда они столкнулись с этим ограничением, стали выпускаться двухъядерные и четырехъядерные процессоры для настольных компьютеров, однако мобильные системы на кристалле уже являются двух- и четырехъядерными, так что добиться ускорения будет нелегко».

Таким образом, в конечном итоге закон Мура, возможно, и верен, но только в том, что для перехода к x86 потребуется целая мобильная экосистема. Нельзя сказать, что это невозможно, раньше это уже делалось. Правда это было в эпоху, когда ежегодный объем продаж составлял порядка миллиона единиц, а сейчас продается 62 миллиона в квартал. Это было сделано с помощью готовой среды виртуализации, которая могла имитировать старую архитектуру со скоростью примерно в 60%. Между тем, производительность современных гипотетических поисковых систем виртуализации для оптимизированного (O3) кода приближается к 27%.

Если вы полагаете, что в конечном итоге JavaScript придет к этому, то наиболее эффективным способом будет усовершенствование аппаратуры. Либо у Intel через 5 лет будет жизнеспособный чип (вероятно), а Apple поменяет концепцию (маловероятно), либо ARM в течение следующего десятилетия выйдет из игры (пообщайтесь с 10 инженерами по аппаратуре, и вы получите 10 разных мнений о вероятности такого варианта). Впрочем, десятилетие – это долгий срок для проекта, который может увенчаться успехом.

Боюсь, на этом мои познания в области аппаратуры заканчиваются. Могу сказать вам только одно: если хотите верить, что ARM преодолеет разрыв с x86 в ближайшие 5 лет, в первую очередь вам необходимо найти того, кто работает над ARM или x86 (то есть, человека, действительно обладающего знаниями), чтобы он согласился с вами. Для написания данной статьи я консультировался со многими квалифицированными инженерами, и все они отказались официально озвучить такую позицию, поэтому мне кажется, что в в ней ничего хорошего нет.

Программный аспект


Здесь многие компетентные инженеры ПО заходят в тупик. Они мыслят так: JavaScript стал быстрее, и будет ускоряться и в дальнейшем!

Первая часть данного утверждения соответствует истине. JavaScript стал гораздо быстрее. Тем не менее, он уже достиг пика и в будущем его скорость существенно не вырастет.

Почему? Во-первых, большая часть улучшений в JavaScript за всю его историю на самом деле касалась аппаратуры. Вот что пишет Джефф Этвуд:

«Я обнаружил, что производительность JavaScript существенно улучшилась в период с 1996 по 2006 год. То, что Web 2.0 построен на основе JavaScript, стал возможным в основном благодаря решающим улучшениям производительности согласно закону Мура».

Если связать ускорение JS с аппаратурой в целом, то улучшение производительности (аппаратной) JS не является предпосылкой для улучшения производительности программ в будущем. Именно поэтому, если вы хотите верить, что JS будет ускоряться, на сегодняшний день это скорее всего будет происходить за счет ускорения аппаратуры, поскольку об этом свидетельствует историческая тенденция.

А как насчет JIT,V8, Nitro/SFX, TraceMonkey/IonMonkey, Chakra и остальных? Что ж, в момент выхода они были чем-то значимым, хотя и не таким значимым, как вы думаете. V8 вышел в сентябре 2008 года. Примерно в это же время я откопал копию Firefox 3.0.3:

Поймите меня правильно, рост производительности в 9 раз нельзя игнорировать, в конце концов, это число почти равно разнице между ARM и x86. Таким образом, разница в производительности между Chrome 8 и Chrome 26 остается на том же уровне, поскольку с 2008 года ничего крайне важного не произошло. Другие производители браузеров наверстали упущенное (кто-то быстрее, кто-то медленнее), но никто с тех пор по-настоящему не увеличил скорость самого кода процессора.

Улучшается ли производительность JavaScript?


Вот Chrome v8 на моем Mac (самая ранняя версия, которая все еще работает, декабрь 2010), а вот v26.


Не видите разницы? Это потому, что ее нет. В последнее время не произошло ничего крайне важного с JavaScript, ограниченным процессором.

Если Сеть кажется вам быстрее, чем в 2010 году, то это, вероятно, из-за того, что вы работаете на более быстром компьютере, а улучшения в Chrome здесь ни при чем.

Примечание. Некоторые умные люди отметили, что в наши дни SunSpider не является хорошим тестом производительности (при этом они отказались предоставить какие-либо актуальные цифры). Чтобы начать осмысленную дискуссию, я выполнил Octane (тест Google) на старых версиях Chrome, и он показал некоторое улучшение:


По моему мнению, улучшения производительности, приобретенного за этот период, недостаточно подтверждения заявления о том, что JS ликвидирует разрыв в обозримый промежуток времени. Тем не менее, надо признать, что я переоценил данный случай, так как что-то все же происходит в JavaScript, ограниченном процессором. Тем не менее, для меня эти числа подтверждают большую гипотезу: эти улучшения – совсем не те величины, что могут устранить разрыв с собственным кодом в обозримом будущем. Необходимо улучшить все в 2 – 9 раз, чтобы конкурировать с LLVM. Эти улучшения хороши, но не до такой степени. Конец примечания.

Дело в том, что идея применения JIT в JavaScript возникла 60 лет назад. За ней последовали 60 лет исследований и буквально тысячи реализаций для всех языков программирования, чтобы доказать, что это была хорошая идея. Сейчас же, когда мы сделали это, мы исчерпали идеи 60-летней давности. Все, друзья, шоу окончено. Возможно, нам удастся выработать еще одну хорошую идею в течение следующих 60 лет.

Но ведь Safari вроде бы быстрее, чем раньше?


Если это правда, то почему мы постоянно слышим обо всех великих улучшениях производительности в JavaScript? Чуть ли не каждую неделю кто-то рекламирует огромные ускорения в каком-нибудь тесте. Здесь Apple заявляет об ошеломляющем ускорении в 3,8 раза в JSBench:



Выходит, Safari 7 в 3,8 раза быстрее других браузеров?

Возможно, для удобства Apple, информация о данной версии Safari не разглашается, так что никто не может опубликовать независимые данные о быстродействии Safari. Тем не менее, позвольте мне высказать ряд соображений по данному заявлению, основанных только на общедоступной информации.

Прежде всего, меня заинтересовал тот факт, что в открытых сообщениях о JSBench Apple сообщает о гораздо более высоких результатах, нежели в сообщениях о традиционных тестах вроде SunSpider. Сейчас за JSBench стоят некоторые интересные люди, например, Брендан Эйх, создатель JavaScript, однако в отличие от традиционных тестов, в JSBench не пишется программа, где решающую роль играют целые числа или что-то в этом роде. Вместо этого JSBench автоматически сгребает все, что преподносят Amazon, Facebook и Twitter, и создает из всего этого тесты. Если вы пишете веб-браузер, который (скажем честно) большинство людей использует для посещения Facebook, я представляю себе, насколько полезно иметь тест исключительно для Facebook. С другой стороны, если вы пишете программу для работы с таблицами, игру или приложение для фильтрации изображений, мне кажется, что традиционный тест с его арифметикой целых чисел и хэшированием md5 пригодится вам гораздо больше, чем наблюдение за скоростью аналитического кода Facebook.

Другой важный факт состоит в том, что, по заявлению Apple, улучшение производительности в SunSpider не всегда означает улучшение чего-либо еще. В том же самом документе, который представляет предпочтительный тест Apple, Эйх и другие пишут следующее:

«Диаграмма четко показывает, что, по данным SunSpider, производительность версии 3.6 Firefox увеличилось в 13 раз по сравнению с версией 1.5. Тем не менее, если посмотреть на улучшения на Аmazon, то они выглядят гораздо скромнее – 3 раза. Что еще интереснее, за последние два года улучшения на Аmazon выровнялись. Судя по всему, некоторые оптимизации, которые хорошо работают на Sun Spider, малоэффективны на Аmazon».

В этом же самом документе создатель JavaScript и один из ведущих архитекторов Mozilla открыто признает, что за последние два года с производительностью JavaScript сайта Amazon совершенно ничего не произошло, и никогда не случалось ничего невероятно захватывающего. Это говорит о том, что маркетологи просто годами навязывают свою продукцию.

В продолжение темы они утверждают по сути, что тестирование производительности Amazon является лучшим средством прогнозирования работы Amazon, чем тестирование производительности SunSpider [э-э-э… очевидно…], следовательно, оно хорошо подходит для веб-браузеров, которые используются для посещения Amazon. Тем не менее, все это не поможет написать приложение для обработки фотографий.

Но в любом случае, опираясь на открытую информацию, я могу сказать, что заявления Apple об увеличении производительности в 3,8 раза не всегда означают что-то полезное для вас. Также могу сказать, что если бы у меня были тесты, опровергающие заявления Apple о превосходстве над Chrome, мне бы не позволили опубликовать их.

Так что давайте закончим данный раздел следующим выводом: если у кого-то имеется график, показывающий, что его веб-браузер быстрее, это не означает, что JS в целом становится быстрее.

Очень надеемся, что статья Вам понравиться на столько же, на сколько она понравилась в свое время и нам. Если это так, то в скором времени Вас ждет вторая часть перевода.
Only registered users can participate in poll. Log in, please.
Продолжать перевод?
73.78% Продолжать перевод этой статьи 242
9.45% Продолжать перевод, но другой статьи 31
16.77% Не продолжать перевод 55
328 users voted. 119 users abstained.
Tags:
Hubs:
+12
Comments 46
Comments Comments 46

Articles