SlideShare a Scribd company logo
1 of 157
Download to read offline
Mistakes I Made
Building Netflix
 for the iPhone
      Kent Brewster
        @kentbrew
 http://kentbrewster.com
In This Talk
About Me
About Life at Netflix
Mistakes I Made and Lessons I
Learned
View Source, Launch Movies,
and Roll Your Own UI
About Me
About Me
Seven-time Hugo and one-time
Nebula loser.
About Me
Seven-time Hugo and one-time
Nebula loser.
Atari, 1977.
About Me
Seven-time Hugo and one-time
Nebula loser.
Atari, 1977.
Invented the Learn-To-Type-Or-
Be-Blown-To-Bits Video Gaming
Genre, 1982.
My Qualifications
My Qualifications
No Degree or Training in
Anything Remotely Relevant
My Qualifications
No Degree or Training in
Anything Remotely Relevant
In the Right Place at the Right
Time, with the Right Amount of
Curiosity and OCD
My Qualifications
No Degree or Training in
Anything Remotely Relevant
In the Right Place at the Right
Time, with the Right Amount of
Curiosity and OCD
Living Proof that Just About
Anybody Can Do This
Even More About Me
 WebMD, 1984-2003. (Yeah,
 seriously, nineteen years.)
 Yahoo, 2004-2009.
 Netflix, 2009-2010.
 These days? Vurve.
Um ... "Vurve?"
Um ... "Vurve?"
Vurve makes the process of
advertising online suck a whole
lot less for small businesses.
Um ... "Vurve?"
Vurve makes the process of
advertising online suck a whole
lot less for small businesses.
Currently playing with: Big
Data, Hadoop/MapReduce, Hive/
Pig, Ruby, Python, HTML5, EC2,
Node.js, Redis, Mongo.
Um ... "Vurve?"
Vurve makes the process of
advertising online suck a whole
lot less for small businesses.
Currently playing with: Big
Data, Hadoop/MapReduce, Hive/
Pig, Ruby, Python, HTML5, EC2,
Node.js, Redis, Mongo.
http://vurve.com/jobs
Vurve, if IE < 8
Life at Netflix
Life at Netflix
They pay you what you're worth.
Life at Netflix
They pay you what you're worth.
They don't track your vacation.
Life at Netflix
They pay you what you're worth.
They don't track your vacation.
You can bring your dog to work.
Life at Netflix
They pay you what you're worth.
They don't track your vacation.
You can bring your dog to work.
When you tell your friends
where you work, they will all say
"Netflix! I love Netflix!"
Things I Worked On
Things I Worked On
Facebook Connect (v1)
Things I Worked On
Facebook Connect (v1)
OAuth Walk-Through
Things I Worked On
Facebook Connect (v1)
OAuth Walk-Through
Netflix Widgets
Things I Worked On
Facebook Connect (v1)
OAuth Walk-Through
Netflix Widgets
First API-Based Prototype
Things I Worked On
Facebook Connect (v1)
OAuth Walk-Through
Netflix Widgets
First API-Based Prototype
Trickplay in HTML
Things I Worked On
Facebook Connect (v1)
OAuth Walk-Through
Netflix Widgets
First API-Based Prototype
Trickplay in HTML
Netflix for iPhone
iPhone Chronology
iPhone Chronology
April 1st: iPad ships with Netflix
iPhone Chronology
April 1st: iPad ships with Netflix
April 4th: invited to lead iPhone
iPhone Chronology
April 1st: iPad ships with Netflix
April 4th: invited to lead iPhone
April 9th: working prototype
iPhone Chronology
April 1st: iPad ships with Netflix
April 4th: invited to lead iPhone
April 9th: working prototype
April 23rd: first design mocks
iPhone Chronology
April 1st: iPad ships with Netflix
April 4th: invited to lead iPhone
April 9th: working prototype
April 23rd: first design mocks
August 26th: champagne in the
War Room!
Surprise the First


       April 19th: iPhone 4
       on Gizmodo.
Surprise the Second

       June 7th: Reed shows
       the prototype at
       Apple's Worldwide
       Developer Conference,
       commits to "summer"
       launch.
First Three Mistakes
First Three Mistakes
 I took on a ridiculous deadline.
First Three Mistakes
 I took on a ridiculous deadline.
 I let my manager (who wrote
 zero lines of code) make key
 architectural decisions.
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.
Why HTML?
Why HTML?
Netflix does incremental
updates and heavy A/B testing.
Why HTML?
Netflix does incremental
updates and heavy A/B testing.
Entire UI can be overhauled
without requiring a trip to the
App Store.
Why HTML?
Netflix does incremental
updates and heavy A/B testing.
Entire UI can be overhauled
without requiring a trip to the
App Store.
Bugs fix very quickly; the first
one we had was on launch day,
and was handled in 15 minutes.
How To Tell HTML
  from HTML5
How To Tell HTML
  from HTML5
Try it out on Internet Explorer.*
How To Tell HTML
  from HTML5
Try it out on Internet Explorer.*
Did it work?
How To Tell HTML
  from HTML5
Try it out on Internet Explorer.*
Did it work?
No?
How To Tell HTML
  from HTML5
