Building Web Apps of the future. Tomorrow, today and yesterday.

B590f0fb3aba34aee093cfa1406eac0b?s=47 Paul Kinlan
November 12, 2012

Building Web Apps of the future. Tomorrow, today and yesterday.

"I skate to where the puck is going to be, not where it has been." - Wayne Gretzky. Building apps using AppCache and IndexedDb. Pfft! That is so 2011. The browser is an amazing runtime that can already deliver amazing apps. Let's dive into the technologies that will help you deliver amazing web apps that blow your users socks off now and in the future.

B590f0fb3aba34aee093cfa1406eac0b?s=128

Paul Kinlan

November 12, 2012
Tweet

Transcript

  1. ME DEVELOPER ADVOCATE AT GOOGLE @Paul Kinlan

  2. BUILDING WEB APPS OF THE FUTURE TODAY, TOMORROW AND YESTERDAY

    By @Paul Kinlan
  3. @AEROTWIST IS RUNNING A SWEEP-STAKE ON MY "NERVOUS" WORD. Tweet

    him.
  4. I HEARD THIS ON A TRAIN “Oh I don't use

    apps on the web, I just use it for news and wikipedia” — Some guy
  5. BUILDING APPS FOR YESTERDAY

  6. STOP IT

  7. BUILDING APPS FOR TODAY

  8. IT'S HARD IT IS ALSO BROKEN DateDiff anyone?

  9. WE CAN STILL DO SOME AMAZING AMAZING AMAZING AMAZING AMAZING

    AMAZING AMAZING AMAZING AMAZING AMAZING AMAZING AMAZING AMAZING AMAZING AMAZING AMAZING AMAZING AMAZING AMAZING AMAZING AMAZING AMAZING STUFF
  10. E.G WEB LAB

  11. chromeweblab.com

  12. AND JAM WITH CHROME LAUNCHED YESTERDAY!

  13. jamwithchrome.com

  14. WHAT I WANT FROM AN APP 1. Availability With added

    2. Interoperability 3. Experience
  15. AVAILABILITY “Availability - noun: The act of being awesome all

    the time.” — Kinsters Compendium of Wordage
  16. WHY OFFLINE? 1. Mobile? 2. Responsiveness? Be there when your

    users need you.
  17. EXPERIMENT WITH OFFLINE APPS Top 50(ish) apps on iOS and

    Android Downloaded App Pulled the plug Loaded app
  18. None
  19. SAME EXPERIMENT WITH OFFLINE WEB APPS

  20. MOST APPS

  21. THE EXCEPTION

  22. SUMMARY Native Apps win hands down Lots works brilliantly offline,

    no online requirement. Many load and offer UI with cached content but needs web for more information. Many games loads and then download even more data. Minority of apps fail to load. The user is kept inside the app experience
  23. WEB DEVELOPERS ARE FROM VENUS “I will add offline support

    into my app” — A Web Dev “I will add online support into my app” — An App Dev
  24. WARNING OFFLINE APPS ARE A PARADIGM SHIFT FOR WEB DEVELOPERS

    THE WEB IS A HODGE-PODGE OF API'S THAT DON'T QUITE WORK TOGETHER
  25. APPCACHE If you want to have any offline experience at

    all, you have to use it.
  26. None
  27. APPCACHE HINTS Listen to Andrew Betts + Jake Archibald Prefer

    client side templating Avoid HTML5 history, prefer onhashchange Put webfonts in to the app cache NETWORK: * for using analytics
  28. STORAGE? If you want to have any offline storage at

    all, you have to use both indexedDB and WebSQL. Note: The versioning API just changed :\
  29. INTEROPERABILITY “No App is an island. — Paul Kinlan”

  30. WEB INTENTS AW SNAP.

  31. Photo by Shawn Hoke

  32. I HAD WEB INTENTS FOR 25 MINUTES I suppose I

    have this time free now for questions?
  33. REGISTER PROTOCOL HANDLER Use well known schemes Create new schemes

    Warning: Does not work well offline. n a v i g a t o r . r e g i s t e r P r o t o c o l H a n d l e r ( " m a i l t o " , " h t t p : / / p a u l . k i n l a n . m e / ? % s " ) n a v i g a t o r . r e g i s t e r P r o t o c o l H a n d l e r ( " w e b + I m O n a H o r s e " , " h t t p : / / p a u l . k i n l a n . m e / ? % s " )
  34. REGISTER CONTENT HANDLER Warning: Does not work well offline. n

    a v i g a t o r . r e g i s t e r C o n t e n t H a n d l e r ( " t e x t / p l a i n " , " h t t p : / / p a u l . k i n l a n . m e / ? % s " )
  35. API'S ARE ONLY HALF THE PROBLEM Eco-systems need to be

    built around API's. You have to provide value to the developer.
  36. EXPERIENCE “Do what the user expects — Paul Kinlan”

  37. DOWNLOAD Navigating cool. /to something isn't N a v i

    g a t i n g < a h r e f = " i m a g e s / m e . p n g " d o w n l o a d = " a w e s o m e . p n g " > / t o s o m e t h i n g i s n ' t < / a > c o o l .
  38. CREATEOBJECTURL This is a story all about how... MyFile.txt Create

    file w i n d o w . U R L . c r e a t e O b j e c t U R L ( b ) ; v a r d o w n l o a d F i l e = f u n c t i o n ( ) { w i n d o w . U R L = w i n d o w . w e b k i t U R L | | w i n d o w . U R L ; v a r t y p e r = d o c u m e n t . g e t E l e m e n t B y I d ( " t y p e r " ) ; v a r b = n e w B l o b ( [ t y p e r . t e x t C o n t e n t ] , { t y p e : " t e x t / p l a i n " } ) v a r a = d o c u m e n t . c r e a t e E l e m e n t ( ' a ' ) ; a . d o w n l o a d = c o n t a i n e r . q u e r y S e l e c t o r ( ' i n p u t [ t y p e = " t e x t " ] ' ) . v a l u e ; a . h r e f = w i n d o w . U R L . c r e a t e O b j e c t U R L ( b ) ; a . t e x t C o n t e n t = ' D o w n l o a d r e a d y ' ; a . d a t a s e t . d o w n l o a d u r l = [ " t e x t / p l a i n " , a . d o w n l o a d , a . h r e f ] . j o i n ( ' : ' ) ; o u t p u t . a p p e n d C h i l d ( a ) ; } ;
  39. No file chosen Choose File ACCESSING FILES < i n

    p u t t y p e = f i l e [ w e b k i t D i r e c t o r y ] > i n p u t . o n c h a n g e = f u n c t i o n ( e ) { v a r f i l e s = e . s r c E l e m e n t . f i l e s ; f o r ( v a r f i n f i l e s ) { v a r f i l e = f i l e s [ f ] ; v a r l i = d o c u m e n t . c r e a t e E l e m e n t ( " l i " ) ; l i . t e x t C o n t e n t = f i l e . n a m e ; f i l e l i s t . a p p e n d C h i l d ( l i ) ; } } ;
  40. ACCESSING DRAGGED FILES t a r g e t .

    o n d r o p = f u n c t i o n ( e ) { e . p r e v e n t D e f a u l t ( ) ; v a r f i l e s = e . d a t a T r a n s f e r . f i l e s ; f o r ( v a r f = 0 ; f < f i l e s . l e n g t h ; f + + ) { v a r f i l e = f i l e s [ f ] ; v a r l i = d o c u m e n t . c r e a t e E l e m e n t ( " l i " ) ; l i . t e x t C o n t e n t = f i l e . n a m e ; f i l e l i s t . a p p e n d C h i l d ( l i ) ; } } ;
  41. ACTUALLY READING THE FILE v a r f i l

    e = / / R e s u l t o f o p e r a t i o n v a r r e a d e r = n e w F i l e R e a d e r ( ) ; r e a d e r . o n l o a d = f u n c t i o n ( e ) { / / R E A D f i r s t 1 0 b y t e s v a r b y t e s = n e w U i n t 8 A r r a y ( e . t a r g e t . r e s u l t . s l i c e ( 0 , 1 0 ) ) ; f o r ( v a r b = 0 ; b < b y t e s . l e n g t h ; b + + ) { d r o p 2 . i n n e r T e x t + = " 0 x " + b y t e s [ b ] . t o S t r i n g ( 1 6 ) ; } } ; / / R e a d t h e d a t a i n r e a d e r . r e a d A s A r r a y B u f f e r ( f i l e ) ;
  42. I CAN HAZ FILE SYSTEM w i n d o

    w . r e q u e s t F i l e S y s t e m ( T E M P O R A R Y , / / p e r s i s t e n t v s . t e m p o r a r y s t o r a g e 1 0 2 4 * 1 0 2 4 , / / s i z e ( b y t e s ) o f n e e d e d s p a c e i n i t F s , / / s u c c e s s c a l l b a c k o p t _ e r r o r H a n d l e r / / o p t . e r r o r c a l l b a c k , d e n i a l o f a c c e s s ) ;
  43. CACHING FILES v a r x h r = n

    e w X M L H t t p R e q u e s t ( ) ; x h r . o p e n ( ' G E T ' , ' / p a t h / t o / i m a g e . p n g ' , t r u e ) ; x h r . r e s p o n s e T y p e = ' a r r a y b u f f e r ' ; x h r . o n l o a d = f u n c t i o n ( e ) { w i n d o w . r e q u e s t F i l e S y s t e m ( T E M P O R A R Y , 1 0 2 4 * 1 0 2 4 , f u n c t i o n ( f s ) { f s . r o o t . g e t F i l e ( ' i m a g e . p n g ' , { c r e a t e : t r u e } , f u n c t i o n ( f i l e E n t r y ) { f i l e E n t r y . c r e a t e W r i t e r ( f u n c t i o n ( w r i t e r ) { w r i t e r . o n w r i t e e n d = f u n c t i o n ( e ) { . . . } ; w r i t e r . o n e r r o r = f u n c t i o n ( e ) { . . . } ; w r i t e r . w r i t e ( n e w B l o b ( [ x h r . r e s p o n s e ] , { t y p e : ' i m a g e / p n g ' } ) ) ; } , o n E r r o r ) ; } , o n E r r o r ) ; } , o n E r r o r ) ; } ; x h r . s e n d ( ) ;
  44. FILER.JS MAKES IT EASY github.com/ebidel/filer.js v a r f i

    l e r = n e w F i l e r ( ) ; f i l e r . i n i t ( { p e r s i s t e n t : f a l s e , s i z e : 1 0 2 4 * 1 0 2 4 } , f u n c t i o n ( f s ) { . . . } , o n E r r o r ) ; f i l e r . l s ( ' p a t h / t o / s o m e / d i r / ' , f u n c t i o n ( e n t r i e s ) { . . . } , o n E r r o r ) ; f i l e r . c p ( ' f i l e . t x t ' , ' / p a t h / t o / f o l d e r ' , ' n e w n a m e . t x t ' , f u n c t i o n ( e n t r y ) { / / e n t r y . f u l l P a t h = = ' / p a t h / t o / f o l d e r / n e w n a m e . t x t ' } , o n E r r o r ) ; v a r b = n e w B l o b ( [ ' b o d y { c o l o r : r e d ; } ' ] , { t y p e : ' t e x t / c s s ' } ) ; f i l e r . w r i t e ( ' s t y l e s . c s s ' , { d a t a : b , t y p e : b . t y p e } , f u n c t i o n ( e n t r y , w r i t e r ) { . . . } , o n E r r o r ) ;
  45. MAKE THE FILE SYSTEM API CROSS BROWSER and a (http://goo.gl/WSRy0)

    https://github.com/ebidel/idb.filesystem.js Demo I t ' s j u s t t h e s a m e . F T W .
  46. BUILDING APPS FOR TOMORROW...

  47. CAMERA INPUT v a r o p t i o

    n s = { v i d e o : t r u e , a u d i o : f a l s e } ; v a r v = d o c u m e n t . q u e r y S e l e c t o r ( ' # c a m e r a ' ) ; v a r c a l l b a c k = f u n c t i o n ( s ) { v . s r c = w i n d o w . U R L . c r e a t e O b j e c t U R L ( s ) ; } n a v i g a t o r . g e t U s e r M e d i a ( o p t i o n s , c a l l b a c k ) ;
  48. AUDIO INPUT 0:13 / / s u c c e

    s s c a l l b a c k w h e n r e q u e s t i n g a u d i o i n p u t s t r e a m f u n c t i o n g o t S t r e a m ( s t r e a m ) { v a r a u d i o C o n t e x t = n e w w e b k i t A u d i o C o n t e x t ( ) ; / / C r e a t e a n A u d i o N o d e f r o m t h e s t r e a m . v a r m S t r e a m S o u r c e = a u d i o C o n t e x t . c r e a t e M e d i a S t r e a m S o u r c e ( s t r e a m ) ; / / C o n n e c t i t t o t h e d e s t i n a t i o n t o h e a r y o u r s e l f ( o r a n y o t h e r n o d e f o r p r o c e s s i n g ! ) m S t r e a m S o u r c e . c o n n e c t ( a u d i o C o n t e x t . d e s t i n a t i o n ) ; } n a v i g a t o r . w e b k i t G e t U s e r M e d i a ( { a u d i o : t r u e } , g o t S t r e a m ) ;
  49. APPLY CSS FILTERS v i d e o . c

    s s f i l t e r { - w e b k i t - a n i m a t i o n : f i l t e r s - a n i m 2 s i n f i n i t e a l t e r n a t e ; } @ - w e b k i t - k e y f r a m e s f i l t e r s - a n i m { 0 % { - w e b k i t - f i l t e r : b l u r ( 0 p x ) g r a y s c a l e ( 0 ) ; } 5 0 % { - w e b k i t - f i l t e r : b l u r ( 3 p x ) g r a y s c a l e ( 0 . 5 ) ; } 1 0 0 % { - w e b k i t - f i l t e r : b l u r ( 6 p x ) g r a y s c a l e ( 1 ) ; } }
  50. CSS SHADERS . d e m o - 5 .

    t a r g e t { t r a n s i t i o n : a l l 2 0 0 0 m s ; - w e b k i t - f i l t e r : c u s t o m ( u r l ( s h a d e r s / d e m o 5 . v e r t ) m i x ( u r l ( s h a d e r s / d e m o 5 . f r a g ) n o r m a l s o u r c e - a t o p ) , 4 0 4 0 , t i m e 0 , t r a n s f o r m p e r s p e c t i v e ( 6 0 0 ) ) ; } . d e m o - 5 . t a r g e t : h o v e r { - w e b k i t - f i l t e r : c u s t o m ( u r l ( s h a d e r s / d e m o 5 . v e r t ) m i x ( u r l ( s h a d e r s / d e m o 5 . f r a g ) n o r m a l s o u r c e - a t o p ) , 4 0 4 0 , t i m e 2 , t r a n s f o r m p e r s p e c t i v e ( 6 0 0 ) r o t a t e X ( 3 5 d e g ) s c a l e ( 0 . 8 ) ) ; }
  51. WEB RTC Start Call Hang Up

  52. NOW FOR SOMETHING MORE AWESOME. A NEW PLATFORM

  53. WHY?!?!

  54. APPS SHOULD BE OFFLINE BY DEFAULT Apps should load regardless

    of connection.
  55. APPS SHOULD LOOK AND FEEL NATIVE

  56. APPS SHOULD BE ABLE ACCESS TO NATIVE API'S Network Sockets

    Serial Ports USB and Bluetooth File System Media Galleries
  57. APPS SHOULD BE SECURE BY DEFAULT CSP FTW! # B

    l o c k e v e r y t h i n g , t h e n w h i t e l i s t f r o m t h e r e . d e f a u l t - s r c ' n o n e ' ; # A c c e p t C S S f r o m t h e e x t e n s i o n ' s p a c k a g e . s t y l e - s r c ' s e l f ' ; # A c c e p t J a v a S c r i p t f r o m t h e e x t e n s i o n ' s p a c k a g e . s c r i p t - s r c ' s e l f ' ; # A l l o w i m a g e s f r o m G o o g l e M a p s t o l o a d o v e r H T T P S . i m g - s r c h t t p s : / / m a p s . g o o g l e . c o m ; a l e r t ( e v a l ( " f o o . b a r . b a z " ) ) ; w i n d o w . s e t T i m e o u t ( " a l e r t ( ' h i ' ) " , 1 0 ) ; w i n d o w . s e t I n t e r a l ( " a l e r t ( ' h i ' ) " , 1 0 ) ; n e w F u n c t i o n ( " r e t u r n f o o . b a r . b a z " ) ;
  58. FINALLY. APPS SHOULD BE BUILT USING TECHNOLOGY THAT WE KNOW

    AND LOVE HTML CSS JAVASCRIPT
  59. ACCESS TO HARDWARE NETWORK SOCKETS WEB SERVER IN THE BROWSER

  60. IT'S JUST A SOCKET v a r s o c

    k e t = c h r o m e . s o c k e t ; s o c k e t . c r e a t e ( " t c p " , { } , f u n c t i o n ( _ s o c k e t I n f o ) { s o c k e t I n f o = _ s o c k e t I n f o ; / / C a c h e g l o b a l l y [ e e k ] s o c k e t . l i s t e n ( s o c k e t I n f o . s o c k e t I d , " 1 2 7 . 0 . 0 . 1 " , 8 0 8 0 , 2 0 , f u n c t i o n ( r e s u l t ) { / / A c c e p t t h e f i r s t r e s p o n s e s o c k e t . a c c e p t ( s o c k e t I n f o . s o c k e t I d , o n A c c e p t ) ; } ) ; } ) ;
  61. BUT THERE IS A LOT OF CODE v a r

    o n A c c e p t = f u n c t i o n ( a c c e p t I n f o ) { / / T h i s i s a r e q u e s t t h a t t h e s y s t e m i s p r o c e s s i n g . / / R e a d t h e d a t a . s o c k e t . r e a d ( a c c e p t I n f o . s o c k e t I d , f u n c t i o n ( r e a d I n f o ) { / / P a r s e t h e r e q u e s t . v a r d a t a = a r r a y B u f f e r T o S t r i n g ( r e a d I n f o . d a t a ) ; / / W e o n l y w a n t t o h a n d l e g e t r e q u e s t s i f ( d a t a . i n d e x O f ( " G E T " ) = = 0 ) { / / w e c a n o n l y d e a l w i t h G E T r e q u e s t s v a r u r i E n d = d a t a . i n d e x O f ( " " , 4 ) ; i f ( u r i E n d < 0 ) { / * t h r o w a w o b b l e r * / r e t u r n ; } v a r u r i = d a t a . s u b s t r i n g ( 4 , u r i E n d ) ; v a r f i l e = f i l e s M a p [ u r i ] ; / / p i c k o u t t h e f i l e w e w a n t t o s e r v e r i f ( ! ! f i l e = = f a l s e ) { / * F i l e d o e s n o t e x i s t * / r e t u r n ; } w r i t e 2 0 0 R e s p o n s e ( a c c e p t I n f o . s o c k e t I d , f i l e ) ; } e l s e { / / T h r o w a n e r r o r s o c k e t . d e s t r o y ( a c c e p t I n f o . s o c k e t I d ) ; / / W e n e e d t o s a y t h a t w e c a n a c c e p t a n o t h e r i n c o m i n g r e q u e s t . s o c k e t . a c c e p t ( s o c k e t I n f o . s o c k e t I d , o n A c c e p t ) ; } } ) ; } ;
  62. CAN WE USE AN EXISTING ECO-SYSTEM?

  63. LIKE NODE?

  64. NODE API'S IN THE BROWSER MARKDOWN o n l o

    a d = f u n c t i o n ( ) { v a r m d E l = d o c u m e n t . g e t E l e m e n t B y I d ( " m a r k d o w n " ) ; v a r h t m l E l = d o c u m e n t . g e t E l e m e n t B y I d ( " h t m l " ) ; v a r m d = r e q u i r e ( " m a r k d o w n " ) . m a r k d o w n ; m d E l . o n k e y p r e s s = f u n c t i o n ( ) { v a r o u t p u t = m d . t o H T M L ( m d E l . v a l u e ) ; h t m l E l . i n n e r H T M L = o u t p u t ; } ; } ; $ b r o w s e r i f y - r m a r k d o w n - o b u n d l e . j s
  65. NODE API'S IN THE BROWSER BROWSERIFY + CHROME MAPPING =

    WIN powered by https://github.com/iceddev/http-chromify Browserify Chrome v a r h t t p = r e q u i r e ( ' h t t p ' ) ; h t t p . c r e a t e S e r v e r ( f u n c t i o n ( r e q , r e s ) { r e s . w r i t e H e a d ( 2 0 0 , { ' C o n t e n t - T y p e ' : ' t e x t / p l a i n ' } ) ; r e s . e n d ( ' H e l l o W o r l d \ n ' ) ; } ) . l i s t e n ( 1 3 3 7 , ' 1 2 7 . 0 . 0 . 1 ' ) ; c o n s o l e . l o g ( ' S e r v e r r u n n i n g a t h t t p : / / 1 2 7 . 0 . 0 . 1 : 1 3 3 7 / ' ) ;
  66. CLOSING THOUGHTS

  67. DO AWESOME

  68. AND BUILD DRONES youtube.com/watch?v=K7sG1dRSn4c

  69. THANKS @Paul_Kinlan +Paul Kinlan http://paul.kinlan.me LINKS Browserify - Chromeify -

    net - http - github.com/substack/node-browserify github.com/GoogleChrome/browserify-chrome github.com/GoogleChrome/net-chromeify github.com/iceddev/http-chromify
  70. None