(disclaimer: I work for Adobe on a competing service (PhoneGap Build) and have worked with PhoneGap for years)
This is a silly benchmark - there is absolutely no reason you would put 1000 calls at once, sequential or parallel, across this sort of bridge in a real app. You probably shouldn't be calling any JavaScript API in a client-side app 1000 times at once.
The bridge in PhoneGap Android probably is slower than the one in Forge but
1) that's a tradeoff the PhoneGap devs were willing to make for wider compatibility, support for older devices, and isolation from the bizarre Android WebKit bugs that crop up in every release.
2) synthetic benchmarks aside, there's no indication this would affect the usability of the app.
Take the camera example in the article. A PhoneGap call (judging from the graphs) takes about 14ms, a Forge call about 3ms. That's for the entire round trip (JavaScript -> Native -> JavaScript), so divide each in half for each side of the trip.
With PhoneGap:
* first half of the trip (7ms)
* Android presents Camera activity, user picks a photo, Android returns control to original app (say, 500ms, very conservatively)
* second half of the trip (7ms)
= 514ms
With Forge:
* first half of the trip (1.5ms)
* Android presents Camera activity, user picks a photo, Android returns control to original app (500ms)
* second half of the trip (1.5ms)
= 503ms
This is much closer to a real-world use case - and the calls to native APIs entirely dominate the time spent on the bridge.
Hey Andrew - a disclaimer of my own: I'm a co-founder of Trigger.
Actually, we think this is a pretty important benchmark: battery drain and general responsiveness is a huge deal on mobile devices, so we take performance of the bridge very seriously. Every millisecond counts here.
Also, I can absolutely see the need to send large number of messages - a streaming accelerometer API, for example, which is on our roadmap.
You're right that there might be trade-offs between raw performance and supporting every quirk of every device. However, in this case, the Android bug you refer to only affects v2.3 emulators, not actual devices (to the best of our knowledge). We automatically set up our users with a v2.2 emulator to side step the problem.
We think such significant performance gains for our users, and a much cleaner, easier to maintain codebase for us, is well worth it in this case.
That's disingenuous: if every millisecond counted, then you'd be developing apps natively instead of using a web bridge.
Clearly, there is a tradeoff to be made between usability&portability and speed. To be fair, I think the camera example is not a good one: at Zite we use web<->native api for lots of things that performance is really important for since they are frequent (logging, timing, anything called frequently)
Disagree it's disingenuous. I'm a web developer without any mobile experience. I accept there will be some performance impact from using a web bridge. However, I want to minimize this as far as possible - and all the studies show milliseconds really do count so far as usability goes.
Agree the web<->native api performance is important for the use cases you mention.
Although performance is important, as someone who does PhoneGap apps for a living (http://mulberry.toura.com) I can tell you that there are so many other performance problems with HTML5 that this is wayyy premature optimization.
11ms isn't going to kill you, and if you are experiencing performance problems, there are far more important things to do (check for DOM leaks, dealing with 3G latency, etc.) than shave off a few ms on a call to a native function.
Or put another way, there's no reason to create another PhoneGap-like framework to save 11ms on a native function call. There are a whole lot of other reasons (many business-related) of course. But this isn't one of them. :)
Of course, there were a number of reasons we were wary of being downstream of PhoneGap. The specific issue of Android performance wasn't a blocker, but was, to us, symptomatic of a philosophical difference between PhoneGap's approach and ours. We're not saying one is Right and one is Wrong - we just have different priorities.
Another key aspect for us was that our runtime platform is tightly integrated with our tooling: how those tools interact with the generation of runnable apps is obviously key to usability of our product, so we were very uncomfortable not owning such a key part of the puzzle.
The other option would have been to fork PhoneGap with no intention to push upstream, but that, to me, is against the spirit of open source, and still not optimal to us as we'd need to shoe-horn our tooling to fit a code base not designed with our needs in mind.
This a million times. I spent a better part of the last year optimizing the hell out of an HTML5 app and the bottlenecks are almost entirely in initial rendering time (CSS stylesheets and HTML Parsing/Manipulation and coaxing the memory management to not explode on you with a lot of images).
Hi,
Agreed that in your standard app, the overhead of rendering will outweigh that of communication with native code.
For us at Trigger, however, we don't have any control over the efficiency of your Javascript, or the interpreter and rendering engine that holds it.
What we can control is how efficient the communication is between your JS and the underlying native APIs. Everyone agrees that performance is a key issue, so we take great care to ensure that the performance of code we control is as small as possible.
I just wanted to say that I LOVE Zite on my TouchPad, every single day I spend about 2 hours looking at all articles... it is a joy to use. Thanks for the hard work making quality webOS software....
re only affecting emulators: see @pmuellr's reply below - the bug in question affects 2.2 devices also. Since we're a community-driven open source project, you can see the discussion process :)
http://groups.google.com/group/phonegap-dev/browse_thread/th...
Again, "such significant performance gains for our users" is just FUD when you're talking about arbitrary benchmarks. An app built using Forge and PhoneGap, providing the same functionality, with the same UI layer, would be a much better measure of that. I'd be happy to be proven wrong.
Thanks for the link - I can only see two mentions of 2.2 in that thread: one (in the first question) where the OP was asking about it, and another mention from Patrick, suggesting he think the issue only affects 2.3 phone using JSC. We don't know of any shipped phones that fall into that category.
Remember, this post was called "Why Trigger.io doesn’t use PhoneGap" - it's about the reasons we chose not to live downstream from you, not just a post bashing what you've done.
For us, the significant delta in performance is evidence of a different philosophy between what we are aiming for, and what you offer. We clearly want to make different design decisions, and need to be independent to do that properly.
> Also, I can absolutely see the need to send large number of messages - a streaming accelerometer API, for example, which is on our roadmap.
There is no benefit to sending ondevicemotion events out to the native code because you can always get higher frequency updates on the native code (60Hz vs 20Hz) and sending them in via stringViaEvaluatingJavascriptFromString is identical between Trigger.io and PhoneGap (and will happen with a lower latency than things are drawn on screen in a UIWebView).
Hi James. You do realize that the bridge can be optimized to the bone to beat Trigger if needed. Even with the negligible difference in bridge speed, Cordova is superior to your closed platform because it is open.
It is perfectly OK if you learn from inspecting the open platform, just don't come back to badmouth it.
I hate to hijack, but are you guys seeing any of these apps rejected by Apple because they weren't made with native controls or any other reason? There's a project I'm going to begin working on and phonegap looks like a real time saver to me, but I don't want to have to deal with Apple telling me that my apps aren't "good enough" for them.
We've submitted hundreds of apps with PhoneGap and never had Apple reject due to PhoneGap. However, if your HTML/CSS looks terrible, Apple will probably reject you. Especially if it's just a static website app. Make it look nice and give it more functionality than a static website, and you should be fine.
They tried to do that a few years ago, but nowadays they don't reject just because an app is web-based. I have one that's 95% HTML5 and it was approved absolutely fine.
On a side note, are there plans to develop a better set of debugging tools for PhoneGap? It's one of the major pains of the platform. If one is already in development can you point me in the proper direction? Thanks!
Debugging tools definitely need to be improved, but what I struggle with the most are memory/crashing bugs. XCode, for all its warts, provides sophisticated tools for handling this. Troubleshooting these issues on WebKit+PhoneGap is a miasma of trial and error, especially if the bug is hard to replicate on a desktop with 10 times as much RAM as a mobile device.
Ripple (http://ripple.tinyhippos.com/) does a pretty good job. You can get an extension for Chrome. It will simulate PhoneGap events and extend JS api's to support what iOS and Android should have. Kind of clunky but pretty useful.
Interesting - haven't heard of Trigger.io before (I build a lot of PhoneGap applications). One thing that's going to keep me on PhoneGap for the foreseeable future, despite its issues, is the fact that it is an Open Source project now. I trust ASF + volunteers more than any startup/company.
facepalm. First, it is generally better to apply performance improvements to the existing framework than to create a new one.
Second, different is not always better. This will increase call performance, but will incur a (de)serialization penalty, limit parameter types (likely to scalars and read-only hashmaps), and make debugging more difficult. And beware of telling the OS that you implement this protocol, or you will have created an XSS attack vector on your native app.
Whenever you break new ground, don't fool yourself into thinking that you're the first person who has had an idea, and make sure that you sanity check your work.
We totally agree that when things have a solid foundation it makes sense to build on top of them. The problem we saw with Phonegap was several design decisions we disagreed with (as we described briefly in the blog post).
This left us with the option of putting up with it (and ending up with an inferior product), or writing our own bridge, and writing our own bridge made sense. Of course you are right in that writing anything new means you have to work hard to get it to as high a standard as the alternatives, which is why we work hard to test our platform - see http://trigger.io/cross-platform-application-development-blo....
It's also important to remember that the native bridge is just one part of our product, we also write the code that generates and builds the app, which we want to integrate as tightly as possible. Writing our own bridge makes this a lot easier to do well.
You gotta admit the native bridge is pretty important though, it could be a bottleneck for all the nice bits native code. On that basis the bridge is fundamental to good performance.
It would have been great to see these improvements contributed back to PhoneGap/Cordova, which has an extremely permissive license and whose code is open-source. As it is, trigger.io comes with a restrictive license, I have to create an account to use it, I can't see the code, and they mandate that I include their branding with any free use of their product. Yay.
Is trigger.io a fork of PhoneGap? If not, "contributed back" isn't exactly the right phrase.
In any case, I think that anyone is free to do whatever they want with their code- trigger.io are not obliged to liberally license their work. They even describe how they've achieved their performance increase in the blog post- it's more than many would do.
We're trying to optimize the development cycle for web devs. So it's not just about the bridge itself, but also keeping the code around it lean and fit in with our command line tools / cloud build service. All so the build / test cycle is seconds.
Also we're a small team so don't have time to do everything we would like, and also contribute to Cordova. Trigger.io's native bridge is not a a fork of PhoneGap or downstream of it.
This is an awesome read. I've made an HTML5-based app (overview at http://taxono.my for the curious), but have been stuck using Appcelerator, because I need to use the hooks to run code in the background- AFAIK PhoneGap and the like do not have the ability to do this unless you make an Objective-C plugin.
But the bridge between the webview and the Appcelerator code is painfully slow. I had it pinging over current location coordinates more than once per second- it worked fine in the simulator but utterly crippled the app when run on a device. For now all I can do minimize the number of calls I make, but that's hardly a great solution.
Thanks! The app was developed for an NYC app making competition (http://2011.nycbigapps.com) and so, with a deadline- so the Android version ended up not being finished in time.
Rest assured, the Android version is on the way. In fact, this app-crippling native <-> webview communication is what has taken up all my time and stopped me from developing the Android version.
Looking forward to the day you guys have a solution for background processing- the Appcelerator JS/native hybrid is a mess I'd love to see the back of.
Anyone have experiences of moving from PhoneGap to Trigger.io? Sounds like the tooling is a bit simpler to use (you can avoid XCode): http://www.quora.com/How-is-Trigger-io-better-than-PhoneGap-... But otherwise I can't see many inducements to using Trigger.io's commercial service over open-source PhoneGap.
When thinking about the pricing model, you should compare us to a combination of PhoneGap's cloud build service (which is also fremium and restrictive) and their support packages:
The main difference with us is that you do not pay to raise a support tickets: you get direct access to our developers on any plan. And we charge per-app with no restrictions on the number of developers.
It seems, from what I can tell, users must go through Trigger.io to do a build to get their app in the store. Their code isn't portable to a non-trigger.io platform, either (mobile web, etc.), and the built binary contains closed-source code (Trigger.io platform stuff).
You can run a PhoneGap build locally without going thru the PhoneGap build service. And you get complete and unrestricted access to the source code.
If your service disappears or starts charging exorbitant amounts of money, users are SOL.
Trigger.io is a commercial entity that is in the business of locking customers into a platform and exploiting it. PhoneGap is the opposite. I place no value judgements on this (I use plenty of licensed code on a daily basis and I work for a commercial entity doing something similar); that may or may not matter to a person, but to me - that seems to be the main difference.
+1. Even if there is perfect trust with a platform vendor, that doesn't mean they won't come under new management tomorrow that rewrites the rules. That's a scary proposition for the backbone of one's business, since porting to a new platform is almost as much work as writing it in the first place.
I can't say I never use closed libraries/platforms/APIs, but when possible, I always choose the option that has a community fork, or some other escape route.
We think the biggest barrier to adoption of a platform like ours or PhoneGap's is complexity. So to keep the API and dev process as simple as possible we decided to keep control of the whole experience for our launch. Now, we're considering opening up more than just our command line tools, and will likely start doing that soon.
But being closed for now, people will hold us to a higher standard of simplicity, performance and customer support to give them a reason to change. We work hard to live up to that.
What you consider the 'main' thing is subjective, just wanted to point out the difference in how we support our customers and the pricing for it in the previous comment.
re: "This approach is heavier and hackier, but a decision they made in order to sideline a bug in the Android 2.3 simulation. It’s not a bug that affects actual Android 2.3 devices, so we take this to be a bit of overkill."
From what I could tell, the bug was shipped starting with some version of Android 2.x (I'm thinking 2.2) where JSC was used as the internal JS engine for WebKit instead of V8. When the Android devs added V8 support, they actually broke JSC support. It's a device manufacturer choice (or was) as to which JS engine to use. Curiously, Android shipped the 2.3 simulator image (guess that was the version) with JSC support, thus, "it was broken".
The API in question is `WebView.addJavascriptInterface()`. That method returned successfully, but whenever you accessed the interface from JS, you'd trap.
Could be this was only on the simulator, but - I'm thinking folks saw this on devices as well. Maybe those devices are no longer relevant?
Presumably Cordova will revert back to using `WebView.addJavascriptInterface()` when it's safe to do. The problem is, it's not clear when it's safe to do so. It's also not clear how you can test your JS environment to see if "it's safe", programmatically. Or maybe you can (eg, throw an Error, check for existence of error.stack), but ... it's wasn't a comfortable situation to be in.
Do you have some references that the 'bug' doesn't ship on devices, or that it no longer ships on simulator images?
What versions of Android SDK/simulator/devices does Trigger.io support? Presumably you don't support running Android 2.3 on the simulator, as your code would trap?
Hey Patrick, we support from v2.0 upwards, although not as heavily tested on 2.0 and 2.1. Our tooling actually sets users up with an AVD, and our docs (http://docs.trigger.io/en/v1.2/android/getting-started.html) do say that 2.3 is not supported on the emulator.
If we do get requests from our users to change that approach, we'd obviously consider it, but at the moment, we think the significant performance and code cleanliness benefits outweigh the downside.
I'm not quite sure I understand what you mean (so if this is the wrong answer let us know). But if you mean why do we use a different method on Android compared to iOS: we can communicate directly from Javascript to Java as part of the WebView in Android, which is very fast. The URL interception method is actually the slowest part of iOS but there is no way around it.
Thanks for the answer. Sorry I wasn't clear... I was referring to this part of the article, in which you describe how the HTML / JavaScript communicates with Objective C on the iPhone:
>> We then make a request to a fake URI (forge://…) which we intercept in native code
Have you tried doing the same for Android? Do you have any numbers that compare the performance of this method with the JS -> Java bridge?
Ok, that makes sense, the JS -> Java communication in Android is already very fast as it is something that can be done as part of the WebView. The fake URI request is a workaround on iOS as this feature doesn't exist. I don't have any numbers offhand, but the JS -> Java communication is definitely a very quick part of the bridge.
Last time we were looking at the web/javascript based cross-platform tools there seemed to be lots of issues with memory handling (running out of memory to be specific). Is this still the case or, even, has this ever been a major issue for big applications? Maybe somebody who has used these tools successfully can provide some more information.
Trigger looks to be an interesting technology, unfortunately it also looks like a Gowalla Situation waiting to happen. It would be tough for me to build products for my clients (or a business) on that.
How does this compare to other native bridging platforms like Appcelerator Titanium? I see no mention of it anywhere in the blog posts or on the comparison charts on your site, etc.
We'll do other articles and comparisons in the future - we haven't yet had a chance to benchmark against Appcelerator.
Anecdotally we think a performance comparison of the bridge would be favorable, but actually the main reason people use us over other frameworks is that our development process is designed for web devs.
So with us, you don't need to do local compiles or use a particular IDE, and we have a much faster build / test cycle.
I don't want to be a spoil-sport, but it's not rocket science to make native bridges really fast, you have to cheat, it's fiddly and different for each OS type.
Awesome - we'd love to hear what you think after you have a play. Feel free to email me directly at sahil@trigger.io if you have any questions.
Simplicity is and has always been of huge importance for us. Developers that use our framework tell us it is much easier to get started with than other offerings out there.
Or you could realized language bridges are stupid and just write the Android and iOS code. Seriously, all you do is trade one set of problems for another. Might as well deal with the native platform problems and make an awesome app for that platform.
This is a silly benchmark - there is absolutely no reason you would put 1000 calls at once, sequential or parallel, across this sort of bridge in a real app. You probably shouldn't be calling any JavaScript API in a client-side app 1000 times at once.
The bridge in PhoneGap Android probably is slower than the one in Forge but
1) that's a tradeoff the PhoneGap devs were willing to make for wider compatibility, support for older devices, and isolation from the bizarre Android WebKit bugs that crop up in every release.
2) synthetic benchmarks aside, there's no indication this would affect the usability of the app.
Take the camera example in the article. A PhoneGap call (judging from the graphs) takes about 14ms, a Forge call about 3ms. That's for the entire round trip (JavaScript -> Native -> JavaScript), so divide each in half for each side of the trip.
With PhoneGap: * first half of the trip (7ms) * Android presents Camera activity, user picks a photo, Android returns control to original app (say, 500ms, very conservatively) * second half of the trip (7ms) = 514ms
With Forge: * first half of the trip (1.5ms) * Android presents Camera activity, user picks a photo, Android returns control to original app (500ms) * second half of the trip (1.5ms) = 503ms
This is much closer to a real-world use case - and the calls to native APIs entirely dominate the time spent on the bridge.