Try it out on Internet Explorer.*
Did it work?
No?
It's HTML5.
*Except IE9
*Except IE9
IE9 launched the day after I
gave this talk at SxSW.
*Except IE9
IE9 launched the day after I
gave this talk at SxSW.
Everything I like to play with
(shadows, round corners,
gradients, canvas) works like a
champ.
*Except IE9
IE9 launched the day after I
gave this talk at SxSW.
Everything I like to play with
(shadows, round corners,
gradients, canvas) works like a
champ.
Now if we just had proper DOM-
compatible JavaScript, life
would be complete.
UI Mistake

I tried to use native form
controls.
Ratings Selector

      I liked this, but the
      designer hated the
      checkmark, and really
      wanted red and gold
      stars.
      Failed on Android.
Search Box
Search Box
input type=search didn't work.
Search Box
input type=search didn't work.
Had to hand-whittle the borders,
the little magnifying glass, and
the progress indicator.
Search Box
input type=search didn't work.
Had to hand-whittle the borders,
the little magnifying glass, and
the progress indicator.
Goofy timing issues on focus()
and blur().
Search Box
input type=search didn't work.
Had to hand-whittle the borders,
the little magnifying glass, and
the progress indicator.
Goofy timing issues on focus()
and blur().
Blew up on Android.
The Damn Keyboard
The Damn Keyboard
Could not be raised or lowered
programatically.
The Damn Keyboard
Could not be raised or lowered
programatically.
(You'd think focus() and blur()
would do it, but you'd be wrong.)
The Damn Keyboard
Could not be raised or lowered
programatically.
(You'd think focus() and blur()
would do it, but you'd be wrong.)
Shoved the UI up and failed to
shove it all the way back down.
The Damn Keyboard
Could not be raised or lowered
programatically.
(You'd think focus() and blur()
would do it, but you'd be wrong.)
Shoved the UI up and failed to
shove it all the way back down.
Blew steaming chunks on
Android.
Really Enormous
     Mistake

I attempted to replicate native
scrolling using HTML, CSS, and
JavaScript.
Scrolling
Scrolling
Had to provide native
performance, with a fixed
header and footer.
Scrolling
Had to provide native
performance, with a fixed
header and footer.
Had to perform awesomely on a
2G iPod Touch.
Scrolling
Had to provide native
performance, with a fixed
header and footer.
Had to perform awesomely on a
2G iPod Touch.
Was tested by launching the app,
immediately scrolling like crazy
before the data had loaded, and
declaring that it sucked.
I Stole From:
I Stole From:
PastryKit library (not public at
the time, hard to understand)
I Stole From:
PastryKit library (not public at
the time, hard to understand)
TouchScroll (basic framework)
I Stole From:
PastryKit library (not public at
the time, hard to understand)
TouchScroll (basic framework)
iScroll (excellent physics)
I Stole From:
PastryKit library (not public at
the time, hard to understand)
TouchScroll (basic framework)
iScroll (excellent physics)
Sencha Touch (did not officially
exist)
How Scrolling Works
How Scrolling Works
 Kill touchmove default actions
 with preventDefault().
How Scrolling Works
 Kill touchmove default actions
 with preventDefault().
 Listen and respond with CSS
 transitions, not JS positioning.
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.
Three Windows
Three Windows
Main list, gallery list, and details
page.
Three Windows
Main list, gallery list, and details
page.
Try not to re-render lists, but
also try not to rely on the DOM.
Three Windows
Main list, gallery list, and details
page.
Try not to re-render lists, but
also try not to rely on the DOM.
iOS is optimized for translate3d.
(Android? Not so much....)
Home Position
      #viewport {
        position: absolute;
        top: 0; left: 0;
        height: 480px;
        width: 320px;
        overflow: hidden;
      }

      #body, #main, #gallery,
      and #details all
      positioned absolutely
Drag to Scroll
      #main {
        -webkit-transition:
        -webkit-transform
        2000ms ease-in;
        -webkit-transform:
        translate3d(0, -300px,
        0);
      }

      Transform just the main
      list.
Tap to Slide
     #page {
       -webkit-transition:
       -webkit-transform
       500ms ease-in;
       -webkit-transform:
       translate3d(320px, 0,
       0);
     }

     Transform the entire
     page to the right.
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!
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.
Going Back is Hard
        Sometimes we need to
        reset the list we're
        backing into, sometimes
        we don't.

        Sometimes the entire
        gallery has changed,
        from instant queue to a
        category gallery.
position:fixed?

Yes, position:fixed works on
Android. http://bit.ly/aj8wyl
This is good, because scrolling
with JavaScript is kinda busted.
This is bad, because it's buggy.
http://bit.ly/cCTX6r
webOS
  position:fixed?




Yes, but I have a feeling that
this won't roll out to everyone.
Webkit Scrolling?
Position header and footer
absolutely.
Listen for touchstart.
Hide the header and footer,
scroll the window, and replace
when done.
Headers in the App
Header and footer should be
part of the app's framework.
Body should be a Web view;
native scrolling will take care of
everything.
Throw title info over the wall to
native app using hacky
JavaScript bridge.
Why We Quit Working
  On The Scrolling
Why We Quit Working
  On The Scrolling
 The first 90% of the job takes the
 first 90% of the time.
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.
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.
Big Mistake

