Titanium Mobile: flexibility vs. performance

22,097 views
21,948 views

Published on

Published in: Technology
0 Comments
29 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
22,097
On SlideShare
0
From Embeds
0
Number of Embeds
11,067
Actions
Shares
0
Downloads
159
Comments
0
Likes
29
Embeds 0
No embeds

No notes for slide

Titanium Mobile: flexibility vs. performance

  1. 1. Appcelerator Titanium Mobile FLEXIBILITY VS PERFORMANCEOlivier Morandi
  2. 2. $ whoami Olivier Morandi Software engineer http://titaniumninja.com olivier.morandi@gmail.com @olivier_morandi https://github.com/omorandi2 Appcelerator Titanium - Flexibility vs. Performance
  3. 3. Titanium Mobile • Rapid development & prototyping tool • Single high level language: JS • Multiple deployment platforms (iOS, Android, ...) • We can leverage an ever growing set of JS libraries and modules (web, node.js, etc.) • Possibility to extend the framework with native modules3 Appcelerator Titanium - Flexibility vs. Performance
  4. 4. Titanium Apps are NATIVE Can we also expect a native User Experience?4 Appcelerator Titanium - Flexibility vs. Performance
  5. 5. Titanium 2.0 • Improved stability • Improved platform parity • Improved performance • Appcelerator Cloud Services5 Appcelerator Titanium - Flexibility vs. Performance
  6. 6. Some Mobile Dev Tools Mobile Web Flexibility → ∞ + High Level Language + High Level APIs + Dynamic updates + Cross Platform Titanium PhoneGap Mobile RubyMotion 0 ← Performance 1 + Execution Speed + Native UX + Native capabilities6 Appcelerator Titanium - Flexibility vs. Performance
  7. 7. Some Mobile Dev Tools Mobile Web Flexibility → ∞ + High Level Language + High Level APIs + Dynamic updates + Cross Platform Titanium ? PhoneGap Mobile ? RubyMotion 0 ← Performance 1 + Execution Speed + Native UX + Native capabilities6 Appcelerator Titanium - Flexibility vs. Performance
  8. 8. An example: Ti.UI.TableView7 Appcelerator Titanium - Flexibility vs. Performance
  9. 9. Common Problems • Slow transitions – the table view takes ages to show up • Choppy scrolling – Everybody wants super-slick animations, isn’t it?8 Appcelerator Titanium - Flexibility vs. Performance
  10. 10. Towards Increased Performance • Understand the tools, then: Measure Optimize Learn9 Appcelerator Titanium - Flexibility vs. Performance
  11. 11. Runtime Environment JS APP JS APP V8 Parser Parser JavaScriptCore Bytecode Titanium Native Titanium gen Modules Code Gen Modules OPT Native Interpreter Code IOS SDK ANDROID SDK10 Appcelerator Titanium - Flexibility vs. Performance
  12. 12. Runtime Environment JS APP JS APP V8 Parser Parser JavaScriptCore Bytecode Titanium Native Titanium gen Modules Code Gen Modules OPT JIT NOInterpreter Native Code IOS SDK ANDROID SDK10 Appcelerator Titanium - Flexibility vs. Performance
  13. 13. Runtime Environment JS APP JS APP V8 Parser Parser JavaScriptCore Bytecode Titanium Native Titanium gen Modules Code Gen Modules OPT JIT NOInterpreter Native Code IOS SDK ANDROID SDK10 Appcelerator Titanium - Flexibility vs. Performance
  14. 14. Runtime Environment JS APP JS APP V8 Parser Parser JavaScriptCore Bytecode Titanium Native Titanium gen Modules Code Gen Modules OPT JIT NOInterpreter Native Code IOS SDK ANDROID SDK10 Appcelerator Titanium - Flexibility vs. Performance
  15. 15. Measure: which runs faster? function processRow(row) { return {title: row.info}; } 1 2 var rows = []; var rows = []; for (var r = 0; r < array.length; r++) { for (var r = 0; r < array.length; r++) { rows.push({title: array[r].info}); rows.push(processRow(array[r])); } } 3 4 var len = array.length; var len = array.length; var rows = []; var rows = []; for (var r = 0; r < len; r++) { for (var r = 0; r < len; r++) { rows.push({title: array[r].info}); rows.push(processRow(array[r])); } } 5 var rows = array.map(processRow);11 Appcelerator Titanium - Flexibility vs. Performance
  16. 16. Tests on iPhone 4 1000 100 ms 10 1 100 1000 10000 Number of Rows 1) for + inline 2) for + funct 3) for + inline + cache len 4) for + funct + cache len 5) map12 Appcelerator Titanium - Flexibility vs. Performance
  17. 17. Which runs faster? function processRow2(row) { return Ti.UI.createTableViewRow({title: row.info}); } 1 2 var rows = []; var rows = []; for (var r = 0; r < array.length; r++) { for (var r = 0; r < array.length; r++) { rows.push(Ti.UI.createTableViewRow( rows.push(processRow2(array[r])); {title: array[r].info})); } } 3 4 var len = array.length; var len = array.length; var rows = []; var rows = []; for (var r = 0; r < len; r++) { for (var r = 0; r < len; r++) { rows.push(Ti.UI.createTableViewRow( rows.push(processRow2(array[r])); {title: array[r].info})); } } 5 var rows = array.map(processRow2);13 Appcelerator Titanium - Flexibility vs. Performance
  18. 18. Tests on iPhone 4 10000 1000 ms 100 10 1 10 100 1000 Number of rows 1) for + inline 2) for + funct 3) for + inline + cache len 4) for + funct + cache len 5) map14 Appcelerator Titanium - Flexibility vs. Performance
  19. 19. Tests on iPhone 4 10000 ES E TH 1000 T S !! U ! R TS T L ms ’T U 100 N ES O R D 10 1 10 100 1000 Number of rows 1) for + inline 2) for + funct 3) for + inline + cache len 4) for + funct + cache len 5) map14 Appcelerator Titanium - Flexibility vs. Performance
  20. 20. WHY? • They’re not generalizable • Your code won’t look like the one presented here • Do your own measurements15 Appcelerator Titanium - Flexibility vs. Performance
  21. 21. Is table creation slow? • Obtaining some rough figures: var start = new Date().getTime(); //your code goes here var end = new Date().getTime(); Ti.API.info(elapsed ms: + (end - start));16 Appcelerator Titanium - Flexibility vs. Performance
  22. 22. Are there more accurate tools? • mmm.... AFAIK NO!17 Appcelerator Titanium - Flexibility vs. Performance
  23. 23. Android DDMS + Traceview18 Appcelerator Titanium - Flexibility vs. Performance
  24. 24. Android DDMS + Traceview WHERE’S MY JS???18 Appcelerator Titanium - Flexibility vs. Performance
  25. 25. Xcode Instruments: profiler tool19 Appcelerator Titanium - Flexibility vs. Performance
  26. 26. Xcode Instruments: profiler tool JS code hidden here19 Appcelerator Titanium - Flexibility vs. Performance
  27. 27. Titanium Profiler... still to come20 Appcelerator Titanium - Flexibility vs. Performance
  28. 28. Titanium Profiler (iOS only) • Custom version of the Ti JavaScriptCore library • Work in progress • Some info here http://titaniumninja.com/profiling-ti-mobile-apps-is-it-possible/ • Will be possibly integrated in Ti Mobile • Stay tuned on http://titaniumninja.com/21 Appcelerator Titanium - Flexibility vs. Performance
  29. 29. Is table creation REALLY slow? • Try optimizing the row creation loop body • Implement Lazy loading – Initialize the table with fewer rows and show it immediately – Meantime continue creating the remaining rows and update the table with the complete row set22 Appcelerator Titanium - Flexibility vs. Performance
  30. 30. Wanna smooth scrolling?23 Appcelerator Titanium - Flexibility vs. Performance
  31. 31. Instruments: Core Animation24 Appcelerator Titanium - Flexibility vs. Performance
  32. 32. Tables with complex rows are slow ~35-40 FPS Expected: ~60 FPS25 Appcelerator Titanium - Flexibility vs. Performance
  33. 33. 1. Blended layers These labels are transparent, even if we set the background color, or a background image26 Appcelerator Titanium - Flexibility vs. Performance
  34. 34. What can we do? -(UILabel*)label { ! if (label==nil) ! { label = [[UILabel alloc] initWithFrame:CGRectZero]; label.backgroundColor = [UIColor whiteColor]; label.numberOfLines = 0; [self addSubview:label]; label.opaque = YES; self.opaque = YES; self.backgroundColor = [UIColor whiteColor]; ! } ! return label; } TiUILabel.m:104 Discussion (Cfr. UIView Reference) “The opaque property provides a hint to the drawing system as to how it should treat the view. If set to YES, the drawing system treats the view as fully opaque, which allows the drawing system to optimize some drawing operations and improve performance”27 Appcelerator Titanium - Flexibility vs. Performance
  35. 35. What can we do? !! -(UILabel*)label { ! ! if (label==nil) IX ! { F label = [[UILabel alloc] initWithFrame:CGRectZero]; A label.backgroundColor = [UIColor whiteColor]; label.numberOfLines = 0; T [self addSubview:label]; O label.opaque = YES; N self.opaque = YES; self.backgroundColor = [UIColor whiteColor]; ! } ! return label; } TiUILabel.m:104 Discussion (Cfr. UIView Reference) “The opaque property provides a hint to the drawing system as to how it should treat the view. If set to YES, the drawing system treats the view as fully opaque, which allows the drawing system to optimize some drawing operations and improve performance”27 Appcelerator Titanium - Flexibility vs. Performance
  36. 36. Result ~45-50 FPS28 Appcelerator Titanium - Flexibility vs. Performance
  37. 37. 2. Offscreen rendered layers29 Appcelerator Titanium - Flexibility vs. Performance
  38. 38. Solution • Don’t use rounded corners (borderRadius) • Use an image mask instead var img = Ti.UI.createMaskedImage({ mask : mask.png,// alpha mask image : myPicture,//image to mask mode : Ti.UI.iOS.BLEND_MODE_SCREEN });30 Appcelerator Titanium - Flexibility vs. Performance
  39. 39. What about FPSs? ~55-60 FPS (Just using image masks)31 Appcelerator Titanium - Flexibility vs. Performance
  40. 40. Not satisfied? Going fully native • Let’s create a custom optimized UITableView • We’ll expose it through a native module32 Appcelerator Titanium - Flexibility vs. Performance
  41. 41. API for the custom view • API • createMessagesView(properties); • setMessages([]messages); • insert(message); • addEventListener(‘click’, callback); • Config { rowBackgroundColor: #efefef, nameColorIfMe: #191919, nameColorIfOther: #8f032c, … }33 Appcelerator Titanium - Flexibility vs. Performance
  42. 42. API for the custom view • API IT Y • setMessages([]messages);IB IL • createMessagesView(properties); • insert(message); EX FL callback); ED • addEventListener(‘click’, S • Config R EA EC { D rowBackgroundColor: #efefef, nameColorIfMe: #191919, nameColorIfOther: #8f032c, … }33 Appcelerator Titanium - Flexibility vs. Performance
  43. 43. Message model { isMe: true, name: "Vincent", picture: "vin.png", body: "Its not. Its the same ballpark.", date: 12394838299 //unix timestamp },34 Appcelerator Titanium - Flexibility vs. Performance
  44. 44. A single row name date picture Click body35 Appcelerator Titanium - Flexibility vs. Performance
  45. 45. Traditional UITableViewCell - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {! ! UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MessageCell"]; ! if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MessageCell"] autorelease]; UILabel *nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(75.0, 25.0, 120.0, 18.0)]; nameLabel.font = [UIFont boldSystemFontOfSize:16.0]; nameLabel.textAlignment = UITextAlignmentLeft; ! ! nameLabel.backgroundColor = rowBackgroundColor; ! ! [cell.contentView addSubview:nameLabel]; } else { //... } Message *msg = [messages objectAtIndex:(indexPath.row)]; BOOL isMe = [TiUtils boolValue:[dict objectForKey:@"isMe"]]; nameLabel.textColor = isMe ? nameColorIfMe : nameColorIfOther; //...36 Appcelerator Titanium - Flexibility vs. Performance
  46. 46. Not fast enough? Use FastCells - (void) drawContentView:(CGRect)rect { Low level drawing primitives if (message == nil) return; CGContextRef context = UIGraphicsGetCurrentContext(); CGContextClearRect(context, rect); CGFloat max_width = self.contentView.frame.size.width; if (message.isMe) [nameColorIfMe set]; else [nameColorIfOther set]; [message.name drawInRect:CGRectMake(userInfoLeft, userInfoTop, rectWidth(userInfoLeft, userInfoRight, max_width), userInfoHeight) withFont:bigBoldFont lineBreakMode:UILineBreakModeTailTruncation]; //... }37 Appcelerator Titanium - Flexibility vs. Performance
  47. 47. Concluding remarks on Titanium • Is it worth it? • Does it really speeds up development? • Is developing with Titanium “better” or “worse” than making parallel per-platform developments?38 Appcelerator Titanium - Flexibility vs. Performance
  48. 48. Where’s the value? • Quick prototyping iterations • Single complex business-logic core • Cross platform deployment • Maintainability of the project in the long term39 Appcelerator Titanium - Flexibility vs. Performance
  49. 49. Some interesting reads • JavaScriptCore, the WebKit JS implementation - http://wingolog.org/archives/ 2011/10/28/javascriptcore-the-webkit-js-implementation • v8: a tale of two compilers - http://wingolog.org/archives/2011/07/05/v8-a-tale- of-two-compilers • JSC v/s V8 performance on ARM - http://xc0ffee.wordpress.com/2011/09/07/ webkit-gtk-jsc-vs-v8-performance-on-arm/ • The Future of JavaScript Engines: Replace Them With JavaScript Compilers - http://shorestreet.com/node/43 • Optimisation: dont waste your time - http://www.scirra.com/blog/83/ optimisation-dont-waste-your-time • Guidelines for JavaScript Programs: Are They Still Necessary? - http://www.inf.u- szeged.hu/~akiss/pub/pdf/herczeg_guidelines.pdf40 Appcelerator Titanium - Flexibility vs. Performance
  50. 50. Thank YOU! Any question?41 Appcelerator Titanium - Flexibility vs. Performance

×