Mistakes I Made Building Netflix for the iPhone
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Mistakes I Made Building Netflix for the iPhone

on

  • 10,783 views

Slides for the talk by the same name I gave at SxSW 2011. You can view the demo app at http://iflx.com, and fork the source from https://github.com/kentbrew/iflx.

Slides for the talk by the same name I gave at SxSW 2011. You can view the demo app at http://iflx.com, and fork the source from https://github.com/kentbrew/iflx.

Statistics

Views

Total Views
10,783
Views on SlideShare
9,063
Embed Views
1,720

Actions

Likes
21
Downloads
189
Comments
0

30 Embeds 1,720

http://blog.pinchzoom.com 844
http://kentbrewster.com 482
http://pinchzoom.com 135
http://freshandmobile.com 62
http://lanyrd.com 38
http://pinchzoom-archive.tumblr.com 33
http://ribot.posterous.com 30
http://pinchzoom.tumblr.com 29
http://paper.li 9
http://kent.pinterest.com 8
http://twitter.com 6
http://static.slidesharecdn.com 6
http://postsynaptically3.rssing.com 5
http://www.pinchzoom.com 5
http://feeds.feedburner.com 5
http://www.kentbrewster.com 3
http://delvinialinks.posterous.com 3
https://p.yammer.com 2
http://pz2013.local 2
http://www.ofelio.com 2
http://www.techgig.com 2
http://newsblur.com 1
http://www.hanrss.com 1
http://boutofcontext.com 1
http://www.slideshare.net 1
http://webcache.googleusercontent.com 1
http://pinchzoom.local 1
https://twitter.com 1
http://pz.local 1
http://pinterest.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