I tried to make the same
codebase work for Android. (See
also "I let my manager make key
architectural decisions.")
Um ... Android?
Um ... Android?
When you view source you will
discover multiple references to
"android," so it's an open secret.
Um ... Android?
When you view source you will
discover multiple references to
"android," so it's an open secret.
I have absolutely no idea when
or if Netflix will launch for
Android.
Um ... Android?
When you view source you will
discover multiple references to
"android," so it's an open secret.
I have absolutely no idea when
or if Netflix will launch for
Android.
I will say this: it was very, very
hard to work on.
More Mistakes
More Mistakes

I did not push back hard enough
on the design.
More Mistakes

I did not push back hard enough
on the design.
I ignored the application
framework.
More Mistakes

I did not push back hard enough
on the design.
I ignored the application
framework.
I failed to use some really
important tools.
HTML5
HTML5
data:URIs for CSS backgrounds
HTML5
data:URIs for CSS backgrounds
local storage to cache API calls
(main list is regenerated daily)
HTML5
data:URIs for CSS backgrounds
local storage to cache API calls
(main list is regenerated daily)
Multipart XHR for images that
never change but may be served
up in different order (box art).
HTML5
data:URIs for CSS backgrounds
local storage to cache API calls
(main list is regenerated daily)
Multipart XHR for images that
never change but may be served
up in different order (box art).
cache-manifest to store code &
framework offline
Careful, Now:
Careful, Now:
border-image was very slow to
render at different widths.
Careful, Now:
border-image was very slow to
render at different widths.
Scrolling using CSS transitions
hit an absolute height limit on
iPod Touch and iPhone 3
Careful, Now:
border-image was very slow to
render at different widths.
Scrolling using CSS transitions
hit an absolute height limit on
iPod Touch and iPhone 3
box-shadow slowed things down
tremendously
Big but Unavoidable
      Mistake

I used an inadequate API.
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 title
and one for the user's rating.
Episodes and
bookmarks 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.
All calls must be
signed with oAuth.
Cannot be done on the fly by the
application; too slow.
Using JavaScript exposes your
key and secret.
Hack to fix: throw key/secret
over the wall with the app on
launch.
Good news: they may
  be fixing the API.




 http://techblog.netflix.com
NQL?
Netflix needs to build something
like Yahoo! Query Language.
http://developer.yahoo.com/yql
Group related endpoints
together. Developers need to be
able to get everything Netflix
knows about a customer's front
page, or a season of South Park,
with a single call to the API.
Really happening?




Yep, looks like like it might be.
http://techblog.netflix.com
View Source?
View Source?
Netflix has taken great care to
obfuscate this application.
View Source?
Netflix has taken great care to
obfuscate this application.
I'd like to help you view source,
but I can't.
View Source?
Netflix has taken great care to
obfuscate this application.
I'd like to help you view source,
but I can't.
I strongly recommend you do
NOT do any of the following....
Do not search
http://developer.netflix.com
    for "ipad open app."
Should you discover the nflx://
protocol, don't mess around with it.
Don't get all stubborn and try
nflx:// calls on an iPhone or iPad
 with the Netflix app installed.
If you try to hit an invalid nflx://
 URL, the app will drop you into
 Safari, pointed at the UI loader.
Do not copy this
URL into desktop Safari.
Don't inspect or follow any links to
           JavaScript.
Do not copy behavior.js to your
         clipboard....
And whatever you do, do NOT run
it through http://jsbeautifier.org.
If You Accidentally Happen to
Glimpse Some Source, Please Avert
     Your Eyes, and Assume the
             Following:
If You Accidentally Happen to
Glimpse Some Source, Please Avert
     Your Eyes, and Assume the
             Following:

 Anything that looks broken or
 brain-damaged is my fault.
If You Accidentally Happen to
Glimpse 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.
(awesome demo here)
Try It Yourself!




Plays only on devices with the Netflix app
 installed. Windows phone? Unknown....
Try It Yourself!
Please be gentle:
http://iflx.us




Plays only on devices with the Netflix app
 installed. Windows phone? Unknown....
Try It Yourself!
Please be gentle:
http://iflx.us
Remember, it's a two-hour hack.




Plays only on devices with the Netflix app
 installed. Windows phone? Unknown....
Try It Yourself!
Please be gentle:
http://iflx.us
Remember, it's a two-hour hack.
Fork Me On GitHub:
https://github.com/kentbrew/iflx


Plays only on devices with the Netflix app
 installed. Windows phone? Unknown....
Search Structure


<input id="query" /><ul id="results"></ul>
Search Loop
checkSearch : function() {
  var v = $.s.query.value;
  if (v) {
    if (v !== $.g.lastValue) {
      $.f.runSearch(v);
    }
    $.g.lastValue = v;
  }
}

$.w.setInterval(
 function() {
   $.f.checkSearch();
 }, 500
);
Search Query
runSearch: 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',
   }})
  );
}
OAuth?

http://kentbrewster.com/netflix-
api-explorer
http://kentbrewster.com/true-
oauth-confessions
Launching a Movie




Plays only on devices with the Netflix app
 installed. Windows phone? Unknown....
Launching a Movie
nflx://www.netflix.com/
WiPlayer




Plays only on devices with the Netflix app
 installed. Windows phone? Unknown....
Launching a Movie
nflx://www.netflix.com/
WiPlayer
?movieid=[box art movie ID]




Plays only on devices with the Netflix app
 installed. Windows phone? Unknown....
Launching a Movie
nflx://www.netflix.com/
WiPlayer
?movieid=[box art movie ID]
&episodeid=[episode ID]


Plays only on devices with the Netflix app
 installed. Windows phone? Unknown....
