Slide 1

Slide 1 text

Jurassic JavaScript Park Rodando offline até na Ilha Nublar!

Slide 2

Slide 2 text

@eduardojmatos eduardomatos.me OI, EU SOU O EDU

Slide 3

Slide 3 text

a maior plataforma de contratação de serviços do Brasil

Slide 4

Slide 4 text

PORQUE AINDA FALAMOS SOBRE OFFLINE EM 2016?

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

http://ispspeedindex.netflix.com/country/brazil/

Slide 7

Slide 7 text

MÉDIA DE CONEXÃO MÓVEL 2,5MB 20,4MB 8,8MB http://www.reclameaqui.com.br/noticias/noticias/com-media-de-velocidade-abaixo-da-mundial-internet-brasileir_1585/

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

COMO ISSO DEVERIA IMPACTAR NOSSO DESENVOLVIMENTO?

Slide 10

Slide 10 text

UX Sensação de rapidez Não deve ser frustrante Deve ser honesta sobre conectividade Não deve perder informações

Slide 11

Slide 11 text

TÁ, E COMO FAZ?

Slide 12

Slide 12 text

APPLICATION CACHE CACHE DE ARQUIVOS NO BROWSER

Slide 13

Slide 13 text

CACHE MANIFEST CACHE: http://jurassicpark.com/images/dino1.jpg http://jurassicpark.com/images/dino2.jpg http://jurassicpark.com/images/dino3.jpg NETWORK: https://facebook.com/sdk.js FALLBACK: index.html offline.html

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

PROBLEMAS O AppCache só atualiza o conteúdo do manifesto se ele mesmo for atualizado Os arquivos sempre virão do ApplicationCache mesmo se você estiver online … Recomendo fortemente a leitura: http://sergiolopes.org/palestra-appcache-html5-offline/

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

HÁ ESPERANÇA

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

MAS AINDA NÃO É O IDEAL… O Application Cache é ok para cachear assets Mas precisamos de algo mais evoluído para controlar de forma programática, sem modo texto

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

AppCache Service Workers

Slide 22

Slide 22 text

O FUTURO DO CACHE NO BROWSER SERVICE WORKERS

Slide 23

Slide 23 text

