SlideShare une entreprise Scribd logo
1  sur  161
Télécharger pour lire hors ligne
os desafios do desenvolvimento
de front-end em um e-commerce
@shiota 2013
olá!slideshare.net/eshiota
github.com/eshiota
@shiota
front-end engineer
@
DEV
e-commerce 101
em alguns slides
=)
taxa de conversão
dos usuários que entram no site, quantos
finalizam uma compra?
ticket médio
em média, quanto os usuários gastam
por compra?
=)
taxa de conversão
×
ticket médio
=
taxa de conversão
×
ticket médio
= $
= $=)
= ?=)
complexo
indeciso
exigente
inexperiente
decidido
cuidadoso
experiente
ser humano, como
todos nós =)
o que faz o usuário
abandonar o carrinho?
alto custo de frete
$
não estão prontos
para finalizar
?
produtos muito caros
$
guardam para depois
não mencionou
claramente o frete
?
sem guest checkout
formulário com
muitas informações
checkout complexo
website lento
taxas extras
falta de opções
de pagamento
entrega demorada
spam de ofertas
site não funciona
=(
como o front-end pode
melhorar a conversão?
formulário com muitas informações
checkout complexo
website lento
site não funciona
velocidade da página
interface estável
detalhes = emotion design
validação de novas hipóteses
desafios de front-end
(agora a palestra começa =P)
múltiplos desenvolvedores
desenvolvimento escalável
performance client-side
testes a/b
trabalhando com
vários desenvolvedores
trabalhar em equipe
é difícil... =(
aspas simples
×
aspas duplas
ponto e vírgula no JS
×
sem ponto e vírgula
JavaScript
×
CoffeeScript
(JavaScript, claro)
(com ponto e vírgula)
... mas cada um pode ter
uma visão diferente e
complementar. =)
code smell performance
sintaxe arquitetura
mantenha um code
standard para o time.
consistência, legibilidade,
sem bikeshed.
git + pull requests
qualquer um revisa,
qualquer um comenta.
diferentes visões,
mais erros detectados.
o conhecimento é
disseminado pelo time.
todos ficam mais
criteriosos com o que fazem.
desenvolvimento
escalável e testável
desenvolvimento ágil:
mudanças precisas,
altos ganhos.
melhorias são constantes,
e nada é 100% definitivo.
o código deve ser facilmente
alterável/adaptável.
dica 1
usem pre-processors de CSS.
sério. agora. já. eu espero.
sass
+
variáveis, mixins e
funções
/*********************************************************************
*
* Variables Module
*
* All constants that will be used through the styles must be
* defined here.
*
*********************************************************************/
$TEXT_COLOR : #555;
$DISCOUNT_COLOR : #ef6565;
$LIGHT_COLOR : #fefafa;
$SELECTION_BACKGROUND : #41bdce;
$SELECTION_COLOR : #fff;
$LINK_COLOR : #447f87;
$LINK_HOVER_COLOR : #41bdce;
$LINK_ACTIVE_COLOR : #447f87;
$ERROR_BACKGROUND : #fffaad;
$LIGHT_BACKGROUND : #fefefa;
$SITE_WIDTH : 978px;
$FOOTER_HEIGHT : 777px;
$PURPLE : #905194;
$ORANGE : #fbb100;
/*********************************************************************
*
* Mixins Module
*
* All general purpose mixins are defined here.
*
*********************************************************************/
/*********************************************************************
* =Clearfix
*********************************************************************/
@mixin clearfix {
&:after {
clear: both;
content: " ";
display: block;
font-size: 0;
height: 0;
visibility: hidden;
}
zoom: 1;
}
/*********************************************************************
* =Image replacement
*
* `display` property should be declare on the element, not here
* on the mixin. Element must have fixed width and height.
*********************************************************************/
@mixin img_replacement {
text-indent: 100%;
overflow: hidden;
white-space: nowrap;
}
/*********************************************************************
*
* Functions Module
*
* Custom functions used by the application
*
*********************************************************************/
// Returns unitless number
@function remove-unit($number) {
$unit: unit($number);
$one: 1;
@if $unit == "px" { $one: 1px; }
@if $unit == "em" { $one: 1em; }
@if $unit == "%" { $one: 1%; }
@return $number / $one;
}
// Returns flexible value
// Returns `em` by default, accepts `%` as format.
@function flex($target, $context: 14, $unit: "em") {
$size: remove-unit($target) / remove-unit($context);
@if $unit == "em" { @return #{$size}em; }
@if $unit == "%" { @return percentage($size); }
}
// Alias to `flex` function, using `%` as format.
@function perc($target, $context) {
@return flex($target, $context, "%");
}
// Alias to `flex` function, using `em` as format.
@function em($target, $context: 14) {
@return flex($target, $context, "em");
}
estilos modularizados
em partials
app/
assets/
stylesheets/
base/
_functions.scss
_mixins.scss
_variables.scss
ui/
_breadcrumb.scss
_carousel.scss
_dentedBox.scss
_flashMessage.scss
/*******************************************************************************
*
* UI > Breadcrumb
*
* General styles for the breadcrumb.
*
*******************************************************************************/
.breadcrumb {
font-size: em(12px);
line-height: em(21px, 12px);
text-transform: uppercase;
color: #444;
width: 978px;
}
.breadcrumb a,
.breadcrumb a:visited,
.breadcrumb a:active {
color: #444;
text-decoration: none;
}
.breadcrumb a:hover {
color: #444;
text-decoration: underline;
}
.breadcrumb .separator {
padding: 0 3px;
}
/*******************************************************************************
*
* UI > Loader
*
* Animated loader for AJAX requests
*
*******************************************************************************/
@mixin loader_sprite_position($xoffset, $yoffset) {
background-position: sprite-position($icon-sprite, loader_sprite, $xoffset, $yoffset);
}
.loader {
width: 25px;
height: 25px;
display: none;
}
.loader b {
display: block;
width: 25px;
height: 25px;
background-image: sprite-url($icon-sprite);
}
.loader b,
.loader .f1 { @include loader_sprite_position(-10px, -10px); }
.loader .f2 { @include loader_sprite_position(-45px, -10px); }
.loader .f3 { @include loader_sprite_position(-80px, -10px); }
.loader .f4 { @include loader_sprite_position(-115px, -10px); }
.loader .f5 { @include loader_sprite_position(-150px, -10px); }
.loader .f6 { @include loader_sprite_position(-185px, -10px); }
.loader .f7 { @include loader_sprite_position(-220px, -10px); }
.loader .f8 { @include loader_sprite_position(-255px, -10px); }
geração automática de sprites
acelera o desenvolvimento.
$icon-sprite: sprite-map("icon/*.png", $spacing: 16px, $repeat: no-repeat, $layout: vertical);
$icon-sprite: sprite-map("icon/*.png", $spacing: 16px, $repeat: no-repeat, $layout: vertical);
/* Compass sprite function receives the map variable and image as arguments */
background: sprite($icon-sprite, arrow_dropdown) no-repeat;
/* Compiled CSS */
background: url(/assets/icon-s5dab8c2901.png) -40px -158px no-repeat;
função de inline image
economiza requests.
/* Compiled CSS */
background: #f5f3fb url('data:image/
png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAQCAMAAAAcVM5PAAAAGXRFWHRTb2Z0d2FyZQBBZG9
iZSBJbWFnZVJlYWR5ccllPAAAAAlQTFRF5+TW////////4qZUpQAAAAN0Uk5T//
8A18oNQQAAACBJREFUeNpiYGBgAgMGBkYog4mJXAbILAiDkVxzAAIMAEMOAPMId2OWAAAAAElFTkSuQmCC
') repeat;
/* Generates a base64 image */
background: #f5f3eb inline-image("bg_dots.png") repeat;
(seja criterioso)
dica 2
módulos: poucas linhas,
comportamentos isolados,
extensíveis, e testáveis.
estrutura base (reset, base styles)
grid
padrões
módulos
módulos contextualizados
css do módulo
/*******************************************************************************
*
* UI > Loader
*
* Animated loader for AJAX requests
*
*******************************************************************************/
@mixin loader_sprite_position($xoffset, $yoffset) {
background-position: sprite-position($icon-sprite, loader_sprite, $xoffset, $yoffset);
}
.loader {
width: 25px;
height: 25px;
display: none;
}
.loader b {
display: block;
width: 25px;
height: 25px;
background-image: sprite-url($icon-sprite);
}
.loader b,
.loader .f1 { @include loader_sprite_position(-10px, -10px); }
.loader .f2 { @include loader_sprite_position(-45px, -10px); }
.loader .f3 { @include loader_sprite_position(-80px, -10px); }
.loader .f4 { @include loader_sprite_position(-115px, -10px); }
.loader .f5 { @include loader_sprite_position(-150px, -10px); }
.loader .f6 { @include loader_sprite_position(-185px, -10px); }
.loader .f7 { @include loader_sprite_position(-220px, -10px); }
.loader .f8 { @include loader_sprite_position(-255px, -10px); }
css do módulo
contextualizado
// On ui/_buttons.scss
.bt-wrapper .loader {
position: absolute;
z-index: 4;
right: 20px;
top: 50%;
margin-top: -9px;
}
// On modules/_checkoutAddressForm.scss
.address-form .cep-input .loader {
position: absolute;
right: -33px;
top: em(29px);
}
javascript enxuto,
auto-contido.
// Implements the animated loader for AJAX requests
// Loader constructor
//
// * `placement`: Function that determines the loader's placement
ns("EDEN.ui.Loader", function (placement) {
if (!(this instanceof EDEN.ui.Loader)) {
return new EDEN.ui.Loader(placement);
}
this.frame = 1;
this.framesQty = 8;
this.stack = [];
this.animating = false;
this.$loader = $("<div class='loader'><b> </b></div>");
this.$renderer = this.$loader.find("b");
this.placement = placement;
this.init();
});
EDEN.ui.Loader.prototype = {
// Properties
// ----------
// Animation speed (in frames per second)
fps : 20,
// Fading speed
fadeSpeed : 150,
// Public methods
// --------------
testável!
describe("EDEN.ui.Loader", function () {
var Loader = EDEN.ui.Loader;
beforeEach(function () {
loadFixtures("loader.html");
});
afterEach(function () {
$("body").find(".loader").remove();
});
it("accepts instance creation without new operator", function () {
var newLoader = Loader();
expect(newLoader).toBeInstanceOf(Loader);
});
it("inits the loader on creation", function () {
var loader
, oldInit = EDEN.ui.Loader.prototype.init
;
EDEN.ui.Loader.prototype.init = jasmine.createSpy();
loader = new Loader();
expect(loader.init).toHaveBeenCalled();
EDEN.ui.Loader.prototype.init = oldInit;
});
it("appends the loader to body as a default", function () {
var loader = new Loader();
expect($("body").find(".loader").length).toEqual(1);
});
it("appends the loader through an argument function", function () {
var loader = new Loader(function ($loader) {
$("#loader-placeholder").append($loader);
});
expect($("#loader-placeholder").find(".loader").length).toEqual(1);
});
});
"Mas tem muita coisa que
não dá pra testar, né?"
"Mas testes atrapalham a
entrega do projeto, né?"
a Baby possui 1144 specs de
JavaScript até agora
falhas no jshint ou nas specs
de javascript quebram o build
dica 3
javascript desacoplado e
modularizado
mediator: ponto central de
comunicação via pub/sub
MEDIATOR
nenhum módulo tem
conhecimento do outro
MEDIATOR
Mediator, me avisa quando
sair o novo do Game of
Thrones?
Blz
MEDIATOR
Mediator, me avisa quando
sair o novo do Mythbusters?
É nóish.
MEDIATOR
Mediator, saiu um eppy novo
de Game of Thrones.
Subscribers, saiu um eppy
novo de Game of Thrones!
Ae, vou baixar, acho
que vai ser feliz e tal
=D
MEDIATOR
Mediator, saiu um eppy novo
de Mythbusters.
Subscribers, saiu um eppy
novo de Mythbusters!
Ae, vou baixar!
os módulos só conhecem
o mediator
módulos desacoplados, com
comportamentos específicos e
isolados
// Code inside ShippingAddressForm
_registerInterests : function () {
this.element.find(".cep-input")
.on("keyup paste cut", this._onCepModification.bind(this));
},
_onCepModification : function (event) {
if (this.isCepFilled()) {
EDEN.mediator.trigger("shipping-cep-change", event.target.value);
} else {
EDEN.mediator.trigger("shipping-cep-incomplete", event.target.value);
}
}
// Code inside checkoutModule
_registerInterests : function () {
EDEN.mediator.on("shipping-cep-change", this._onShippingCepChange, this);
this.shippingService.on("get-success", this._onShippingGetSuccess, this);
},
_onShippingCepChange : function (cep) {
this.shippingService.get(cep);
}
_onShippingGetSuccess : function (data) {
EDEN.mediator.trigger("shipping-rate-change", data.rate);
EDEN.mediator.trigger("delivery-estimate-change", data.estimate);
}
// Code inside purchseInfo
_registerInterests : function () {
EDEN.mediator.on("shipping-rate-change", this._onShippingRateChange, this);
EDEN.mediator.on("delivery-estimate-change", this._onDeliveryEstimateChange, this);
},
_onShippingRateChange : function (rate) {
this.updateShippingRate(rate);
},
_onDeliveryEstimateChange : function (days) {
this.updateDeliveryEstimate(days);
},
updateShippingRate : function (rate) {
var formatter = EDEN.currency.formatter;
this.element.find(".shipping-rate").text(formatter(rate));
this.shippingRate = rate;
this.updateTotal();
},
updateTotal : function () {
var total = this.subtotal + this.shippingRate,
formatter = EDEN.currency.formatter;
this.element.find(".total").text(formatter(total));
EDEN.mediator.trigger("cart-total-change", total);
}
// Code inside installmentSelector
_registerInterests : function () {
EDEN.mediator.on("cart-total-change", this._onCartTotalChange, this);
},
_onCartTotalChange : function (total) {
this.updateInstallments(total);
},
updateInstallments : function (total) {
// Updates the values
}
você não precisa saber
tudo isso de primeira.
addyosmani.com/largescalejavascript
aprenda javascript antes de
se focar em um framework.
performance
client-side
css/javascript
minification/compression
lazy-load everything! o/
sprites e imagens inlines
sass
+
não abuse de font-faces
testes a/b
isole os estilos e JS em
classes, partials e módulos
totalmente separados
<nav id="site-menu" class="site-menu">
<div class="site-menu-container">
<% if new_header? %>
<%= render "layouts/open_site_nav" %>
<% else %>
<%= render "layouts/site_nav" %>
<% end %>
<% unless new_header? %>
<%= render "layouts/search" %>
<% end %>
</div>
</nav>
/*******************************************************************************
* =Menu A
*******************************************************************************/
.site-header-old .user-menu {
position: absolute;
right: perc(261px, $SITE_WIDTH);
cursor: pointer;
width: 213px;
height: 63px;
overflow: hidden;
z-index: 600;
}
/*******************************************************************************
* =Menu B
*******************************************************************************/
.site-header-new .user-menu {
position: absolute;
right: perc(261px, $SITE_WIDTH);
width: perc(150px, $SITE_WIDTH);
height: em(63px);
overflow: hidden;
z-index: 600;
}
AB-TESTING.md - como
remover a versão perdedora
# A/B Testing on Baby Site
This document lists all A/B tests currently being run on the project, and
shortly introduces the method being used.
## Tests currently being run
### Site-wide
#### Header design version
* Test name: `header-version`
* Starts at: `ApplicationController`, on `:before_filter`
* Goal: When user goes to a success checkout page
* Ends at: `orders#success` view
* PR/Commits: [#664](https://github.com/Baby-com-br/troy/pull/664)
To remove this test:
* Remove the `new_header?` method and its `:helper_method` on
`application_controller.rb`
* Remove the `header_version` method and its `:helper_method` on
`application_controller.rb` and ALL its calls.
* Consolidate the correct `render` calls on `layouts/_header.html.erb` and
`layouts/_site_menu.html.erb`
* Remove the `site-header-<%= header_version %>` class on `layouts/_header.html.erb`
* Remove the `header-version-<%= header_version %>` class on `layouts/_head.html.erb`,
on the `<body>` tag
* Remove the `finished` call on `baby-site/app/views/orders/success.html.erb`
* On `modules/_mainSearchForm.scss`, remove the entire block related to the
loser version, and on the winner version: (1) remove the comment header about
the A/B test, (2) unprefix all selectors by removing either `.site-menu` (if
the old header won) or `.site-header` (if the new header won)
* On `layout/_user_menu.scss`, remove the entire block related to the
loser version, and on the winner version: (1) remove the comment header about
the A/B test, (2) unprefix all selectors by removing either `.site-header-new` (if
the old header won) or `.site-header-old` (if the new header won)
* On `ui/_section_header.scss`, remove the `.header-version-old .section-titles`
and `.header-version-new .section-titles` blocks, and use the winner padding
on `.section-titles`.
* On `sections/_profile.scss`, remove the `.header-version-old .profile-header .site-menu`
and `.header-version-new .profile-header .site-menu` blocks, and use the winner padding
on `.profile-header .site-menu`.
* On `layout/_main.scss`, delete the `.header-version-old .site-menu-container` block.
shiota, um dev front-end
precisa saber back-end?
fulano(a), eu preciso saber
cozinhar ou lavar roupa?
não, mas ajuda, né? ;D
você não precisa ser um
nando vieira*.
* @fnando - faz design, front-end, manja JS pacas, é um dev Ruby f*odido, e manja de SysOps
saber back-end
melhora seu código.
saber back-end
lhe dá mais controle.
saber back-end
melhora a comunicação.
quando você deixa de perguntar
apenas "como vou fazer isso" e
passa a perguntar "como vou
fazer isso da melhor maneira"...
... você está no
caminho certo.
divirta-se. sempre. =)
obrigado!slideshare.net/eshiota
github.com/eshiota
@shiota

Contenu connexe

Tendances

Criando Jogos com HTML5
Criando Jogos com HTML5Criando Jogos com HTML5
Criando Jogos com HTML5
José Farias
 

Tendances (14)

Jquery - Dicas e Truques
Jquery - Dicas e TruquesJquery - Dicas e Truques
Jquery - Dicas e Truques
 
Tutorial.yii
Tutorial.yiiTutorial.yii
Tutorial.yii
 
Aplicações rápidas para a Web com Django
Aplicações rápidas para a Web com DjangoAplicações rápidas para a Web com Django
Aplicações rápidas para a Web com Django
 
jQuery - Visão Geral
jQuery - Visão GeraljQuery - Visão Geral
jQuery - Visão Geral
 
PHP Conference Brasil 2013 - Aplicações PHP 5.4 com componentes Aura
PHP Conference Brasil 2013 - Aplicações PHP 5.4 com componentes AuraPHP Conference Brasil 2013 - Aplicações PHP 5.4 com componentes Aura
PHP Conference Brasil 2013 - Aplicações PHP 5.4 com componentes Aura
 
Curso de Introdução - PHP
Curso de Introdução - PHPCurso de Introdução - PHP
Curso de Introdução - PHP
 
Java script - funções
Java script - funçõesJava script - funções
Java script - funções
 
Java script aula 10 - angularjs
Java script   aula 10 - angularjsJava script   aula 10 - angularjs
Java script aula 10 - angularjs
 
Criando Jogos com HTML5
Criando Jogos com HTML5Criando Jogos com HTML5
Criando Jogos com HTML5
 
Angular JS, você precisa conhecer
Angular JS, você precisa conhecerAngular JS, você precisa conhecer
Angular JS, você precisa conhecer
 
RubyConfBr 2015 - Rails & Javascript: faça isso direito
RubyConfBr 2015 - Rails & Javascript: faça isso direitoRubyConfBr 2015 - Rails & Javascript: faça isso direito
RubyConfBr 2015 - Rails & Javascript: faça isso direito
 
Ecommerce, mais simples do que parece
Ecommerce, mais simples do que pareceEcommerce, mais simples do que parece
Ecommerce, mais simples do que parece
 
Hibernate efetivo (IA-2014 / Disturbing the Mind)
Hibernate efetivo (IA-2014 / Disturbing the Mind)Hibernate efetivo (IA-2014 / Disturbing the Mind)
Hibernate efetivo (IA-2014 / Disturbing the Mind)
 
Segurança e Performance WordPress
Segurança e Performance WordPressSegurança e Performance WordPress
Segurança e Performance WordPress
 

Similaire à Desafios do Desenvolvimento de Front-end em um e-commerce

Blog cozinha internacional da dona sinhá
Blog cozinha internacional da dona sinháBlog cozinha internacional da dona sinhá
Blog cozinha internacional da dona sinhá
Amebas
 
Html5 storage api
Html5 storage apiHtml5 storage api
Html5 storage api
Suissa
 
JavaScript ninja com jQuery
JavaScript ninja com jQueryJavaScript ninja com jQuery
JavaScript ninja com jQuery
Reinaldo Junior
 
Apresentação tcd
Apresentação tcdApresentação tcd
Apresentação tcd
Thata2012
 
Java mais ágil que nunca no desenvolvimento Web
Java mais ágil que nunca no desenvolvimento WebJava mais ágil que nunca no desenvolvimento Web
Java mais ágil que nunca no desenvolvimento Web
Bruno Borges
 

Similaire à Desafios do Desenvolvimento de Front-end em um e-commerce (20)

Blog cozinha internacional da dona sinhá
Blog cozinha internacional da dona sinháBlog cozinha internacional da dona sinhá
Blog cozinha internacional da dona sinhá
 
Html5 storage api
Html5 storage apiHtml5 storage api
Html5 storage api
 
Less
LessLess
Less
 
Desenvolvendo aplicacoes mobile_com_html_css_
Desenvolvendo aplicacoes mobile_com_html_css_Desenvolvendo aplicacoes mobile_com_html_css_
Desenvolvendo aplicacoes mobile_com_html_css_
 
Edição de conteúdo web usando Javascript de ponta a ponta
Edição de conteúdo web usando Javascript de ponta a pontaEdição de conteúdo web usando Javascript de ponta a ponta
Edição de conteúdo web usando Javascript de ponta a ponta
 
Introdução ao framework CakePHP
Introdução ao framework CakePHPIntrodução ao framework CakePHP
Introdução ao framework CakePHP
 
JavaScript ninja com jQuery
JavaScript ninja com jQueryJavaScript ninja com jQuery
JavaScript ninja com jQuery
 
isk-daemon: busca visual de imagens para todos
isk-daemon: busca visual de imagens para todosisk-daemon: busca visual de imagens para todos
isk-daemon: busca visual de imagens para todos
 
Apresentação tcd
Apresentação tcdApresentação tcd
Apresentação tcd
 
Desenvolvimento Android: Faça da maneira certa
Desenvolvimento Android: Faça da maneira certaDesenvolvimento Android: Faça da maneira certa
Desenvolvimento Android: Faça da maneira certa
 
don't repeat yourself front-ender
don't repeat yourself front-enderdon't repeat yourself front-ender
don't repeat yourself front-ender
 
Html5 - O futuro da Web
Html5 - O futuro da WebHtml5 - O futuro da Web
Html5 - O futuro da Web
 
Java mais ágil que nunca no desenvolvimento Web
Java mais ágil que nunca no desenvolvimento WebJava mais ágil que nunca no desenvolvimento Web
Java mais ágil que nunca no desenvolvimento Web
 
Php 07 Cakephp
Php 07 CakephpPhp 07 Cakephp
Php 07 Cakephp
 
04_Introducao_JavaScript.pdf
04_Introducao_JavaScript.pdf04_Introducao_JavaScript.pdf
04_Introducao_JavaScript.pdf
 
ITCSS - Um adeus para desorganização
ITCSS - Um adeus para desorganização ITCSS - Um adeus para desorganização
ITCSS - Um adeus para desorganização
 
TDC2011 - Desenvolvimento de jogos com Javascript e HTML5
TDC2011 - Desenvolvimento de jogos com Javascript e HTML5TDC2011 - Desenvolvimento de jogos com Javascript e HTML5
TDC2011 - Desenvolvimento de jogos com Javascript e HTML5
 
Automatizando Tarefas com o Watir-Webdriver - Case
Automatizando Tarefas com o Watir-Webdriver - CaseAutomatizando Tarefas com o Watir-Webdriver - Case
Automatizando Tarefas com o Watir-Webdriver - Case
 
Alta Performance em Aplicações Web
Alta Performance em Aplicações WebAlta Performance em Aplicações Web
Alta Performance em Aplicações Web
 
Introdução ao JavaScript
Introdução ao JavaScriptIntrodução ao JavaScript
Introdução ao JavaScript
 

Plus de Eduardo Shiota Yasuda

Plus de Eduardo Shiota Yasuda (13)

Front-end Culture @ Booking.com
Front-end Culture @ Booking.comFront-end Culture @ Booking.com
Front-end Culture @ Booking.com
 
The anatomy of an A/B Test - JSConf Colombia Workshop
The anatomy of an A/B Test - JSConf Colombia WorkshopThe anatomy of an A/B Test - JSConf Colombia Workshop
The anatomy of an A/B Test - JSConf Colombia Workshop
 
Dominating the Web Typography
Dominating the Web TypographyDominating the Web Typography
Dominating the Web Typography
 
Internationalisation: 2200+ different ways to view a website
Internationalisation: 2200+ different ways to view a websiteInternationalisation: 2200+ different ways to view a website
Internationalisation: 2200+ different ways to view a website
 
Web Audio Band - Playing with a band in your browser
Web Audio Band - Playing with a band in your browserWeb Audio Band - Playing with a band in your browser
Web Audio Band - Playing with a band in your browser
 
RetroJS - Escrevendo músicas da era 8-bits com JavaScript e Web Audio API
RetroJS - Escrevendo músicas da era 8-bits com JavaScript e Web Audio APIRetroJS - Escrevendo músicas da era 8-bits com JavaScript e Web Audio API
RetroJS - Escrevendo músicas da era 8-bits com JavaScript e Web Audio API
 
Modular and Event-Driven JavaScript
Modular and Event-Driven JavaScriptModular and Event-Driven JavaScript
Modular and Event-Driven JavaScript
 
Baby.com.br: Analisando, adaptando e melhorando a arquitetura da informação e...
Baby.com.br: Analisando, adaptando e melhorando a arquitetura da informação e...Baby.com.br: Analisando, adaptando e melhorando a arquitetura da informação e...
Baby.com.br: Analisando, adaptando e melhorando a arquitetura da informação e...
 
Arquitetura de Front-end em Aplicações de Larga Escala
Arquitetura de Front-end em Aplicações de Larga EscalaArquitetura de Front-end em Aplicações de Larga Escala
Arquitetura de Front-end em Aplicações de Larga Escala
 
Responsive Web Design e a Ubiquidade da Web
Responsive Web Design e a Ubiquidade da WebResponsive Web Design e a Ubiquidade da Web
Responsive Web Design e a Ubiquidade da Web
 
User Experience para Developers
User Experience para DevelopersUser Experience para Developers
User Experience para Developers
 
Sushi e Interfaces - PechaKucha São Paulo Vol. 8 + Inspire Japan
Sushi e Interfaces - PechaKucha São Paulo Vol. 8 + Inspire JapanSushi e Interfaces - PechaKucha São Paulo Vol. 8 + Inspire Japan
Sushi e Interfaces - PechaKucha São Paulo Vol. 8 + Inspire Japan
 
O Design e a Interface no mundo da Programação
O Design e a Interface no mundo da ProgramaçãoO Design e a Interface no mundo da Programação
O Design e a Interface no mundo da Programação
 

Desafios do Desenvolvimento de Front-end em um e-commerce