Launching a Movie
nflx://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....
Launch Behavior
var 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;
}
ASCII-art Starbars
li {
                                 .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;
}
Starbar JS
var 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);
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>
Questions?
Randall
 Munroe
  always
has the last
  laugh.

More Related Content

What's hot

Ionic: The Web SDK for Develop Mobile Apps.
Ionic: The Web SDK for Develop Mobile Apps.Ionic: The Web SDK for Develop Mobile Apps.
Ionic: The Web SDK for Develop Mobile Apps.Matheus Cardoso
 
Iphone programming: Objective c
Iphone programming: Objective cIphone programming: Objective c
Iphone programming: Objective cKenny Nguyen
 
Design For Multiple Touchpoints
Design For Multiple TouchpointsDesign For Multiple Touchpoints
Design For Multiple TouchpointsShane Morris
 
Building Mobile Applications with Ionic
Building Mobile Applications with IonicBuilding Mobile Applications with Ionic
Building Mobile Applications with IonicMorris Singer
 
TOC Workshop 2013
TOC Workshop 2013TOC Workshop 2013
TOC Workshop 2013Haig Armen
 
Real world software launch
Real world software launchReal world software launch
Real world software launchKunal Johar
 
Adobe phonegap-workshop-2013
Adobe phonegap-workshop-2013Adobe phonegap-workshop-2013
Adobe phonegap-workshop-2013Haig Armen
 
Ux design for iPhone
Ux design for iPhoneUx design for iPhone
Ux design for iPhonePaul Coulton
 
不能承受的感動 - iOS App實機測試
不能承受的感動 - iOS App實機測試不能承受的感動 - iOS App實機測試
不能承受的感動 - iOS App實機測試彼得潘 Pan
 
iPhone Dev Camp Keynote
iPhone Dev Camp KeynoteiPhone Dev Camp Keynote
iPhone Dev Camp Keynoteietatfandm
 
iPhoneDevCamp Keynote
iPhoneDevCamp KeynoteiPhoneDevCamp Keynote
iPhoneDevCamp KeynotePhil Wolff
 
iPhone Dev Camp Keynote
iPhone Dev Camp  KeynoteiPhone Dev Camp  Keynote
iPhone Dev Camp Keynotetristan.woo
 
Silverlight won't save your user experience - you will!
Silverlight won't save your user experience - you will!Silverlight won't save your user experience - you will!
Silverlight won't save your user experience - you will!Shane Morris
 
iPads for Beginners
iPads for BeginnersiPads for Beginners
iPads for Beginnerskarlaholt
 
Ionic Framework: Let's build amazing apps. No Excuses!
Ionic Framework: Let's build amazing apps. No Excuses!Ionic Framework: Let's build amazing apps. No Excuses!
Ionic Framework: Let's build amazing apps. No Excuses!Matheus Cardoso
 
Philly ete-2011
Philly ete-2011Philly ete-2011
Philly ete-2011davyjones
 
Ot pt apps 2012 updated
Ot pt apps 2012 updatedOt pt apps 2012 updated
Ot pt apps 2012 updatedEllen Deutsch
 
PhoneGap in a Day
PhoneGap in a DayPhoneGap in a Day
PhoneGap in a DayTroy Miles
 
Of innovation and impatience - Future Decoded 2015
Of innovation and impatience - Future Decoded 2015Of innovation and impatience - Future Decoded 2015
Of innovation and impatience - Future Decoded 2015Christian Heilmann
 
The image problem of the web and how to solve it…
The image problem of the web and how to solve it…The image problem of the web and how to solve it…
The image problem of the web and how to solve it…Christian Heilmann
 

What's hot (20)

Ionic: The Web SDK for Develop Mobile Apps.
Ionic: The Web SDK for Develop Mobile Apps.Ionic: The Web SDK for Develop Mobile Apps.
Ionic: The Web SDK for Develop Mobile Apps.
 
Iphone programming: Objective c
Iphone programming: Objective cIphone programming: Objective c
Iphone programming: Objective c
 
Design For Multiple Touchpoints
Design For Multiple TouchpointsDesign For Multiple Touchpoints
Design For Multiple Touchpoints
 
Building Mobile Applications with Ionic
Building Mobile Applications with IonicBuilding Mobile Applications with Ionic
Building Mobile Applications with Ionic
 
TOC Workshop 2013
TOC Workshop 2013TOC Workshop 2013
TOC Workshop 2013
 
Real world software launch
Real world software launchReal world software launch
Real world software launch
 
Adobe phonegap-workshop-2013
Adobe phonegap-workshop-2013Adobe phonegap-workshop-2013
Adobe phonegap-workshop-2013
 
Ux design for iPhone
Ux design for iPhoneUx design for iPhone
Ux design for iPhone
 
不能承受的感動 - iOS App實機測試
不能承受的感動 - iOS App實機測試不能承受的感動 - iOS App實機測試
不能承受的感動 - iOS App實機測試
 
iPhone Dev Camp Keynote
iPhone Dev Camp KeynoteiPhone Dev Camp Keynote
iPhone Dev Camp Keynote
 
iPhoneDevCamp Keynote
iPhoneDevCamp KeynoteiPhoneDevCamp Keynote
iPhoneDevCamp Keynote
 
iPhone Dev Camp Keynote
iPhone Dev Camp  KeynoteiPhone Dev Camp  Keynote
iPhone Dev Camp Keynote
 
