Scale-proof Frontend: a real world architecture - Ivan Prignano, Nicola Racco - Codemotion Milan...
-
Upload
codemotion -
Category
Technology
-
view
379 -
download
0
description
Transcript of Scale-proof Frontend: a real world architecture - Ivan Prignano, Nicola Racco - Codemotion Milan...
Scale-proof Frontend:a real world architecture
28 Novembre 2014 Milano
IvanPrignano
@iprignano
NicolaRacco
@nicolaracco
Front-end developer Back-end developer
intro: ivan
27 M giocatori / giorno 67 M giocatori / mese
Il Progetto
Nicola ora
• Tornei a più fasi
• Generazione dinamica delle bracket
• Backend per approvazione utenti e gestione torneo
• Scalabilità in base al carico
Sistema di gestione e visualizzazione di tornei
2
8
BDD
Stack tecnologico
Ivan ora
Ruby on Rails
“Ruby on Rails is an open-source web framework that’s optimized for programmer happiness and sustainable productivity.
It lets you write beautiful code by favoring convention over configuration.”
WEB FRAMEWORK
• Minificazione asset out-of-the-box
• Turbolinks (pjax) out-of-the-box
SassCSS PREPROCESSOR
@import "mixins"
$red: #ff0000
.box width: 100%
.box-title color: $red @include boldness()
.box { width: 100%;}
.box .box-title { color: #ff0000;
font-weight: bold; text-transform: uppercase;
}
SlimTEMPLATING ENGINE
.box.box-title Sono un titolo!#box-content = @content
<div class=“box”><div class=“box-title”> Sono un titolo!</div><div id=“box-content”>
Sono un contenuto!</div>
</div>
CoffeeScriptCOMPILE-TO-JS LANGUAGE
class Brackets.Tooltips constructor: (el) -> alert(el)
new Brackets.Tooltips('.elemento')
Brackets.Tooltips = (function() { function Tooltips(el) { alert(el); }
return Tooltips;
})();
new Brackets.Tooltips('.elemento');
Come funziona
ancora Ivan
Registrazione utente Approvazione team
Chiusura registrazioniPubblicazione torneo
Avanzamento di fase Annuncio vincitori
Registrazione utente Approvazione team
Chiusura registrazioniPubblicazione torneo
Avanzamento di fase Annuncio vincitori
Problema:la generazione dell’albero
Nicola!
JSON
JSON EVERYWHERE
209,"with_recording":false,"score":[0,0],"result_type":5,"best_of":1},"from":[{"position":97,"payload":
{"id":null,"with_recording":false,"score":[0,0],"result_type":5}},{"position":99,"payload":{"id":209,"with_recording":false,"score":
[0,0],"result_type":5}}]},{"position":102,"payload":{"id":88,"with_recording":false,"score":[1,0],"result_type":3,"best_of":
1},"from":[{"position":101,"payload":{"id":88,"with_recording":false,"score":[0,0],"result_type":5}},
{"position":103,"payload":{"id":77,"with_recording":false,"score":[0,0],"result_type":5}}]}]},{"position":108,"payload":{"id":
151,"with_recording":true,"score":[0,1],"result_type":2,"best_of":1},"from":[{"position":106,"payload":{"id":
168,"with_recording":false,"score":[0,0],"result_type":5,"best_of":1},"from":[{"position":105,"payload":
{"id":null,"with_recording":false,"score":[0,0],"result_type":5}},{"position":107,"payload":{"id":
168,"with_recording":false,"score":[0,0],"result_type":5}}]},{"position":110,"payload":{"id":151,"with_recording":true,"score":
[0,1],"result_type":2,"best_of":1},"from":[{"position":109,"payload":{"id":84,"with_recording":false,"score":
HTML plain? Perché no!PRIMA PROVA
Semplice da scrivere e stilare
Facile da testare
PRO
Poco performante su grandi numeri
Zoom limitato
CONTRO
SVG!SECONDA PROVA
Semplice quanto la versione HTML
Uber Zooming
PRO
Poco performante su device mobile
CONTRO
Registrazione utente Approvazione team
Chiusura registrazioniPubblicazione torneo
Avanzamento di fase Annuncio vincitori
Ivan
Registrazione utente Approvazione team
Chiusura registrazioniPubblicazione torneo
Avanzamento di fase Annuncio vincitori
Problema:modali per il match report
Ivan
Preloading static data
$.when( @startGetAllStaticData()... ).done => @staticData = { champions: @champions spells: @summonerSpells items: @items versions: @versions }
# Show the brackets!
Preloading static data
$.when( @startGetAllStaticData()... ).done => @staticData = { champions: @champions spells: @summonerSpells items: @items versions: @versions }
# Show the brackets!
Preloading static data
$.when( @startGetAllStaticData()... ).done => @staticData = { champions: @champions spells: @summonerSpells items: @items versions: @versions }
# Show the brackets!
API Proxy
Cache delle chiamate
Nel caso le API ufficiali fossero down, il servizio funziona comunque
1 chiamata dal frontend = multiple sul backend
Brackets Proxy API
history.pushState()
https://dominio.com/brackets/1
history.pushState()
https://dominio.com/brackets/1/battles/64
Share dinamico
Share dinamico
Inoltre…
Nicola
JSON
Risultati
Nicola
da 2 a 16.384128^2
~10.350 connessioniConcurrency di 300
<0.05s
Possibili miglioramenti
Ivan
Static data spriting
SVG spriting
SSSSVG 2000Supercool Server-side Scalable Vector Graphics 2000
Offloading della creazione
delle SVG sul server
Conclusioni
Premature optimisation
!==
Unnecessary optimisation
Nicola
Refactor often, refactor early
Ivan
CACHE
ALL THE THINGS
Domande?