if ('serviceWorker' in navigator) { navigator.serviceWorker.register( '/js/sw.js',
 { scope: '/' }
 ).then(function(reg) { if(reg.installing) { console.log('Service worker installing'); } else if(reg.waiting) { console.log('Service worker installed'); } else if(reg.active) { console.log('Service worker active'); } }).catch(function(error) { // registration failed console.log('Registration failed with ' + error); }); };

Slide 24

Slide 24 text

// /js/sw.js this.addEventListener('install', function(event) { event.waitUntil( caches.open('v1').then(function(cache) { return cache.addAll([ '/index.html', '/js/app.js', '/css/styles.css', '/images/gallery/jurassic_park.jpg' ]); }) ); });

Slide 25

Slide 25 text

this.addEventListener('fetch', function(event) { var response; event.respondWith(caches.match(event.request).catch(function() { return fetch(event.request); }).then(function(r) { response = r; caches.open('v1').then(function(cache) { cache.put(event.request, response); }); return response.clone(); }).catch(function() { return caches.match('/images/gallery/jurassic_park.jpg'); })); });

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

No content

Slide 28

Slide 28 text

MAS VAMOS FALAR SOBRE DADOS Como faço pra armazenar informações além de assets?

Slide 29

Slide 29 text

FORMAS DE SE ARMAZENAR DADOS • cookies • localStorage • WebSQL • IndexedDB

Slide 30

Slide 30 text

COOKIE Forma mais primitiva de armazenar informação no browser

Slide 31

Slide 31 text

document.cookie = "dino=T-Rex"; document.cookie = "dino=T-Rex;expires=Fri, 31 Dec 9999 23:59:59 GMT";

Slide 32

Slide 32 text

No content

Slide 33

Slide 33 text

https://github.com/js-cookie/js-cookie

Slide 34

Slide 34 text

Cookies.set("dino", "Velociraptor", { expires: 7 }); Cookies.get("dino"); // returns "dino" Cookies.remove("dino");

Slide 35

Slide 35 text

PRÓS CONTRAS Simples de implementar Sem uma biblioteca o controle fica complicado Browsers suportam amplamente Problemas de segurança (Cookie stealing e XSS, CSFR, etc.) Ótimo para informações curtas Limite de 4093 bytes

Slide 36

Slide 36 text

LOCALSTORAGE Forma mais moderninha de armazenamento

Slide 37

Slide 37 text

localStorage.setItem("dino", "Aragosaurus"); localStorage.getItem("dino"); // returns "Aragosaurus" localStorage.dino = "Aragosaurus";

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

https://github.com/addyosmani/basket.js

Slide 40

Slide 40 text

basket.require( { url: "jquery.js" }, { url: "underscore.js" }, { url: "backbone.js" } ); basket.require({ url: "jquery.min.js", key: "jquery" }); var req = basket.get("jquery");

Slide 41

Slide 41 text

https://github.com/marcuswestin/store.js

Slide 42

Slide 42 text

store.set("dino", "Datousaurus"); store.get("dino"); // returns "Datousaurus" store.remove("dino"); store.clear(); store.set("dino", { name: "Datousaurus", diet: "herbivorous" });

Slide 43

Slide 43 text

No content

Slide 44

Slide 44 text

PRÓS CONTRAS Fácil implementação Limite de 5M por domínio Amplo suporte É síncrono Melhor segurança Os dados ficam lá eternamente, mesmo não visitando mais o site

Slide 45

Slide 45 text

WEBSQL SQL no seu browser

Slide 46

Slide 46 text

// name, version, description, size (bytes) var db = openDatabase("dinos", "1", "todo list example db", 2 * 1024 * 1024); // executeSql // (SQL string, arguments, success, error) db.transaction( function (tx) { tx.executeSql( "CREATE TABLE IF NOT EXISTS dinos (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT)", [], function (tx, results) { console.log("ok!"); }, function (err) { console.log("error!", err); } ); } );

Slide 47

Slide 47 text

db.transaction( function (tx) { tx.executeSql( "SELECT * FROM dinos WHERE id > ?", ["1"], function (tx, results) { var row = ""; for (var i=0; i

Slide 48

Slide 48 text

db.transaction( function (tx) { tx.executeSql( "INSERT INTO dinos(name) VALUES(?)", ["Megalosaurus"], function ( tx, results ) { console.log("ok! inserted!"); }, function (err) { console.log("not inserted :("); } ); }, function (err) { console.log("inserting problems...", err); }, function () { console.log("transaction completed!"); } );

Slide 49

Slide 49 text

No content

Slide 50

Slide 50 text

No content

Slide 51

Slide 51 text

No content

Slide 52

Slide 52 text

PRÓS CONTRAS Banco de dados no browser Sintaxe SQL pode assustar quem não está acostumado Performance razoável Deprecated. Apenas alguns browsers ainda dão suporte. Não é full SQL supported. Crash com muitos dados (10,000 rows já apresenta certa lentidão)

Slide 53

Slide 53 text

INDEXEDDB like a localStorage, but coolest

Slide 54

Slide 54 text

var request = window.indexedDB.open("DinoDatabase", 1); request.onerror = function (event) { console.log("Error", event.target.errorCode); }; request.onupgradeneeded = function (event) { db = event.target.result; if ( db.objectStoreNames.contains("dinos") ) { db.deleteObjectStore("dinos"); } var store = db.createObjectStore("dinos", { autoIncrement: true }); };

Slide 55

Slide 55 text

request.onsuccess = function (event) { db = event.target.result; var trans = db.transaction(["dinos"], "readwrite"); var transRequest = trans.objectStore("dinos"); transRequest.onsuccess = function (event) { var result = transRequest.result || event.result; if (!result) return; console.log("dino", result.key, result.value.text); cursor.continue(); } var dinoName = "Velociraptor"; var storeRequest = transRequest.put(dinoName); storeRequest.onsuccess = function (event) { console.log(event.target.result) } storeRequest.onerror = function (event) { console.log(event) } };

Slide 56

Slide 56 text

No content

Slide 57

Slide 57 text

No content

Slide 58

Slide 58 text

PRÓS CONTRAS Mais evoluído que localStorage Suporte em browsers modernos Pode trabalhar com uma quantidade maior de dados Se o usuário fechar o browser no meio de uma transaction, o dado se perde Pode trabalhar em Workers Mais complexo que as outras formas de armazenamento Tem índices

Slide 59

Slide 59 text

FUNCIONA NO MEU FRAMEWORK DO ❤?

Slide 60

Slide 60 text

LOCALSTORAGE https://github.com/jeromegn/Backbone.localStorage https://github.com/grevory/angular-local-storage https://github.com/STRML/react-localstorage https://github.com/locks/ember-localstorage-adapter

Slide 61

Slide 61 text

WEBSQL https://github.com/BJTerry/backbone.websqloffline https://github.com/paulocaldeira17/angular-websql https://github.com/inDream/ember-model-websql- adapter

Slide 62

Slide 62 text

INDEXEDDB https://github.com/vincentmac/backbone-idb https://github.com/bramski/angular-indexedDB https://github.com/kurko/ember-indexeddb-adapter

Slide 63

Slide 63 text

OK, MAS TUDO ISSO AINDA PARECE MUITO COMPLICADO...

Slide 64

Slide 64 text

MOZILLA.LOCALFORAGE https://github.com/mozilla/localForage

Slide 65

Slide 65 text

// In localStorage, we would do: var obj = { value: "Dinofauro" }; localStorage.setItem("dino", JSON.stringify(obj)); console.log(obj.value); // With localForage, we use callbacks: localforage.setItem("dino", obj, function (err, result) { console.log(result.value); });

Slide 66

Slide 66 text

localforage.getItem("dino", function(err, value) { if (err) { console.error(“Oops...”); } else { console.log("Dino:", value); } });

Slide 67

Slide 67 text

No content

Slide 68

Slide 68 text

No content

Slide 69

Slide 69 text

var db = new PouchDB("dinoDB"); db.put({ _id: 1, name: "Dinofauro Fefiz" }); db.changes().on("change", function () { console.log("Alterou alfuma foisa"); }); db.replicate.to("http://dinofauro.com/dinoDB");

Slide 70

Slide 70 text

No content

Slide 71

Slide 71 text

AGORA SIM! PODEMOS RODAR NOSSA APLICAÇÃO ATÉ NA ILHA NUBLAR!!!

Slide 72

Slide 72 text

NÃO É SÓ POR DIVERSÃO É QUESTÃO DE UX!!!

Slide 73

Slide 73 text

No content

Slide 74

Slide 74 text

SEJA SENSATO! Em alguns casos o cenário offline nem pode existir, como em serviços de chat, transmissão de áudio e vídeo, e etc. O esforço vale a pena somente quando o cenário pede esse tipo de arquitetura

Slide 75

Slide 75 text

No content

Slide 76

Slide 76 text

[email protected] @eduardojmatos http://eduardomatos.me OBRIGADO ;)