Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

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.

Paul Kinlan

November 12, 2012
Tweet

More Decks by Paul Kinlan

Other Decks in Programming

Transcript

  1. 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
  2. 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
  3. WHAT I WANT FROM AN APP 1. Availability With added

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

    the time.” — Kinsters Compendium of Wordage
  5. EXPERIMENT WITH OFFLINE APPS Top 50(ish) apps on iOS and

    Android Downloaded App Pulled the plug Loaded app
  6. 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
  7. 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
  8. 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
  9. 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
  10. 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 :\
  11. I HAD WEB INTENTS FOR 25 MINUTES I suppose I

    have this time free now for questions?
  12. 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 " )
  13. 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 " )
  14. API'S ARE ONLY HALF THE PROBLEM Eco-systems need to be

    built around API's. You have to provide value to the developer.
  15. 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 .
  16. 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 ) ; } ;
  17. 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 ) ; } } ;
  18. 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 ) ; } } ;
  19. 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 ) ;
  20. 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 ) ;
  21. 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 ( ) ;
  22. 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 ) ;
  23. 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 .
  24. 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 ) ;
  25. 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 ) ;
  26. 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 ) ; } }
  27. 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 ) ) ; }
  28. APPS SHOULD BE ABLE ACCESS TO NATIVE API'S Network Sockets

    Serial Ports USB and Bluetooth File System Media Galleries
  29. 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 " ) ;
  30. 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 ) ; } ) ; } ) ;
  31. 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 ) ; } } ) ; } ;
  32. 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
  33. 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 / ' ) ;
  34. 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