Mistakes I Made Building Netflix for the iPhone Presentation Transcript

  • 1. Mistakes I MadeBuilding Netflix for the iPhone Kent Brewster @kentbrew http://kentbrewster.com
  • 2. In This TalkAbout MeAbout Life at NetflixMistakes I Made and Lessons ILearnedView Source, Launch Movies,and Roll Your Own UI
  • 3. About Me
  • 4. About MeSeven-time Hugo and one-timeNebula loser.
  • 5. About MeSeven-time Hugo and one-timeNebula loser.Atari, 1977.
  • 6. About MeSeven-time Hugo and one-timeNebula loser.Atari, 1977.Invented the Learn-To-Type-Or-Be-Blown-To-Bits Video GamingGenre, 1982.
  • 7. My Qualifications
  • 8. My QualificationsNo Degree or Training inAnything Remotely Relevant
  • 9. My QualificationsNo Degree or Training inAnything Remotely RelevantIn the Right Place at the RightTime, with the Right Amount ofCuriosity and OCD
  • 10. My QualificationsNo Degree or Training inAnything Remotely RelevantIn the Right Place at the RightTime, with the Right Amount ofCuriosity and OCDLiving Proof that Just AboutAnybody Can Do This
  • 11. Even More About Me WebMD, 1984-2003. (Yeah, seriously, nineteen years.) Yahoo, 2004-2009. Netflix, 2009-2010. These days? Vurve.
  • 12. Um ... "Vurve?"
  • 13. Um ... "Vurve?"Vurve makes the process ofadvertising online suck a wholelot less for small businesses.
  • 14. Um ... "Vurve?"Vurve makes the process ofadvertising online suck a wholelot less for small businesses.Currently playing with: BigData, Hadoop/MapReduce, Hive/Pig, Ruby, Python, HTML5, EC2,Node.js, Redis, Mongo.
  • 15. Um ... "Vurve?"Vurve makes the process ofadvertising online suck a wholelot less for small businesses.Currently playing with: BigData, Hadoop/MapReduce, Hive/Pig, Ruby, Python, HTML5, EC2,Node.js, Redis, Mongo.http://vurve.com/jobs
  • 16. Vurve, if IE < 8
  • 17. Life at Netflix
  • 18. Life at NetflixThey pay you what youre worth.
  • 19. Life at NetflixThey pay you what youre worth.They dont track your vacation.
  • 20. Life at NetflixThey pay you what youre worth.They dont track your vacation.You can bring your dog to work.
  • 21. Life at NetflixThey pay you what youre worth.They dont track your vacation.You can bring your dog to work.When you tell your friendswhere you work, they will all say"Netflix! I love Netflix!"
  • 22. Things I Worked On
  • 23. Things I Worked OnFacebook Connect (v1)
  • 24. Things I Worked OnFacebook Connect (v1)OAuth Walk-Through
  • 25. Things I Worked OnFacebook Connect (v1)OAuth Walk-ThroughNetflix Widgets
  • 26. Things I Worked OnFacebook Connect (v1)OAuth Walk-ThroughNetflix WidgetsFirst API-Based Prototype
  • 27. Things I Worked OnFacebook Connect (v1)OAuth Walk-ThroughNetflix WidgetsFirst API-Based PrototypeTrickplay in HTML
  • 28. Things I Worked OnFacebook Connect (v1)OAuth Walk-ThroughNetflix WidgetsFirst API-Based PrototypeTrickplay in HTMLNetflix for iPhone
  • 29. iPhone Chronology
  • 30. iPhone ChronologyApril 1st: iPad ships with Netflix
  • 31. iPhone ChronologyApril 1st: iPad ships with NetflixApril 4th: invited to lead iPhone
  • 32. iPhone ChronologyApril 1st: iPad ships with NetflixApril 4th: invited to lead iPhoneApril 9th: working prototype
  • 33. iPhone ChronologyApril 1st: iPad ships with NetflixApril 4th: invited to lead iPhoneApril 9th: working prototypeApril 23rd: first design mocks
  • 34. iPhone ChronologyApril 1st: iPad ships with NetflixApril 4th: invited to lead iPhoneApril 9th: working prototypeApril 23rd: first design mocksAugust 26th: champagne in theWar Room!
  • 35. Surprise the First April 19th: iPhone 4 on Gizmodo.
  • 36. Surprise the Second June 7th: Reed shows the prototype at Apples Worldwide Developer Conference, commits to "summer" launch.
  • 37. First Three Mistakes
  • 38. First Three Mistakes I took on a ridiculous deadline.
  • 39. First Three Mistakes I took on a ridiculous deadline. I let my manager (who wrote zero lines of code) make key architectural decisions.
  • 40. First Three Mistakes I took on a ridiculous deadline. I let my manager (who wrote zero lines of code) make key architectural decisions. I shipped the prototype.
  • 41. Why HTML?
  • 42. Why HTML?Netflix does incrementalupdates and heavy A/B testing.
  • 43. Why HTML?Netflix does incrementalupdates and heavy A/B testing.Entire UI can be overhauledwithout requiring a trip to theApp Store.
  • 44. Why HTML?Netflix does incrementalupdates and heavy A/B testing.Entire UI can be overhauledwithout requiring a trip to theApp Store.Bugs fix very quickly; the firstone we had was on launch day,and was handled in 15 minutes.
  • 45. How To Tell HTML from HTML5
  • 46. How To Tell HTML from HTML5Try it out on Internet Explorer.*
  • 47. How To Tell HTML from HTML5Try it out on Internet Explorer.*Did it work?
  • 48. How To Tell HTML from HTML5Try it out on Internet Explorer.*Did it work?No?
  • 49. How To Tell HTML from HTML5Try it out on Internet Explorer.*Did it work?No?Its HTML5.
  • 50. *Except IE9
  • 51. *Except IE9IE9 launched the day after Igave this talk at SxSW.
  • 52. *Except IE9IE9 launched the day after Igave this talk at SxSW.Everything I like to play with(shadows, round corners,gradients, canvas) works like achamp.
  • 53. *Except IE9IE9 launched the day after Igave this talk at SxSW.Everything I like to play with(shadows, round corners,gradients, canvas) works like achamp.Now if we just had proper DOM-compatible JavaScript, lifewould be complete.
  • 54. UI MistakeI tried to use native formcontrols.
  • 55. Ratings Selector I liked this, but the designer hated the checkmark, and really wanted red and gold stars. Failed on Android.
  • 56. Search Box
  • 57. Search Boxinput type=search didnt work.
  • 58. Search Boxinput type=search didnt work.Had to hand-whittle the borders,the little magnifying glass, andthe progress indicator.
  • 59. Search Boxinput type=search didnt work.Had to hand-whittle the borders,the little magnifying glass, andthe progress indicator.Goofy timing issues on focus()and blur().
  • 60. Search Boxinput type=search didnt work.Had to hand-whittle the borders,the little magnifying glass, andthe progress indicator.Goofy timing issues on focus()and blur().Blew up on Android.
  • 61. The Damn Keyboard
  • 62. The Damn KeyboardCould not be raised or loweredprogramatically.
  • 63. The Damn KeyboardCould not be raised or loweredprogramatically.(Youd think focus() and blur()would do it, but youd be wrong.)
  • 64. The Damn KeyboardCould not be raised or loweredprogramatically.(Youd think focus() and blur()would do it, but youd be wrong.)Shoved the UI up and failed toshove it all the way back down.
  • 65. The Damn KeyboardCould not be raised or loweredprogramatically.(Youd think focus() and blur()would do it, but youd be wrong.)Shoved the UI up and failed toshove it all the way back down.Blew steaming chunks onAndroid.
  • 66. Really Enormous MistakeI attempted to replicate nativescrolling using HTML, CSS, andJavaScript.
  • 67. Scrolling
  • 68. ScrollingHad to provide nativeperformance, with a fixedheader and footer.
  • 69. ScrollingHad to provide nativeperformance, with a fixedheader and footer.Had to perform awesomely on a2G iPod Touch.
  • 70. ScrollingHad to provide nativeperformance, with a fixedheader and footer.Had to perform awesomely on a2G iPod Touch.Was tested by launching the app,immediately scrolling like crazybefore the data had loaded, anddeclaring that it sucked.
  • 71. I Stole From:
  • 72. I Stole From:PastryKit library (not public atthe time, hard to understand)
  • 73. I Stole From:PastryKit library (not public atthe time, hard to understand)TouchScroll (basic framework)
  • 74. I Stole From:PastryKit library (not public atthe time, hard to understand)TouchScroll (basic framework)iScroll (excellent physics)
  • 75. I Stole From:PastryKit library (not public atthe time, hard to understand)TouchScroll (basic framework)iScroll (excellent physics)Sencha Touch (did not officiallyexist)
  • 76. How Scrolling Works
  • 77. How Scrolling Works Kill touchmove default actions with preventDefault().
  • 78. How Scrolling Works Kill touchmove default actions with preventDefault(). Listen and respond with CSS transitions, not JS positioning.
  • 79. How Scrolling Works Kill touchmove default actions with preventDefault(). Listen and respond with CSS transitions, not JS positioning. Independent three-window scrolling and sliding is really hard.
  • 80. Three Windows
  • 81. Three WindowsMain list, gallery list, and detailspage.
  • 82. Three WindowsMain list, gallery list, and detailspage.Try not to re-render lists, butalso try not to rely on the DOM.
  • 83. Three WindowsMain list, gallery list, and detailspage.Try not to re-render lists, butalso try not to rely on the DOM.iOS is optimized for translate3d.(Android? Not so much....)
  • 84. Home Position #viewport { position: absolute; top: 0; left: 0; height: 480px; width: 320px; overflow: hidden; } #body, #main, #gallery, and #details all positioned absolutely
  • 85. Drag to Scroll #main { -webkit-transition: -webkit-transform 2000ms ease-in; -webkit-transform: translate3d(0, -300px, 0); } Transform just the main list.
  • 86. Tap to Slide #page { -webkit-transition: -webkit-transform 500ms ease-in; -webkit-transform: translate3d(320px, 0, 0); } Transform the entire page to the right.
  • 87. Scroll Gallery Up #gallery { -webkit-transition: -webkit-transform 2000ms ease-in; -webkit-transform: translate3d(0, -200px, 0); } Scroll the gallery up. Leave main list alone!
  • 88. Tap to Open Details #page { -webkit-transition: -webkit-transform 500ms ease-in; -webkit-transform: translate3d(320px, 0, 0); } Slide the entire page to the right again.
  • 89. Going Back is Hard Sometimes we need to reset the list were backing into, sometimes we dont. Sometimes the entire gallery has changed, from instant queue to a category gallery.
  • 90. position:fixed?Yes, position:fixed works onAndroid. http://bit.ly/aj8wylThis is good, because scrollingwith JavaScript is kinda busted.This is bad, because its buggy.http://bit.ly/cCTX6r
  • 91. webOS position:fixed?Yes, but I have a feeling thatthis wont roll out to everyone.
  • 92. Webkit Scrolling?Position header and footerabsolutely.Listen for touchstart.Hide the header and footer,scroll the window, and replacewhen done.
  • 93. Headers in the AppHeader and footer should bepart of the apps framework.Body should be a Web view;native scrolling will take care ofeverything.Throw title info over the wall tonative app using hackyJavaScript bridge.
  • 94. Why We Quit Working On The Scrolling
  • 95. Why We Quit Working On The Scrolling The first 90% of the job takes the first 90% of the time.
  • 96. Why We Quit Working On The Scrolling The first 90% of the job takes the first 90% of the time. The last 10% of the work takes the remaining 90% of the time.
  • 97. Why We Quit Working On The Scrolling The first 90% of the job takes the first 90% of the time. The last 10% of the work takes the remaining 90% of the time. Manager got an iPhone 4.
  • 98. Big MistakeI tried to make the samecodebase work for Android. (Seealso "I let my manager make keyarchitectural decisions.")
  • 99. Um ... Android?
  • 100. Um ... Android?When you view source you willdiscover multiple references to"android," so its an open secret.
  • 101. Um ... Android?When you view source you willdiscover multiple references to"android," so its an open secret.I have absolutely no idea whenor if Netflix will launch forAndroid.
  • 102. Um ... Android?When you view source you willdiscover multiple references to"android," so its an open secret.I have absolutely no idea whenor if Netflix will launch forAndroid.I will say this: it was very, veryhard to work on.
  • 103. More Mistakes
  • 104. More MistakesI did not push back hard enoughon the design.
  • 105. More MistakesI did not push back hard enoughon the design.I ignored the applicationframework.
  • 106. More MistakesI did not push back hard enoughon the design.I ignored the applicationframework.I failed to use some reallyimportant tools.
  • 107. HTML5
  • 108. HTML5data:URIs for CSS backgrounds
  • 109. HTML5data:URIs for CSS backgroundslocal storage to cache API calls(main list is regenerated daily)
  • 110. HTML5data:URIs for CSS backgroundslocal storage to cache API calls(main list is regenerated daily)Multipart XHR for images thatnever change but may be servedup in different order (box art).
  • 111. HTML5data:URIs for CSS backgroundslocal storage to cache API calls(main list is regenerated daily)Multipart XHR for images thatnever change but may be servedup in different order (box art).cache-manifest to store code &framework offline
  • 112. Careful, Now:
  • 113. Careful, Now:border-image was very slow torender at different widths.
  • 114. Careful, Now:border-image was very slow torender at different widths.Scrolling using CSS transitionshit an absolute height limit oniPod Touch and iPhone 3
  • 115. Careful, Now:border-image was very slow torender at different widths.Scrolling using CSS transitionshit an absolute height limit oniPod Touch and iPhone 3box-shadow slowed things downtremendously
  • 116. Big but Unavoidable MistakeI used an inadequate API.
  • 117. 23+ API calls build the front page.Get the master list.For each item on the master list,get a child list.For each item in the child list,make two calls, one for the titleand one for the users rating.
  • 118. Episodes andbookmarks are hard. For each episode in a series, create a stand-alone call for that episode and append it to a very long bulk query. This query is too big to GET. Use XHR. Oh, wait. Use CORS, because we are in the cloud.
  • 119. All calls must besigned with oAuth.Cannot be done on the fly by theapplication; too slow.Using JavaScript exposes yourkey and secret.Hack to fix: throw key/secretover the wall with the app onlaunch.
  • 120. Good news: they may be fixing the API. http://techblog.netflix.com
  • 121. NQL?Netflix needs to build somethinglike Yahoo! Query Language.http://developer.yahoo.com/yqlGroup related endpointstogether. Developers need to beable to get everything Netflixknows about a customers frontpage, or a season of South Park,with a single call to the API.
  • 122. Really happening?Yep, looks like like it might be.http://techblog.netflix.com
  • 123. View Source?
  • 124. View Source?Netflix has taken great care toobfuscate this application.
  • 125. View Source?Netflix has taken great care toobfuscate this application.Id like to help you view source,but I cant.
  • 126. View Source?Netflix has taken great care toobfuscate this application.Id like to help you view source,but I cant.I strongly recommend you doNOT do any of the following....
  • 127. Do not searchhttp://developer.netflix.com for "ipad open app."
  • 128. Should you discover the nflx://protocol, dont mess around with it.
  • 129. Dont get all stubborn and trynflx:// calls on an iPhone or iPad with the Netflix app installed.
  • 130. If you try to hit an invalid nflx:// URL, the app will drop you into Safari, pointed at the UI loader.
  • 131. Do not copy thisURL into desktop Safari.
  • 132. Dont inspect or follow any links to JavaScript.
  • 133. Do not copy behavior.js to your clipboard....
  • 134. And whatever you do, do NOT runit through http://jsbeautifier.org.
  • 135. If You Accidentally Happen toGlimpse Some Source, Please Avert Your Eyes, and Assume the Following:
  • 136. If You Accidentally Happen toGlimpse Some Source, Please Avert Your Eyes, and Assume the Following: Anything that looks broken or brain-damaged is my fault.
  • 137. If You Accidentally Happen toGlimpse Some Source, Please Avert Your Eyes, and Assume the Following: Anything that looks broken or brain-damaged is my fault. Anything that works or is awesome was put in after I left, or in spite of my valiant efforts to fuck it up.
  • 138. (awesome demo here)
  • 139. Try It Yourself!Plays only on devices with the Netflix app installed. Windows phone? Unknown....
  • 140. Try It Yourself!Please be gentle:http://iflx.usPlays only on devices with the Netflix app installed. Windows phone? Unknown....
  • 141. Try It Yourself!Please be gentle:http://iflx.usRemember, its a two-hour hack.Plays only on devices with the Netflix app installed. Windows phone? Unknown....
  • 142. Try It Yourself!Please be gentle:http://iflx.usRemember, its a two-hour hack.Fork Me On GitHub:https://github.com/kentbrew/iflxPlays only on devices with the Netflix app installed. Windows phone? Unknown....
  • 143. Search Structure<input id="query" /><ul id="results"></ul>
  • 144. Search LoopcheckSearch : function() { var v = $.s.query.value; if (v) { if (v !== $.g.lastValue) { $.f.runSearch(v); } $.g.lastValue = v; }}$.w.setInterval( function() { $.f.checkSearch(); }, 500);
  • 145. Search QueryrunSearch: function(q) { var n = $.f.fn.length; var id = $.a.k + .f.fn[ + n + ]; var url = $.a.search + ?expand=@title; url += &max_results=20&output=json&v=2.0; url += &term= + encodeURIComponent(q); url += &callback= + encodeURIComponent(id); $.f.fn[n] = function(r) { var id = $.a.k + .f.fn[ + n + ]; $.f.destroy($.d.getElementById(id)); $.f.renderSearch(r); }; $.d.b.appendChild( $.f.create({SCRIPT:{ src:$.f.oAuthRequest(url), type:text/javascript, }}) );}
  • 146. OAuth?http://kentbrewster.com/netflix-api-explorerhttp://kentbrewster.com/true-oauth-confessions
  • 147. Launching a MoviePlays only on devices with the Netflix app installed. Windows phone? Unknown....
  • 148. Launching a Movienflx://www.netflix.com/WiPlayerPlays only on devices with the Netflix app installed. Windows phone? Unknown....
  • 149. Launching a Movienflx://www.netflix.com/WiPlayer?movieid=[box art movie ID]Plays only on devices with the Netflix app installed. Windows phone? Unknown....
  • 150. Launching a Movienflx://www.netflix.com/WiPlayer?movieid=[box art movie ID]&episodeid=[episode ID]Plays only on devices with the Netflix app installed. Windows phone? Unknown....
  • 151. Launching a Movienflx://www.netflix.com/WiPlayer?movieid=[box art movie ID]&episodeid=[episode ID]&returnUrl=[your page]Plays only on devices with the Netflix app installed. Windows phone? Unknown....
  • 152. Launch Behaviorvar playUrl = nflx://www.netflix.com/WiPlayer?;playUrl += movieid= + id;playUrl += &returnUrl=http://yourpage.com;var playButton = $.f.create({A:{ innerHTML:Play, href: playUrl}});playButton.onclick = function() { $.w.location = this.href;}
  • 153. ASCII-art Starbarsli { .fullStars, .emptyStars text-shadow: 0 1px 1px #fff; {} position: absolute; width: 100px;li p.starContainer { top: 0; display: inline-block; left: 0; position: relative; } width: 100px; height: 32px; .fullStars { line-height: 32px; color: #a00; letter-spacing: 4.2px; overflow: hidden; text-align: center; } margin: 0; padding: 0;}
  • 154. Starbar JSvar starContainer = $.f.create({P:{ className:starContainer}});var fullStars = $.f.create({SPAN:{ className:fullStars, innerHTML:&#9733;&#9733;&#9733;&#9733;&#9733;}});fullStars.style.width = (t.average_rating * 20) + %;starContainer.appendChild(fullStars);var emptyStars = $.f.create({SPAN:{ className:emptyStars, innerHTML:&#9734;&#9734;&#9734;&#9734;&#9734;}});starContainer.appendChild(emptyStars);li.appendChild(starContainer);
  • 155. Starbar, Rendered<p class="starContainer"> <span class="fullStars" style="width:70%"> &#9733;&#9733;&#9733;&#9733;&#9733; </span> <span class="emptyStars"> &#9734;&#9734;&#9734;&#9734;&#9734; </span></p>
  • 156. Questions?
  • 157. Randall Munroe alwayshas the last laugh.