Silverlight won't save your user experience - you will!
Silverlight won't save your user experience - you will!Silverlight won't save your user experience - you will!
Silverlight won't save your user experience - you will!
 
iPads for Beginners
iPads for BeginnersiPads for Beginners
iPads for Beginners
 
Ionic Framework: Let's build amazing apps. No Excuses!
Ionic Framework: Let's build amazing apps. No Excuses!Ionic Framework: Let's build amazing apps. No Excuses!
Ionic Framework: Let's build amazing apps. No Excuses!
 
Philly ete-2011
Philly ete-2011Philly ete-2011
Philly ete-2011
 
Ot pt apps 2012 updated
Ot pt apps 2012 updatedOt pt apps 2012 updated
Ot pt apps 2012 updated
 
PhoneGap in a Day
PhoneGap in a DayPhoneGap in a Day
PhoneGap in a Day
 
Of innovation and impatience - Future Decoded 2015
Of innovation and impatience - Future Decoded 2015Of innovation and impatience - Future Decoded 2015
Of innovation and impatience - Future Decoded 2015
 
The image problem of the web and how to solve it…
The image problem of the web and how to solve it…The image problem of the web and how to solve it…
The image problem of the web and how to solve it…
 

Similar to Mistakes I Made Building Netflix for the iPhone

HTML5, CSS3, and other fancy buzzwords
HTML5, CSS3, and other fancy buzzwordsHTML5, CSS3, and other fancy buzzwords
HTML5, CSS3, and other fancy buzzwordsMo Jangda
 
Adding the Awesomesauce Flavor with IE9 Pinned Sites
Adding the Awesomesauce Flavor with IE9 Pinned SitesAdding the Awesomesauce Flavor with IE9 Pinned Sites
Adding the Awesomesauce Flavor with IE9 Pinned SitesJohn Bristowe
 
Mobile App Feature Configuration and A/B Experiments
Mobile App Feature Configuration and A/B ExperimentsMobile App Feature Configuration and A/B Experiments
Mobile App Feature Configuration and A/B Experimentslacyrhoades
 
Free The Enterprise With Ruby & Master Your Own Domain
Free The Enterprise With Ruby & Master Your Own DomainFree The Enterprise With Ruby & Master Your Own Domain
Free The Enterprise With Ruby & Master Your Own DomainKen Collins
 
Github github-github
Github github-githubGithub github-github
Github github-githubfusion2011
 
Building Droids with JavaScript
Building Droids with JavaScriptBuilding Droids with JavaScript
Building Droids with JavaScriptAndrew Fisher
 
Stefan Judis "Did we(b development) lose the right direction?"
Stefan Judis "Did we(b development) lose the right direction?"Stefan Judis "Did we(b development) lose the right direction?"
Stefan Judis "Did we(b development) lose the right direction?"Fwdays
 
Topsy Turvy Design
Topsy Turvy DesignTopsy Turvy Design
Topsy Turvy DesignRich Quick
 
Building a game engine with jQuery
Building a game engine with jQueryBuilding a game engine with jQuery
Building a game engine with jQueryPaul Bakaus
 
RWD in the Wild
RWD in the WildRWD in the Wild
RWD in the WildRich Quick
 
Mobile Java with GWT: Still "Write Once, Run Everywhere"
Mobile Java with GWT: Still "Write Once, Run Everywhere"Mobile Java with GWT: Still "Write Once, Run Everywhere"
Mobile Java with GWT: Still "Write Once, Run Everywhere"Alex Theedom
 
Web Application Hacking
Web Application HackingWeb Application Hacking
Web Application HackingSensePost
 
Coding your company culture
Coding your company cultureCoding your company culture
Coding your company cultureAlex Wolkov
 
An Introduction To Shoes
An Introduction To ShoesAn Introduction To Shoes
An Introduction To ShoesTobias Pfeiffer
 
Week5 BA
Week5 BAWeek5 BA
Week5 BACMoz
 
Adventures in jQuery Mobile
Adventures in jQuery MobileAdventures in jQuery Mobile
Adventures in jQuery MobileAmber Brucker
 
State of Drupal keynote, DrupalCon Austin
State of Drupal keynote, DrupalCon AustinState of Drupal keynote, DrupalCon Austin
State of Drupal keynote, DrupalCon AustinDries Buytaert
 

Similar to Mistakes I Made Building Netflix for the iPhone (20)

HTML5, CSS3, and other fancy buzzwords
HTML5, CSS3, and other fancy buzzwordsHTML5, CSS3, and other fancy buzzwords
HTML5, CSS3, and other fancy buzzwords
 
Adding the Awesomesauce Flavor with IE9 Pinned Sites
Adding the Awesomesauce Flavor with IE9 Pinned SitesAdding the Awesomesauce Flavor with IE9 Pinned Sites
Adding the Awesomesauce Flavor with IE9 Pinned Sites
 
Mobile App Feature Configuration and A/B Experiments
Mobile App Feature Configuration and A/B ExperimentsMobile App Feature Configuration and A/B Experiments
Mobile App Feature Configuration and A/B Experiments
 
Free The Enterprise With Ruby & Master Your Own Domain
Free The Enterprise With Ruby & Master Your Own DomainFree The Enterprise With Ruby & Master Your Own Domain
Free The Enterprise With Ruby & Master Your Own Domain
 
