Slide 1

Slide 1 text

ME DEVELOPER ADVOCATE AT GOOGLE @Paul Kinlan

Slide 2

Slide 2 text

BUILDING WEB APPS OF THE FUTURE TODAY, TOMORROW AND YESTERDAY By @Paul Kinlan

Slide 3

Slide 3 text

@AEROTWIST IS RUNNING A SWEEP-STAKE ON MY "NERVOUS" WORD. Tweet him.

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

BUILDING APPS FOR YESTERDAY

Slide 6

Slide 6 text

STOP IT

Slide 7

Slide 7 text

BUILDING APPS FOR TODAY

Slide 8

Slide 8 text

IT'S HARD IT IS ALSO BROKEN DateDiff anyone?

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

E.G WEB LAB

Slide 11

Slide 11 text

chromeweblab.com

Slide 12

Slide 12 text

AND JAM WITH CHROME LAUNCHED YESTERDAY!

Slide 13

Slide 13 text

jamwithchrome.com

Slide 14

Slide 14 text

WHAT I WANT FROM AN APP 1. Availability With added 2. Interoperability 3. Experience

Slide 15

Slide 15 text

AVAILABILITY “Availability - noun: The act of being awesome all the time.” — Kinsters Compendium of Wordage

Slide 16

Slide 16 text

WHY OFFLINE? 1. Mobile? 2. Responsiveness? Be there when your users need you.

Slide 17

Slide 17 text

EXPERIMENT WITH OFFLINE APPS Top 50(ish) apps on iOS and Android Downloaded App Pulled the plug Loaded app

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

SAME EXPERIMENT WITH OFFLINE WEB APPS

Slide 20

Slide 20 text

MOST APPS

Slide 21

Slide 21 text

THE EXCEPTION

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

APPCACHE If you want to have any offline experience at all, you have to use it.

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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 :\

Slide 29

Slide 29 text

INTEROPERABILITY “No App is an island. — Paul Kinlan”

Slide 30

Slide 30 text

WEB INTENTS AW SNAP.

Slide 31

Slide 31 text

Photo by Shawn Hoke

Slide 32

Slide 32 text

I HAD WEB INTENTS FOR 25 MINUTES I suppose I have this time free now for questions?

Slide 33

Slide 33 text

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 " )

Slide 34

Slide 34 text

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 " )

Slide 35

Slide 35 text

API'S ARE ONLY HALF THE PROBLEM Eco-systems need to be built around API's. You have to provide value to the developer.

Slide 36

Slide 36 text

EXPERIENCE “Do what the user expects — Paul Kinlan”

Slide 37

Slide 37 text

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 .

Slide 38

Slide 38 text

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 ) ; } ;

Slide 39

Slide 39 text

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 ) ; } } ;

Slide 40

Slide 40 text

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 ) ; } } ;

Slide 41

Slide 41 text

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 ) ;

Slide 42

Slide 42 text

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 ) ;

Slide 43

Slide 43 text

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 ( ) ;

Slide 44

Slide 44 text

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 ) ;

Slide 45

Slide 45 text

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 .

Slide 46

Slide 46 text

BUILDING APPS FOR TOMORROW...

Slide 47

Slide 47 text

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 ) ;

Slide 48

Slide 48 text

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 ) ;

Slide 49

Slide 49 text

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 ) ; } }

Slide 50

Slide 50 text

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 ) ) ; }

Slide 51

Slide 51 text

WEB RTC Start Call Hang Up

Slide 52

Slide 52 text

NOW FOR SOMETHING MORE AWESOME. A NEW PLATFORM

Slide 53

Slide 53 text

WHY?!?!

Slide 54

Slide 54 text

APPS SHOULD BE OFFLINE BY DEFAULT Apps should load regardless of connection.

Slide 55

Slide 55 text

APPS SHOULD LOOK AND FEEL NATIVE

Slide 56

Slide 56 text

APPS SHOULD BE ABLE ACCESS TO NATIVE API'S Network Sockets Serial Ports USB and Bluetooth File System Media Galleries

Slide 57

Slide 57 text

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 " ) ;

Slide 58

Slide 58 text

FINALLY. APPS SHOULD BE BUILT USING TECHNOLOGY THAT WE KNOW AND LOVE HTML CSS JAVASCRIPT

Slide 59

Slide 59 text

ACCESS TO HARDWARE NETWORK SOCKETS WEB SERVER IN THE BROWSER

Slide 60

Slide 60 text

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 ) ; } ) ; } ) ;

Slide 61

Slide 61 text

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 ) ; } } ) ; } ;

Slide 62

Slide 62 text

CAN WE USE AN EXISTING ECO-SYSTEM?

Slide 63

Slide 63 text

LIKE NODE?

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

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 / ' ) ;

Slide 66

Slide 66 text

CLOSING THOUGHTS

Slide 67

Slide 67 text

DO AWESOME

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

No content