Titanium Alloy Tutorial
Titanium Alloy TutorialTitanium Alloy Tutorial
Titanium Alloy Tutorial
 
Github github-github
Github github-githubGithub github-github
Github github-github
 
Building Droids with JavaScript
Building Droids with JavaScriptBuilding Droids with JavaScript
Building Droids with JavaScript
 
Stefan Judis "Did we(b development) lose the right direction?"
Stefan Judis "Did we(b development) lose the right direction?"Stefan Judis "Did we(b development) lose the right direction?"
Stefan Judis "Did we(b development) lose the right direction?"
 
Topsy Turvy Design
Topsy Turvy DesignTopsy Turvy Design
Topsy Turvy Design
 
Building a game engine with jQuery
Building a game engine with jQueryBuilding a game engine with jQuery
Building a game engine with jQuery
 
RWD in the Wild
RWD in the WildRWD in the Wild
RWD in the Wild
 
Mobile Java with GWT: Still "Write Once, Run Everywhere"
Mobile Java with GWT: Still "Write Once, Run Everywhere"Mobile Java with GWT: Still "Write Once, Run Everywhere"
Mobile Java with GWT: Still "Write Once, Run Everywhere"
 
YUI The Elephant In The Room
YUI The Elephant In The RoomYUI The Elephant In The Room
YUI The Elephant In The Room
 
Web Application Hacking
Web Application HackingWeb Application Hacking
Web Application Hacking
 
Yahoo is open to developers
Yahoo is open to developersYahoo is open to developers
Yahoo is open to developers
 
Coding your company culture
Coding your company cultureCoding your company culture
Coding your company culture
 
An Introduction To Shoes
An Introduction To ShoesAn Introduction To Shoes
An Introduction To Shoes
 
Week5 BA
Week5 BAWeek5 BA
Week5 BA
 
Adventures in jQuery Mobile
Adventures in jQuery MobileAdventures in jQuery Mobile
Adventures in jQuery Mobile
 
State of Drupal keynote, DrupalCon Austin
State of Drupal keynote, DrupalCon AustinState of Drupal keynote, DrupalCon Austin
State of Drupal keynote, DrupalCon Austin
 

Recently uploaded

Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Nikki Chapple
 
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Jeffrey Haguewood
 
All These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFAll These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFMichael Gough
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...itnewsafrica
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...Karmanjay Verma
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...itnewsafrica
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 

Recently uploaded (20)

Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
 
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
 
All These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFAll These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDF
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...React JS; all concepts. Contains React Features, JSX, functional & Class comp...
React JS; all concepts. Contains React Features, JSX, functional & Class comp...
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 

Mistakes I Made Building Netflix for the iPhone

  • 1. Mistakes I Made Building Netflix for the iPhone Kent Brewster @kentbrew http://kentbrewster.com
  • 2. In This Talk About Me About Life at Netflix Mistakes I Made and Lessons I Learned View Source, Launch Movies, and Roll Your Own UI
  • 4. About Me Seven-time Hugo and one-time Nebula loser.
  • 5. About Me Seven-time Hugo and one-time Nebula loser. Atari, 1977.
  • 6. About Me Seven-time Hugo and one-time Nebula loser. Atari, 1977. Invented the Learn-To-Type-Or- Be-Blown-To-Bits Video Gaming Genre, 1982.
  • 8. My Qualifications No Degree or Training in Anything Remotely Relevant
  • 9. My Qualifications No Degree or Training in Anything Remotely Relevant In the Right Place at the Right Time, with the Right Amount of Curiosity and OCD
  • 10. My Qualifications No Degree or Training in Anything Remotely Relevant In the Right Place at the Right Time, with the Right Amount of Curiosity and OCD Living Proof that Just About Anybody Can Do This
  • 11. Even More About Me WebMD, 1984-2003. (Yeah, seriously, nineteen years.) Yahoo, 2004-2009. Netflix, 2009-2010. These days? Vurve.
  • 13. Um ... "Vurve?" Vurve makes the process of advertising online suck a whole lot less for small businesses.
  • 14. Um ... "Vurve?" Vurve makes the process of advertising online suck a whole lot less for small businesses. Currently playing with: Big Data, Hadoop/MapReduce, Hive/ Pig, Ruby, Python, HTML5, EC2, Node.js, Redis, Mongo.
  • 15. Um ... "Vurve?" Vurve makes the process of advertising online suck a whole lot less for small businesses. Currently playing with: Big Data, Hadoop/MapReduce, Hive/ Pig, Ruby, Python, HTML5, EC2, Node.js, Redis, Mongo. http://vurve.com/jobs
  • 18. Life at Netflix They pay you what you're worth.
  • 19. Life at Netflix They pay you what you're worth. They don't track your vacation.
  • 20. Life at Netflix They pay you what you're worth. They don't track your vacation. You can bring your dog to work.
  • 21. Life at Netflix They pay you what you're worth. They don't track your vacation. You can bring your dog to work. When you tell your friends where you work, they will all say "Netflix! I love Netflix!"
  • 23. Things I Worked On Facebook Connect (v1)
  • 24. Things I Worked On Facebook Connect (v1) OAuth Walk-Through
  • 25. Things I Worked On Facebook Connect (v1) OAuth Walk-Through Netflix Widgets
  • 26. Things I Worked On Facebook Connect (v1) OAuth Walk-Through Netflix Widgets First API-Based Prototype
  • 27. Things I Worked On Facebook Connect (v1) OAuth Walk-Through Netflix Widgets First API-Based Prototype Trickplay in HTML
  • 28. Things I Worked On Facebook Connect (v1) OAuth Walk-Through Netflix Widgets First API-Based Prototype Trickplay in HTML Netflix for iPhone
  • 30. iPhone Chronology April 1st: iPad ships with Netflix
  • 31. iPhone Chronology April 1st: iPad ships with Netflix April 4th: invited to lead iPhone
  • 32. iPhone Chronology April 1st: iPad ships with Netflix April 4th: invited to lead iPhone April 9th: working prototype
  • 33. iPhone Chronology April 1st: iPad ships with Netflix April 4th: invited to lead iPhone April 9th: working prototype April 23rd: first design mocks
  • 34. iPhone Chronology April 1st: iPad ships with Netflix April 4th: invited to lead iPhone April 9th: working prototype April 23rd: first design mocks August 26th: champagne in the War Room!
  • 35. Surprise the First April 19th: iPhone 4 on Gizmodo.
  • 36. Surprise the Second June 7th: Reed shows the prototype at Apple's Worldwide Developer Conference, commits to "summer" launch.
  • 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.
  • 42. Why HTML? Netflix does incremental updates and heavy A/B testing.
  • 43. Why HTML? Netflix does incremental updates and heavy A/B testing. Entire UI can be overhauled without requiring a trip to the App Store.
  • 44. Why HTML? Netflix does incremental updates and heavy A/B testing. Entire UI can be overhauled without requiring a trip to the App Store. Bugs fix very quickly; the first one 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 HTML5 Try it out on Internet Explorer.*
  • 47. How To Tell HTML from HTML5 Try it out on Internet Explorer.* Did it work?
  • 48. How To Tell HTML from HTML5 Try it out on Internet Explorer.* Did it work? No?
  • 49. How To Tell HTML from HTML5 Try it out on Internet Explorer.* Did it work? No? It's HTML5.
  • 51. *Except IE9 IE9 launched the day after I gave this talk at SxSW.
  • 52. *Except IE9 IE9 launched the day after I gave this talk at SxSW. Everything I like to play with (shadows, round corners, gradients, canvas) works like a champ.
  • 53. *Except IE9 IE9 launched the day after I gave this talk at SxSW. Everything I like to play with (shadows, round corners, gradients, canvas) works like a champ. Now if we just had proper DOM- compatible JavaScript, life would be complete.
  • 54. UI Mistake I tried to use native form controls.
  • 55. Ratings Selector I liked this, but the designer hated the checkmark, and really wanted red and gold stars. Failed on Android.
  • 58. Search Box input type=search didn't work. Had to hand-whittle the borders, the little magnifying glass, and the progress indicator.
  • 59. Search Box input type=search didn't work. Had to hand-whittle the borders, the little magnifying glass, and the progress indicator. Goofy timing issues on focus() and blur().
  • 60. Search Box input type=search didn't work. Had to hand-whittle the borders, the little magnifying glass, and the progress indicator. Goofy timing issues on focus() and blur(). Blew up on Android.
  • 62. The Damn Keyboard Could not be raised or lowered programatically.
  • 63. The Damn Keyboard Could not be raised or lowered programatically. (You'd think focus() and blur() would do it, but you'd be wrong.)
  • 64. The Damn Keyboard Could not be raised or lowered programatically. (You'd think focus() and blur() would do it, but you'd be wrong.) Shoved the UI up and failed to shove it all the way back down.
  • 65. The Damn Keyboard Could not be raised or lowered programatically. (You'd think focus() and blur() would do it, but you'd be wrong.) Shoved the UI up and failed to shove it all the way back down. Blew steaming chunks on Android.
  • 66. Really Enormous Mistake I attempted to replicate native scrolling using HTML, CSS, and JavaScript.
  • 68. Scrolling Had to provide native performance, with a fixed header and footer.
  • 69. Scrolling Had to provide native performance, with a fixed header and footer. Had to perform awesomely on a 2G iPod Touch.
  • 70. Scrolling Had to provide native performance, with a fixed header and footer. Had to perform awesomely on a 2G iPod Touch. Was tested by launching the app, immediately scrolling like crazy before the data had loaded, and declaring that it sucked.
  • 72. I Stole From: PastryKit library (not public at the time, hard to understand)
  • 73. I Stole From: PastryKit library (not public at the time, hard to understand) TouchScroll (basic framework)
  • 74. I Stole From: PastryKit library (not public at the time, hard to understand) TouchScroll (basic framework) iScroll (excellent physics)
  • 75. I Stole From: PastryKit library (not public at the time, hard to understand) TouchScroll (basic framework) iScroll (excellent physics) Sencha Touch (did not officially exist)
  • 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.
  • 81. Three Windows Main list, gallery list, and details page.
  • 82. Three Windows Main list, gallery list, and details page. Try not to re-render lists, but also try not to rely on the DOM.
  • 83. Three Windows Main list, gallery list, and details page. Try not to re-render lists, but also 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 we're backing into, sometimes we don't. Sometimes the entire gallery has changed, from instant queue to a category gallery.
  • 90. position:fixed? Yes, position:fixed works on Android. http://bit.ly/aj8wyl This is good, because scrolling with JavaScript is kinda busted. This is bad, because it's buggy. http://bit.ly/cCTX6r
  • 91. webOS position:fixed? Yes, but I have a feeling that this won't roll out to everyone.
  • 92. Webkit Scrolling? Position header and footer absolutely. Listen for touchstart. Hide the header and footer, scroll the window, and replace when done.
  • 93. Headers in the App Header and footer should be part of the app's framework. Body should be a Web view; native scrolling will take care of everything. Throw title info over the wall to native app using hacky JavaScript 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 Mistake I tried to make the same codebase work for Android. (See also "I let my manager make key architectural decisions.")
  • 100. Um ... Android? When you view source you will discover multiple references to "android," so it's an open secret.
  • 101. Um ... Android? When you view source you will discover multiple references to "android," so it's an open secret. I have absolutely no idea when or if Netflix will launch for Android.
  • 102. Um ... Android? When you view source you will discover multiple references to "android," so it's an open secret. I have absolutely no idea when or if Netflix will launch for Android. I will say this: it was very, very hard to work on.
  • 104. More Mistakes I did not push back hard enough on the design.
  • 105. More Mistakes I did not push back hard enough on the design. I ignored the application framework.
  • 106. More Mistakes I did not push back hard enough on the design. I ignored the application framework. I failed to use some really important tools.
  • 107. HTML5
  • 108. HTML5 data:URIs for CSS backgrounds
  • 109. HTML5 data:URIs for CSS backgrounds local storage to cache API calls (main list is regenerated daily)
  • 110. HTML5 data:URIs for CSS backgrounds local storage to cache API calls (main list is regenerated daily) Multipart XHR for images that never change but may be served up in different order (box art).
  • 111. HTML5 data:URIs for CSS backgrounds local storage to cache API calls (main list is regenerated daily) Multipart XHR for images that never change but may be served up in different order (box art). cache-manifest to store code & framework offline
  • 113. Careful, Now: border-image was very slow to render at different widths.
  • 114. Careful, Now: border-image was very slow to render at different widths. Scrolling using CSS transitions hit an absolute height limit on iPod Touch and iPhone 3
  • 115. Careful, Now: border-image was very slow to render at different widths. Scrolling using CSS transitions hit an absolute height limit on iPod Touch and iPhone 3 box-shadow slowed things down tremendously
  • 116. Big but Unavoidable Mistake I 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 title and one for the user's rating.
  • 118. Episodes and bookmarks 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 be signed with oAuth. Cannot be done on the fly by the application; too slow. Using JavaScript exposes your key and secret. Hack to fix: throw key/secret over the wall with the app on launch.
  • 120. Good news: they may be fixing the API. http://techblog.netflix.com
  • 121. NQL? Netflix needs to build something like Yahoo! Query Language. http://developer.yahoo.com/yql Group related endpoints together. Developers need to be able to get everything Netflix knows about a customer's front page, 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
  • 124. View Source? Netflix has taken great care to obfuscate this application.
  • 125. View Source? Netflix has taken great care to obfuscate this application. I'd like to help you view source, but I can't.
  • 126. View Source? Netflix has taken great care to obfuscate this application. I'd like to help you view source, but I can't. I strongly recommend you do NOT do any of the following....
  • 128. Should you discover the nflx:// protocol, don't mess around with it.
  • 129. Don't get all stubborn and try nflx:// 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 this URL into desktop Safari.
  • 132. Don't inspect or follow any links to JavaScript.
  • 133. Do not copy behavior.js to your clipboard....
  • 134. And whatever you do, do NOT run it through http://jsbeautifier.org.
  • 135. If You Accidentally Happen to Glimpse Some Source, Please Avert Your Eyes, and Assume the Following:
  • 136. If You Accidentally Happen to Glimpse 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 to Glimpse 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.
  • 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.us Plays only on devices with the Netflix app installed. Windows phone? Unknown....
  • 141. Try It Yourself! Please be gentle: http://iflx.us Remember, it's 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.us Remember, it's a two-hour hack. Fork Me On GitHub: https://github.com/kentbrew/iflx Plays only on devices with the Netflix app installed. Windows phone? Unknown....
  • 143. Search Structure <input id="query" /><ul id="results"></ul>
  • 144. Search Loop checkSearch : 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 Query runSearch: 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', }}) ); }
  • 147. Launching a Movie Plays only on devices with the Netflix app installed. Windows phone? Unknown....
  • 148. Launching a Movie nflx://www.netflix.com/ WiPlayer Plays only on devices with the Netflix app installed. Windows phone? Unknown....
  • 149. Launching a Movie nflx://www.netflix.com/ WiPlayer ?movieid=[box art movie ID] Plays only on devices with the Netflix app installed. Windows phone? Unknown....
  • 150. Launching a Movie nflx://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 Movie nflx://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 Behavior var 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 Starbars li { .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 JS var 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>
  • 157. Randall Munroe always has the last laugh.

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n
  98. \n
  99. \n
  100. \n
  101. \n
  102. \n
  103. \n
  104. \n
  105. \n
  106. \n
  107. \n
  108. \n
  109. \n
  110. \n
  111. \n
  112. \n
  113. \n
  114. \n
  115. \n
  116. \n
  117. \n
  118. \n
  119. \n
  120. \n
  121. \n
  122. \n
  123. \n
  124. \n
  125. \n
  126. \n
  127. \n
  128. \n
  129. \n
  130. \n
  131. \n
  132. \n