Tech Thursdays: Building Products

Building Products
A brief overview on modern web apps, tech stacks,
languages, frameworks, services, APIs and more.
Hayden Bleasel
Product Designer, Full-Stack
Developer, Entrepreneur.
Currently working on Presumi,
previously working at Palantir,
Sumry and Zookal.
@haydenbleasel on the
internet.
Nice to meet you.
Quick Question
What do you think a “Product” refers to?
Overview
1. Products
2. Web vs Mobile
3. Languages
4. Frameworks
5. Content Management Systems
6. Architecture
7. Services
8. Case Studies
Let’s just get started
I can’t stall much longer. Time to get into it.
1. Products
• Working on a website that you personally own and
focuses more on your needs? Project
• Working on a website that you or a few others own
and focuses on user needs? Product
• Working on a website that is owned by an entity
(company) and focuses users, investors and
growth? Startup
What is a Product?
• Tech startups and larger companies usually focus
on a single entity as their business operations.
• Slack, Facebook, Twitter, Spotify - all companies
focus on a single piece of ecosystem / platform
(usually released on multiple devices)
• This ecosystem is called a Product.
Tech Products
• There’s a whole new range of jobs coming out that
focus on this, namely Product Design (my job title)
• A new spin on Industrial Product Design, this sort
of Product Design focuses on the end-to-end
creation of an entity.
• Facebook, for example, is a massive product.
Visualising, understanding and designing for the
entire ecosystem at once is usually my work.
Distribution methods
• Products can come in many forms, but they’re all
part of the same ecosystem.
• Facebook released a website, an iOS app, an
Android app and a Windows Phone app (plus more)
• Which of these are the most important? Where do
you start? This entirely depends on the context.
2. Web vs Mobile
• What works best for your idea?
• What skills does your team have?
• What is your platform preference?
• Do you have the resources to do both?
• There are some ways around this…
Mobile Apps
• Efficient geolocation
• Touch and gestures
• Push notifications.
• Portability
• Fingerprint recognition
• Focus isolation
Web Apps
• Multitasking
• Screen size
• Information density
• Work environment
How do I choose?
• Are you making Uber? Mobile apps.
• Are you making Atlassian? Desktop apps.
• Are you making Facebook? Probably both.
Which do I choose?
• You’ve got a few options:
1. Create a responsive website (no native apps)
2. Hire a developer per-platform (web, iOS,
Android)
3. Wrap your website in an app frame (Cordova,
UIWebView)
4. Bind web code to native handlers (React Native)
3. Languages
• Picking a language is one of the hardest parts. Everyone
wants to jump on the new hotness.
• Go with what your team knows best. It’s better to build a
MVP in PHP that actually works, as opposed to a MVP in
Node.js that runs like shit. You can always rebuild later on.
• Some languages are reserved for back-end development,
some for front-end development. The languages you use
depend on your platform. What are your options?
• And why are there so many coming out recently?
Hipster code
iOS App
• Objective-C (Old School)
• Swift (New Hotness)
• Sometimes C++ if necessary
Android App
• XML
• Java
• Sometimes C and C++
Web App
• Back-end: PHP, Ruby, Python,
Java, JavaScript (anything can
be used to write a website
back-end basically)
• Front-end: HTML, CSS,
JavaScript (but you can
preprocess these with a bunch
of other languages)
Web App
• Back-end: PHP, Ruby, Python,
Java, JavaScript (anything can
be used to write a website
back-end basically)
• Front-end: HTML, CSS,
JavaScript (but you can
preprocess these with a bunch
of other languages)
What? I thought you said languages are separated?!
JavaScript hotness
• There’s a reason JS is the new hotness.
• TL;DR: JS was originally a web browser scripting language written
in 10 days by a guy at Netscape. Google made their own JS engine
some time later to run Chrome, called the JavaScript V8 engine.
• Some yung money™ a few years ago decided it’d be a great idea
to pull that engine out of Chrome and make it into a server side
compiler called Node.js. Same language on the server and client?
Ridiculous.
• Node.js now runs GoDaddy, Groupon, IBM, LinkedIn, Microsoft,
Netflix, PayPal, Walmart, Yahoo! and Cisco Systems.
But then…
Side note on machines
• I’m not going to argue for Mac or Windows - that
arguments been going on far too long. And also because
Mac is naturally superior.
• There’s plenty of reasons (unix-based commercial
software, build quality, cross-platform compatibility, etc.)
• I actually made the switch because of development.
Running any programming environment (Node, Rails,
PHP, etc) is super easy on Mac and super painful on
Windows because Mac is based on Unix.
4. Frameworks
• Frameworks make creating web apps easier. Native apps
don’t need them most of the time (you can make smaller
framework-module-things yourself though)
• The framework depends on the language you pick and
what you want to accomplish.
• Every language usually has a few popular frameworks
that “everyone” uses.
• You can create your own framework of course (really not
recommended) or just not use one at all.
Picking a framework
• PHP: Laravel, CodeIgniter, CakePHP, Symfony, Zend
• Ruby: Rails, Sinatra, Cuba, Volt, Lotus
• Python: Django, Flask, Pyramid, Turbogears
• Node.js: Express, Meteor, Socket, MEAN, Koa
• JavaScript: React, Angular, Ember, Meteor, jQuery,
Backbone, Knockout, Cappuccino, Chaplin, Echo, Enyo, Ext
JS, Google Web Toolkit, JavaScriptMVC, Mojito, MooTools,
Prototype, Rialto Toolkit, SproutCore, Wakanda Framework…
Why a framework?
function router (request, response) {
if(request.url === ‘/index.html’ || request.url === ‘/‘) {
response.writeHead(200, {
'Content-Type': 'text/plain'
});
response.write('Hello World!')
response.end();
}
var http = require(“http”);
var server = http.createServer(router);
server.listen(3000);
Why a framework?
var app = require(‘express’)();
app.get('/', function (req, res) {
res.send('Hello World!');
});
app.listen(3000);
Plus…
• Better wrappers to the request and response
• Support for view-engines
• Routing mechanism
• Cookies manipulation
• Basic authentication
• Much much more…
5. Content Management Systems
• Sometimes you don’t need to build a product from
ground up.
• If you want to make a store, a blog or a simple website,
you could use a CMS
• A CMS helps you manage your content on your website
and usually the website itself
• Usually really easy to install (click to install) and don’t
require much (or any) code to operate. A lot like off-the-
shelf software for websites.
Popular CMS’
• E-Commerce: Squarespace, Shopify, Magento,
WooCommerce
• Blogging: Squarespace, Wordpress, Ghost
• Marketing Site: Squarespace, Wix, Weebly
• Pieces of junk: Drupal, Joomla
FindMyPlan
• The value proposition for FindMyPlan is getting a
Sim Card to you from any country in the world to
avoid expensive roaming bills when you travel.
• There isn’t a huge tech focus - they need a system
that works for them and allows them to create
value and manage clients easily.
• They’ve moved to from a custom Angular/PHP
web-app to a Shopify site. Why?
Do what works for you
• Don’t pick a damn language because it’s hot. Pick it because you love it
and know it (or at least want to know it eventually).
• Too many startups get told what technology to use and end up
regretting it, some are next door. Don’t be pressured into building a
product a certain way, or even building a product at all.
• A tech startup should be using technology to enable the startup to
reach it’s goals, not building a custom product with super hot code for
their own satisfaction.
• Your tech doesn’t matter to the customer. What matters is how easy it
is to reach their goal.
• JavaScript is the best tho.
6. Architecture
• Picking a language, framework and/or CMS is
great but we need to talk about how these things
work.
• Back in the day it used to be super clear, but
modern technology is enabling crazy things that
don’t seem normal to traditional developers but
they work in amazing ways.
TL;DR: How apps work
Request a page Fetch things for page
Return thingsSend webpage to browser
Figure out what’s needed
Render HTML, CSS, JS,
return all the requests
HTTP Requests API requests to DB
Find things for pageReload page
Over time…
Why client-side JS is hot
Request first page Fetch things for page
Return thingsSend webpage to browser
Just grab everything
Render every page
scaffold and controllers
and return
HTTP Requests API requests to DB
Find things for pageReload page
Over time…
Sometimes you can even…
This means what exactly
• Firstly, the server’s getting a lot less hits. This means
server usage could drop dramatically causing less crashes.
• Secondly, the server isn’t doing any processing for clients.
This means everything is done on the client’s computer,
again causing less server usage.
• Third, EVERYTHING IS SO FAST BECAUSE WE DON’T
NEED TO RELOAD EVERY PAGE.
• It also means all our code is on the client’s computer to
potentially steal but I dunno, c’est la vie I suppose.
One more thing…
One more thing…
7. Services
• Services and APIs are the most useful thing when
you’re building a product.
• Basically, you don’t have to do all the work yourself.
• Products typically have a lot of things in common.
Live chat, payment gateway, error reporting.
• Smart companies identify these needs, build an
entire product out of the one focus, turn them into
drop-in widgets or APIs and monetise on them.
Examples
• Customer Support: Intercom, UserVoice, Drift
• Error Reporting: Rollbar, Sentry, Bugsnag, Airbrake
• Payment Gateway: Paypal, Stripe, Braintree
• Transactional Email: Mandrill, SendGrid, Mailgun
• Analytics: Google Analytics, Mixpanel, Kissmetrics
• A/B Testing: Optimizely, VWO, Performable
Why invest in services
• There’s a reason these services are so successful
and you should look into using them.
• They take a pain point of building products and do
it really, really well.
• You can chuck out the trash code you wrote to
handle user’s error reports and replace it with a
Rollbar installation for free!
“I’ll just write it myself”
<script>
var YOUR_API_KEY = “XXXXXXXX”;
!function(){var t;return t=window.driftt=window.drift=window.driftt||
[],t.init?void 0:t.invoked?
void(window.console&&console.error&&console.error("Drift snippet
included twice.")):(t.invoked=!
0,t.methods=["identify","track","reset","debug","show","ping","page","hi
de","off","on"],t.factory=function(e){return function(){var n;return
n=Array.prototype.slice.call(arguments),n.unshift(e),t.push(n),t}},t.met
hods.forEach(function(e){t[e]=t.factory(e)}),t.load=function(t){var
e,n,o,r;e=3e5,r=Math.ceil(new Date/
e)*e,o=document.createElement(“script”),o.type=“text/
javascript”,o.async=!0,o.crossorigin="anonymous",o.src="https://
js.driftt.com/
include/"+r+"/"+t+".js",n=document.getElementsByTagName("script")
[0],n.parentNode.insertBefore(o,n)})}
(),drift.SNIPPET_VERSION="0.2.0",drift.load(YOUR_API_KEY);
</script>
!function(t){function e(c){if(n[c])return n[c].exports;var o=n[c]={i:c,l:!1,exports:{}};return t[c].call(o.exports,o,o.exports,e),o.l=!0,o.exports}var n={};return e.m=t,e.c=n,e.i=function(t){return t},e.d=function(t,e,n){Object.defineProperty(t,e,{configurable:!
1,enumerable:!0,get:n})},e.n=function(t){var n=t&&t.__esModule?function(){return t["default"]}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="https://js.driftt.com/dist/",e(e.s=316)}
([function(t,e,n){"use strict";var c=Array.isArray;e["default"]=c},function(t,e,n){"use strict";function c(t){var e="undefined"==typeof t?"undefined":r()(t);return!!t&&("object"==e||"function"==e)}var o=n(2),r=n.n(o);e.a=c},function(t,e,n){"use strict";function
c(t){return t&&t.__esModule?t:{"default":t}}e.__esModule=!0;var o=n(238),r=c(o),i=n(237),a=c(i),M="function"==typeof a["default"]&&"symbol"==typeof r["default"]?function(t){return typeof t}:function(t){return t&&"function"==typeof
a["default"]&&t.constructor===a["default"]?"symbol":typeof t};e["default"]="function"==typeof a["default"]&&"symbol"===M(r["default"])?function(t){return"undefined"==typeof t?"undefined":M(t)}:function(t){return t&&"function"==typeof
a["default"]&&t.constructor===a["default"]?"symbol":"undefined"==typeof t?"undefined":M(t)}},function(t,e,n){"use strict";var c=n(2),o=n.n(c),r=n(86),i="object"==("undefined"==typeof self?"undefined":o()(self))&&self&&self.Object===Object&&self,a=r.a||i||
Function("return this")();e.a=a},function(t,e){var n=t.exports={version:"2.4.0"};"number"==typeof __e&&(__e=n)},function(t,e){var n=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return
this")();"number"==typeof __g&&(__g=n)},function(t,e,n){"use strict";function c(t){return n.i(i.a)(t)?n.i(o.a)(t):n.i(r.a)(t)}var o=n(76),r=n(146),i=n(11);e.a=c},function(t,e,n){var c,o,r;o=n(304),r=function(t,e){if(null==e&&(e={}),o.isSetup()&&!window.Raven&&!
window.RavenConfig)return o.captureException(t,e)},c={info:function(){var t;if(window.__DRIFTT_DEBUG__)return t=Array.prototype.slice.call(arguments),t.unshift("Drift - "),console.info.apply(console,t)},log:function(){var t;if(window.__DRIFTT_DEBUG__)return
t=Array.prototype.slice.call(arguments),t.unshift("Drift - "),console.log.apply(console,t)},warn:function(){var t;if(window.__DRIFTT_DEBUG__)return t=Array.prototype.slice.call(arguments),t.unshift("Drift - "),console.warn.apply(console,t)},error:function(t,e)
{return null==e&&(e={}),r(t,e),console.error("Drift - ",t)}},t.exports=c},function(t,e){var n={}.hasOwnProperty;t.exports=function(t,e){return n.call(t,e)}},function(t,e,n){var c=n(104),o=n(61);t.exports=function(t){return c(o(t))}},function(t,e,n){"use
strict";function c(t,e){var c=n.i(r.a)(t,e);return n.i(o.a)(c)?c:void 0}var o=n(143),r=n(171);e.a=c},function(t,e,n){"use strict";function c(t){return null!=t&&n.i(r.a)(t.length)&&!n.i(o.a)(t)}var o=n(55),r=n(56);e.a=c},function(t,e,n){t.exports=!n(13)(function()
{return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(t,e){t.exports=function(t){try{return!!t()}catch(e){return!0}}},function(t,e,n){var c=n(15),o=n(39);t.exports=n(12)?function(t,e,n){return c.f(t,e,o(1,n))}:function(t,e,n){return
t[e]=n,t}},function(t,e,n){var c=n(36),o=n(103),r=n(71),i=Object.defineProperty;e.f=n(12)?Object.defineProperty:function(t,e,n){if(c(t),e=r(e,!0),c(n),o)try{return i(t,e,n)}catch(a){}if("get"in n||"set"in n)throw TypeError("Accessors not
supported!");return"value"in n&&(t[e]=n.value),t}},function(t,e,n){var c=n(108),o=n(62);t.exports=Object.keys||function(t){return c(t,o)}},function(t,e,n){var c=n(69)("wks"),o=n(41),r=n(5).Symbol,i="function"==typeof r,a=t.exports=function(t){return c[t]||
(c[t]=i&&r[t]||(i?r:o)("Symbol."+t))};a.store=c},function(t,e,n){"use strict";function c(t,e){return t===e||t!==t&&e!==e}e.a=c},function(t,e,n){"use strict";function c(t){return!!t&&"object"==("undefined"==typeof t?"undefined":r()(t))}var
o=n(2),r=n.n(o);e.a=c},function(t,e,n){var c=n(5),o=n(4),r=n(257),i=n(14),a="prototype",M=function(t,e,n){var s,u,p,l=t&M.F,f=t&M.G,d=t&M.S,b=t&M.P,A=t&M.B,z=t&M.W,h=f?o:o[e]||(o[e]={}),O=h[a],T=f?c:d?c[e]:(c[e]||{})[a];f&&(n=e);for(s in n)u=!l&&T&&void 0!
==T[s],u&&s in h||(p=u?T[s]:n[s],h[s]=f&&"function"!=typeof T[s]?n[s]:A&&u?r(p,c):z&&T[s]==p?function(t){var e=function(e,n,c){if(this instanceof t){switch(arguments.length){case 0:return new t;case 1:return new t(e);case 2:return new t(e,n)}return new t(e,n,c)}
return t.apply(this,arguments)};return e[a]=t[a],e}(p):b&&"function"==typeof p?r(Function.call,p):p,b&&((h.virtual||(h.virtual={}))[s]=p,t&M.R&&O&&!O[s]&&i(O,s,p)))};M.F=1,M.G=2,M.S=4,M.P=8,M.B=16,M.W=32,M.U=64,M.R=128,t.exports=M},function(t,e,n){"use
strict";function c(t){var e=-1,n=t?t.length:0;for(this.clear();++e<n;){var c=t[e];this.set(c[0],c[1])}}var
o=n(184),r=n(185),i=n(186),a=n(187),M=n(188);c.prototype.clear=o.a,c.prototype["delete"]=r.a,c.prototype.get=i.a,c.prototype.has=a.a,c.prototype.set=M.a,e.a=c},function(t,e,n){"use strict";function c(t){this.__data__=new o.a(t)}var
o=n(21),r=n(199),i=n(200),a=n(201),M=n(202),s=n(203);c.prototype.clear=r.a,c.prototype["delete"]=i.a,c.prototype.get=a.a,c.prototype.has=M.a,c.prototype.set=s.a,e.a=c},function(t,e,n){"use strict";function c(t,e){for(var c=t.length;c--;)if(n.i(o.a)(t[c]
[0],e))return c;return-1}var o=n(18);e.a=c},function(t,e,n){"use strict";function c(t,e,c,r){c||(c={});for(var i=-1,a=e.length;++i<a;){var M=e[i],s=r?r(c[M],t[M],M,c,t):void 0;n.i(o.a)(c,M,void 0===s?t[M]:s)}return c}var o=n(48);e.a=c},function(t,e,n){"use
strict";function c(t,e){var c=t.__data__;return n.i(o.a)(e)?c["string"==typeof e?"string":"hash"]:c.map}var o=n(182);e.a=c},function(t,e,n){"use strict";function c(t){var e=!1;if(null!=t&&"function"!=typeof t.toString)try{e=!!(t+"")}catch(n){}return e}
e.a=c},function(t,e,n){"use strict";function c(t,e){if(n.i(i["default"])(t))return!1;var c="undefined"==typeof t?"undefined":r()(t);return!("number"!=c&&"symbol"!=c&&"boolean"!=c&&null!=t&&!n.i(a.a)(t))||(s.test(t)||!M.test(t)||null!=e&&t in Object(e))}var
o=n(2),r=n.n(o),i=n(0),a=n(31),M=/.|[(?:[^[]]*|(["'])(?:(?!1)[^]|.)*?1)]/,s=/^w*$/;e.a=c},function(t,e,n){"use strict";function c(t){var e=t&&t.constructor,n="function"==typeof e&&e.prototype||o;return t===n}var o=Object.prototype;e.a=c},function(t,e,n)
{"use strict";var c=n(10),o=n.i(c.a)(Object,"create");e.a=o},function(t,e,n){"use strict";function c(t){if("string"==typeof t||n.i(o.a)(t))return t;var e=t+"";return"0"==e&&1/t==-r?"-0":e}var o=n(31),r=1/0;e.a=c},function(t,e,n){"use strict";function c(t)
{return"symbol"==("undefined"==typeof t?"undefined":r()(t))||n.i(i.a)(t)&&s.call(t)==a}var o=n(2),r=n.n(o),i=n(19),a="[object Symbol]",M=Object.prototype,s=M.toString;e.a=c},function(t,e,n){"use strict";var c=n(149),o=n(84),r=n.i(o.a)(function(t,e,o){n.i(c.a)
(t,e,o)});e["default"]=r},function(t,e,n){"use strict";function c(t){return t&&t.__esModule?t:{"default":t}}e.__esModule=!0;var o=n(232),r=c(o);e["default"]=r["default"]||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var c in
n)Object.prototype.hasOwnProperty.call(n,c)&&(t[c]=n[c])}return t}},function(t,e,n){var
c;c=n(287),t.exports=c({INITIALIZE_LAYER:null,INITIALIZE_LAYER_SUCCESS:null,INITIALIZE_LAYER_FAIL:null,INITIALIZE_API:null,DISCONNECT_LAYER:null,RECEIVE_PACKET:null,FETCH_BOOTSTRAP:null,FETCH_BOOTSTRAP_SUCCESS:null,FETCH_BOOTSTRAP_FAIL:null,FETCH_EMBED_CONFIGURATI
ON_PENDING:null,FETCH_EMBED_CONFIGURATION_SUCCESS:null,FETCH_EMBED_CONFIGURATION_FAILURE:null,OVERRIDE_EMBED_CONFIGURATION:null,FETCH_DRIFTT_ORG:null,FETCH_DRIFTT_ORG_SUCCESS:null,FETCH_DRIFTT_ORG_FAIL:null,READY:null,GO_TO_NEW_CONVERSATION:null,GO_TO_LIST:null,GO
_TO_SELECTED_CONVERSATION:null,GO_TO_OFFLINE_FEEDBACK:null,SET_SIDERBAR_VIEW:null,FETCH_DRIFTT_USERS:null,FETCH_DRIFTT_USERS_SUCCESS:null,FETCH_DRIFTT_USERS_FAIL:null,AUTHENTICATE_END_USER:null,AUTHENTICATE_END_USER_SUCCESS:null,AUTHENTICATE_END_USER_FAIL:null,FET
CH_SEGMENT_MEMBERSHIP_PENDING:null,FETCH_SEGMENT_MEMBERSHIP_SUCCESS:null,FETCH_SEGMENT_MEMBERSHIP_FAILURE:null,FETCH_GEOLOCATION_PENDING:null,FETCH_GEOLOCATION_SUCCESS:null,FETCH_GEOLOCATION_FAILURE:null,ENROLL_IN_CAMPAIGN_PENDING:null,ENROLL_IN_CAMPAIGN_SUCCESS:n
ull,ENROLL_IN_CAMPAIGN_FAILURE:null,OPEN_SIDEBAR:null,CLOSE_SIDEBAR:null,CLOSE_SIDEBAR_WITH_TWEEN:null,CHANGE_SIDEBAR_VIEW:null,SHOW_WIDGET:null,HIDE_WIDGET:null,SHOW_WELCOME_MESSAGE:null,HIDE_WELCOME_MESSAGE:null,EXPAND_WIDGET:null,COLLAPSE_WIDGET:null,IFRAME_RES
IZE_DONE:null,IFRAME_RESIZE:null,IFRAME_OVERRIDE_SIZE:null,SHOW_TYPING_INDICATOR_BUTTON_ICON:null,OPEN_ACTIVATION_TAKEOVER:null,CLOSE_ACTIVATION_TAKEOVER:null,LIST:null,CONVERSATION:null,NEW_CONVERSATION:null,SET_IDENTIFIED_CONVERSATION:null,OFFLINE_FEEDBACK:null,
LOADING:null,LAZY_CAMPAIGN_EVALUATION:null,HANDLE_POST_MESSAGE:null,HANDLE_WINDOW_SCROLL:null,HANDLE_WINDOW_MOUSE_OUT:null,HANDLE_WINDOW_MOUSE_OVER:null,REFRESH_TARGETING:null,REFRESH_TIME_ON_PAGE:null,SUBMIT_OFFLINE_FEEDBACK:null,SUBMIT_OFFLINE_FEEDBACK_SUCCESS:n
ull,SUBMIT_OFFLINE_FEEDBACK_FAIL:null,DRIFT_ENQUEUE_MESSAGE:null,DRIFT_CREATE_MESSAGE_PENDING:null,DRIFT_CREATE_MESSAGE_SUCCESS:null,DRIFT_CREATE_MESSAGE_FAILURE:null,DRIFT_CREATE_CONVERSATION_PENDING:null,DRIFT_CREATE_CONVERSATION_SUCCESS:null,DRIFT_CREATE_CONVER
SATION_FAILURE:null,WIDGET_STATS_PENDING:null,WIDGET_STATS_SUCCESS:null,WIDGET_STATS_FAILURE:null})},function(t,e,n){var c;c={CUSTOMER_API_BASE:"https://customer.api.drift.com",CONVERSATION_API_BASE:"https://conversation.api.drift.com",EVENT_API_BASE:"https://
event.api.drift.com",EMBED_API_BASE:"https://js.driftt.com",CLIENT_ID:"f6zuizdyhxrm7r",LAYER_APP_ID:"layer:///apps/production/15806ab6-607f-11e5-817e-98d908000a42"},c.COOKIE_PATH="/",c.LAYER_API_BASE="https://api.layer.com",c.SENTRY_DSN="https://
816fa28dc7cf492ba8ffa277d90f0345@app.getsentry.com/61707",t.exports=c},function(t,e,n){var c=n(37);t.exports=function(t){if(!c(t))throw TypeError(t+" is not an object!");return t}},function(t,e){t.exports=function(t){return"object"==typeof t?null!
==t:"function"==typeof t}},function(t,e){e.f={}.propertyIsEnumerable},function(t,e){t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},function(t,e,n){var c=n(61);t.exports=function(t){return
Object(c(t))}},function(t,e){var n=0,c=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++n+c).toString(36))}},function(t,e){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(c)
{"object"==typeof window&&(n=window)}t.exports=n},function(t,e){t.exports=function(t){return t.webpackPolyfill||(t.deprecate=function(){},t.paths=[],t.children||(t.children=[]),Object.defineProperty(t,"loaded",{enumerable:!0,configurable:!1,get:function(){return
t.l}}),Object.defineProperty(t,"id",{enumerable:!0,configurable:!1,get:function(){return t.i}}),t.webpackPolyfill=1),t}},function(t,e,n){"use strict";var c=n(10),o=n(3),r=n.i(c.a)(o.a,"Map");e.a=r},function(t,e,n){"use strict";function c(t){var e=-1,n=t?t.length:
0;for(this.clear();++e<n;){var c=t[e];this.set(c[0],c[1])}}var o=n(189),r=n(190),i=n(191),a=n(192),M=n(193);c.prototype.clear=o.a,c.prototype["delete"]=r.a,c.prototype.get=i.a,c.prototype.has=a.a,c.prototype.set=M.a,e.a=c},function(t,e,n){"use strict";var
c=n(3),o=c.a.Symbol;e.a=o},function(t,e,n){"use strict";function c(t,e){for(var n=-1,c=t?t.length:0;++n<c&&e(t[n],n,t)!==!1;);return t}e.a=c},function(t,e,n){"use strict";function c(t,e,c){var r=t[e];i.call(t,e)&&n.i(o.a)(r,c)&&(void 0!==c||e in t)||(t[e]=c)}var
o=n(18),r=Object.prototype,i=r.hasOwnProperty;e.a=c},function(t,e,n){"use strict";function c(t,e,a,M,s){return t===e||(null==t||null==e||!n.i(r.a)(t)&&!n.i(i.a)(e)?t!==t&&e!==e:n.i(o.a)(t,e,c,a,M,s))}var o=n(141),r=n(1),i=n(19);e.a=c},function(t,e,n){"use
strict";function c(t){var e=new t.constructor(t.byteLength);return new o.a(e).set(new o.a(t)),e}var o=n(75);e.a=c},function(t,e,n){"use strict";function c(t,e){return e=null==e?o:e,!!e&&("number"==typeof t||r.test(t))&&t>-1&&t%1==0&&t<e}var o=9007199254740991,r=/
^(?:0|[1-9]d*)$/;e.a=c},function(t,e,n){"use strict";function c(t,e){return function(n){return t(e(n))}}e.a=c},function(t,e,n){"use strict";function c(t,e){var c=n.i(a["default"])(t)?o.a:r.a;return c(t,n.i(i.a)(e,3))}var
o=n(47),r=n(135),i=n(145),a=n(0);e["default"]=c},function(t,e,n){"use strict";function c(t){return n.i(o.a)(t)&&a.call(t,"callee")&&(!s.call(t,"callee")||M.call(t)==r)}var o=n(95),r="[object
Arguments]",i=Object.prototype,a=i.hasOwnProperty,M=i.toString,s=i.propertyIsEnumerable;e.a=c},function(t,e,n){"use strict";function c(t){var e=n.i(o.a)(t)?M.call(t):"";return e==r||e==i}var o=n(1),r="[object Function]",i="[object
GeneratorFunction]",a=Object.prototype,M=a.toString;e.a=c},function(t,e,n){"use strict";function c(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=o}var o=9007199254740991;e.a=c},function(t,e,n){"use strict";var
c=n(144),o=n(155),r=n(196),i=r.a&&r.a.isTypedArray,a=i?n.i(o.a)(i):c.a;e.a=a},function(t,e,n){var c,o,r,i,a,M,s;s=n(53)["default"],M=n(205)["default"],r=n(35).COOKIE_PATH,a=n(7),c=void
0,i="",o={ORG_ID_COOKIE_NAME:"DFTT_ORG_ID"+i,INBOX_ID_COOKIE_NAME:"DFTT_INBOX_ID"+i,END_USER_ID_COOKIE_NAME:"DFTT_END_USER_ID"+i,END_USER_EMAIL_COOKIE_NAME:"DFTT_END_USER_EMAIL"+i,END_USER_AUTH_TOKEN_COOKIE_NAME:"DFTT_END_USER_AUTH_TOKEN"+i,END_USER_PREV_BOOTSTRAP
PED_COOKIE_NAME:"DFTT_END_USER_PREV_BOOTSTRAPPED"+i,LAYER_SESSION_TOKEN_COOKIE_NAME:"DFTT_REALTIME_SESSION_TOKEN"+i,END_USER_EXTERNAL_ID_COOKIE_NAME:"driftt_eid",ANONYMOUS_ID_COOKIE_NAME:"driftt_aid",LEAD_HAS_PREV_IDENTIFIED_COOKIE_NAME:"DFTT_LEAD_HAS_PREV_IDENTIF
IED"+i,LEAD_EMAIL_COOKIE_NAME:"DFTT_LEAD_EMAIL"+i,WELCOME_MESSAGE_DISMISSED_COOKIE_NAME:"driftt_wmd"+i},t.exports=M({},o,{cookiePath:r,getIsConfigured:function(){return null!=c},cookie:function(){if(!this.getIsConfigured())throw new Error("You need to make sure
that the cookie library is configured");return c},setCookiePath:function(t){return this.cookiePath=t},getCookie:function(t){return this.cookie().get(t)},clearAllCookies:function(){s(o,function(t){return function(e){return t.cookie().remove(e,{path:t.cookiePath})}}
(this))},setCookie:function(t,e,n){return null==e?void a.warn("Tried to write an undefined value to cookie: "+t):(n=n||{},null==n.path&&(n.path=this.cookiePath),this.cookie().set(t,e,n))},clearCookie:function(t,e){return e=e||
{},null==e.path&&(e.path=this.cookiePath),this.cookie().remove(t,e)},setCookieLib:function(t){return c=t},getLeadHasPreviouslyIdentified:function(){var t,e,n,c;if(n=!1,c=this.getCookie(o.LEAD_HAS_PREV_IDENTIFIED_COOKIE_NAME))try{n=JSON.parse(c)}catch(e)
{t=e,this.setCookie(o.LEAD_HAS_PREV_IDENTIFIED_COOKIE_NAME,!1)}return n},getUserHasPreviouslyBootstrapped:function(){var t,e,n,c;if(n=!1,c=this.getCookie(o.END_USER_PREV_BOOTSTRAPPED_COOKIE_NAME))try{n=JSON.parse(c)}catch(e)
{t=e,this.setCookie(o.END_USER_PREV_BOOTSTRAPPED_COOKIE_NAME,!1)}return n}})},function(t,e,n){var c,o,r,i,a,M,s=[].slice;r=n(53)["default"],i=n(0)["default"],a=n(32)["default"],c=n(7),t.exports.combineHeaders=function(t){return a.apply(null,
[{}].concat(s.call(t)))},t.exports.getJSONContentTypeHeader=function(){return{"Content-Type":"application/json"}},t.exports.getFormContentTypeHeader=function(){return{"Content-Type":"application/x-www-form-urlencoded"}},t.exports.getLayerHeader=function()
{return{Accept:"application/vnd.layer+json; version=1.0"}},t.exports.encodeQueryData=function(t){var e,n,c;n=[];for(e in t)c=t[e],i(c)?r(c,function(t){return n.push(encodeURIComponent(e)+"="+encodeURIComponent(t))}):null!=c&&n.push(encodeURIComponent(e)
+"="+encodeURIComponent(c));return n.join("&")},o=function(t){var e,n;if(200<=(n=t.status)&&n<300)return t;throw e=new Error(t.statusText),e.response=t,e},M=function(t){switch(t.status){case 101:case 204:case 205:case 304:return;default:return
t.json()}},t.exports.createFetch=function(t,e){return fetch(t,e).then(o).then(M)["catch"](function(n){throw c.error(n,{request:{url:t,options:e},response:n.response}),n})},t.exports.throwIfFailed=function(t){if("TypeError"===(null!=t?t.name:void 0))throw new
TypeError(t.statusText)}},function(t,e,n){var c,o,r,i,a,M,s,u,p,l,f,d,b,A,z,h,O,T,L,N,m,q,v,W,g,_,S,E;L=n(113),m=n(294),v=n(74),o=n(7),N=n(292),T=n(97).mergeWithInitialState,r=n(215)["default"],c="Drift.Targeting",l=function(){var t;return
g(),W(document.referrer||"",p(location.hostname)),t=z(),T({visits:O(),referrer:t,ad:f(),device:d(),page:A(t.previousPage),scroll:h(),os:b(),timezone:N.tz.guess(),locale:(navigator.language||navigator.browserLanguage).split("-")
[0],userAgent:navigator.userAgent,query:q(document.location.href||"")})},O=function(){return{first:M("firstVisit")||0,last:M("lastVisit")||0,count:M("numberOfVisits")||0,sessionCount:M("numberOfSessions")||0}},g=function(){var t,e;if(e=Math.round((new
Date).getTime()/1e3),M("firstVisit")||_("firstVisit",e),t=M("lastVisit"),_("lastVisit",e),_("numberOfVisits",(M("numberOfVisits")||0)+1),null==t||L().diff(1e3*t,"hours")>1)return _("numberOfSessions",(M("numberOfSessions")||0)+1)},f=function(){var t;return
t=q(document.location.href),s(t)},s=function(t){return{source:t.utm_source,name:t.utm_campaign,medium:t.utm_medium,content:t.utm_content,term:t.utm_term}},z=function()
{return{original:M("originalReferrer"),previous:M("previousPage"),current:M("currentReferrer"),currentDomain:M("currentReferrerDomain"),currentSearch:M("referrerSearchTerm")}},W=function(t,e){var n,c,o;return n=t.replace(/.*?:///,"").replace(/www./
i,"").toLowerCase().substr(0,150),c=n.replace(/(.*?)/.*/,"$1"),o=q(t),t?(-1===c.indexOf(e)&&(M("originalReferrer")||_("originalReferrer",n),_("currentReferrer",n),_("currentReferrerDomain",c),_("searchTerm",o.query||o.q||o.search)),_("previousPage",n)):
(_("currentReferrer",""),_("referrerDomain",""),_("previousPage",""))},d=function(){return u(navigator.userAgent)},u=function(t){return t.match(/ipad/i)?"tablet":t.match(/(mobi|phone|ipod|blackberry|docomo)/i)?"mobile":t.match(/(ipad|kindle|android)/
i)?"tablet":"desktop"},A=function(t)
{return{path:a(document.location.pathname||""),hostname:document.location.hostname||"",url:a(document.location.href||""),title:document.title||"",search:document.location.search||"",referrer:t,href:document.location.href||""}},b=function(){return v?
{architecture:v.os.architecture,family:v.os.family,version:v.os.version,name:v.os.toString()}:{name:void 0,version:void 0,architecture:void 0,family:void 0}},h=function(){var t,e,n,c;try{return
c=window.innerHeight,t=document.body.scrollHeight,n=document.body.scrollTop,e=(n+c)/t,{windowHeight:c,scrollHeight:t,scrollTop:n,scrollPct:e}}catch(r){return o.warn("Unable to scroll values from window")}},M=function(t){if("undefined"==typeof document||
null===document||"undefined"==typeof localStorage||null===localStorage)return void o.log("Unable to get from localStorage "+t);try{return JSON.parse(localStorage.getItem(c+"."+t))}catch(e){return o.log("Error getting/parsing targeting -> "+t)}},_=function(t,e)
{if("undefined"==typeof document||null===document||"undefined"==typeof localStorage||null===localStorage)return void o.log("Unable to set from localStorage "+t+" -> "+e);if(null!=e)try{localStorage.setItem(c+"."+t,JSON.stringify(e))}catch(n){o.log("Error storing
targeting "+t+" -> "+e)}return e},i=function(){var t,e,n,i,a,M,s,u;if("undefined"==typeof document||null===document||"undefined"==typeof localStorage||null===localStorage)return void o.log("Unable to clear localStorage");for(a=[],t=e=0,s=localStorage.length;0<=s?
e<s:e>s;t=0<=s?++e:--e)a.push(localStorage.key(t));for(u=[],n=0,M=a.length;n<M;n++)i=a[n],r(i,c)?u.push(localStorage.removeItem(i)):u.push(void 0);return u},q=function(t){var e,n,c,o,r,i,a,M,s;if(r={},!t)return r;if(t+="",i=-1===t.indexOf("?")?t:t.split("?")[1],!
i)return r;for(a=i.split("&"),e=0,n=a.length;e<n;e++)o=a[e],M=o.split("="),c=decodeURIComponent(M[0]).toLowerCase(),s=decodeURIComponent(M[1]),r[c]=s;return r},p=function(t){var
e,n,c,o,r,i;for(e="dc=tld",c=t.split("."),o=r=c.length-1;r>=0;o=r+=-1)if(i=c[o],n=c.slice(o).join("."),document.cookie=e+";domain=."+n+";",document.cookie.indexOf(e)>-1)return document.cookie=e.split("=")[0]+"=;domain=."+n+";expires=Thu, 01 Jan 1970 00:00:01
GMT;",n;return t},a=function(t){var e,n;try{t=m(t)}catch(n){e=n,o.warn("Could not parse URL '"+t+"'"),t=""}return t.replace(/https?:///,"").replace(/^www./,"")},S=function(t){return parseInt(t)},E=function(t){return parseInt(t)/
100},t.exports={normalizeUrl:a,toInt:S,toPct:E,load:l,clear:i,parseQuery:q}},function(t,e){t.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},function(t,e)
{t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(t,e){t.exports={}},function(t,e){t.exports=!0},function(t,e,n){var c=n(36),o=n(266),r=n(62),i=n(68)("IE_PROTO"),a=function()
{},M="prototype",s=function(){var t,e=n(102)("iframe"),c=r.length,o="<",i=">";for(e.style.display="none",n(259).appendChild(e),e.src="javascript:",t=e.contentWindow.document,t.open(),t.write(o+"script"+i+"document.F=Object"+o+"/
script"+i),t.close(),s=t.F;c--;)delete s[M][r[c]];return s()};t.exports=Object.create||function(t,e){var n;return null!==t?(a[M]=c(t),n=new a,a[M]=null,n[i]=t):n=s(),void 0===e?n:o(n,e)}},function(t,e){e.f=Object.getOwnPropertySymbols},function(t,e,n){var
c=n(15).f,o=n(8),r=n(17)("toStringTag");t.exports=function(t,e,n){t&&!o(t=n?t:t.prototype,r)&&c(t,r,{configurable:!0,value:e})}},function(t,e,n){var c=n(69)("keys"),o=n(41);t.exports=function(t){return c[t]||(c[t]=o(t))}},function(t,e,n){var c=n(5),o="__core-
js_shared__",r=c[o]||(c[o]={});t.exports=function(t){return r[t]||(r[t]={})}},function(t,e){var n=Math.ceil,c=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?c:n)(t)}},function(t,e,n){var c=n(37);t.exports=function(t,e){if(!c(t))return t;var
n,o;if(e&&"function"==typeof(n=t.toString)&&!c(o=n.call(t)))return o;if("function"==typeof(n=t.valueOf)&&!c(o=n.call(t)))return o;if(!e&&"function"==typeof(n=t.toString)&&!c(o=n.call(t)))return o;throw TypeError("Can't convert object to primitive
value")}},function(t,e,n){var c=n(5),o=n(4),r=n(64),i=n(73),a=n(15).f;t.exports=function(t){var e=o.Symbol||(o.Symbol=r?{}:c.Symbol||{});"_"==t.charAt(0)||t in e||a(e,t,{value:i.f(t)})}},function(t,e,n){e.f=n(17)},function(t,e,n){(function(t,c){var o;(function()
{"use strict";function r(t){return t=String(t),t.charAt(0).toUpperCase()+t.slice(1)}function i(t,e,n){var c={"10.0":"10",6.4:"10 Technical Preview",6.3:"8.1",6.2:"8",6.1:"7 / Server 2008 R2","6.0":"Vista / Server 2008",5.2:"XP 64-bit / Server 2003",5.1:"XP",
5.01:"2000 SP1","5.0":"2000","4.0":"NT","4.90":"ME"};return e&&n&&/^Win/i.test(t)&&!/^Windows Phone /i.test(t)&&(c=c[/[d.]+$/.exec(t)])&&(t="Windows "+c),t=String(t),e&&n&&(t=t.replace(RegExp(e,"i"),n)),t=M(t.replace(/ ce$/i," CE").replace(/bhpw/
i,"web").replace(/bMacintoshb/,"Mac OS").replace(/_PowerPCb/i," OS").replace(/b(OS X) [^ d]+/i,"$1").replace(/bMac (OS X)b/,"$1").replace(//(d)/," $1").replace(/_/g,".").replace(/(?: BePC|[ .]*fc[ d.]+)$/i,"").replace(/bx86.64b/gi,"x86_64").replace(/
8. Case Studies
• Every product is built differently.
• Every product has had complete rebuilds.
• Every product has a storied history.
• Here’s a couple of them…
Facebook
• Back-end originally built with PHP, likely with a basic WAMP setup (Windows,
Apache, MySQL, PHP). Front-end naturally rendered HTML (rendered by
PHP), CSS and JS. No sense of business logic separation (too much effort).
• Now, front-end is still written in PHP-backed HTML but runs through their
weird crazy “HipHop” compiler: PHP -> AST -> C++ -> G++ -> x64. Business
logic exposed through Thrift in PHP, C++ or Java based on service. Also
running Java on custom application servers. Database is MySQL, caching is
done through memcached (300TB at a time) and HBase. Offline processing
done through Hadoop and Hive. Data logging through Scribe, stored in HDFS
through MapReduce. Page acceleration through BigPipe (pipelining logic).
Varnish Cache for HTTP proxying. User storage through Haystack.
• Messenger is another thing entirely with all sorts of insane shit like
infrastructure sharding, dynamic cluster management and cell structures.
Based on Epoll server developed in Erlang and Thrift.
Twitter
• Twitter has always run on Rails but originally based on
regular Ruby. MySQL database, temporarily sharded.
• “Search” replaced Rails with Java server called Blender.
• “Messages” replaced Rails with Starling (Ruby) then
replaced with Scala.
• Database replaces MySQL with Gizzard and FlockDB
• Lots of custom stuff - Snowflake, Rockdove, Firehose.
Presumi
• Back-end in Express and Handlebars (hybrid rendering engine), front-
end originally in Handlebars and jQuery. Database on MongoDB.
• Live chat with Drift, error reporting with Rollbar, analytics with Google
Analytics, payments with Stripe, email with Sendgrid, A/B with
Optimizely.
• Replaced front-end with jQuery with React, Handlebars with JSX.
• Actual build process takes my JSX, transpiles through Babel (+React
plugin) and Webpack and spits out JS. Basically I write super hot
futuristic code and it converts it to pleb browser code.
• Currently replacing internal app hybrid-rendering with full JS rendering
and implementing React properly, reducing server usage by >50%.
That’s all I’ve got
Thanks for listening. I’m here for questions :)
1 of 51

Recommended

Scalable front-end architecture with Bootstrap 3 + Atomic CSS by
Scalable front-end architecture with Bootstrap 3 + Atomic CSSScalable front-end architecture with Bootstrap 3 + Atomic CSS
Scalable front-end architecture with Bootstrap 3 + Atomic CSSHayden Bleasel
1.2K views40 slides
How to write good quality code by
How to write good quality codeHow to write good quality code
How to write good quality codeHayden Bleasel
882 views50 slides
Designing for Growth, Academy Xi by
Designing for Growth, Academy XiDesigning for Growth, Academy Xi
Designing for Growth, Academy XiHayden Bleasel
718 views11 slides
Pearls and Must-Have Tools for the Modern Web / .NET Developer by
Pearls and Must-Have Tools for the Modern Web / .NET DeveloperPearls and Must-Have Tools for the Modern Web / .NET Developer
Pearls and Must-Have Tools for the Modern Web / .NET DeveloperOfer Zelig
1K views72 slides
Untangling the web week1 by
Untangling the web week1Untangling the web week1
Untangling the web week1Derek Jacoby
491 views55 slides
Untangling spring week1 by
Untangling spring week1Untangling spring week1
Untangling spring week1Derek Jacoby
447 views53 slides

More Related Content

What's hot

Untangling spring week2 by
Untangling spring week2Untangling spring week2
Untangling spring week2Derek Jacoby
438 views44 slides
Untangling the web week 2 - SEO by
Untangling the web week 2 - SEOUntangling the web week 2 - SEO
Untangling the web week 2 - SEODerek Jacoby
386 views55 slides
11 Amazing things I Learnt At Word Camp Sydney 2014 by
11 Amazing things I Learnt At Word Camp Sydney 201411 Amazing things I Learnt At Word Camp Sydney 2014
11 Amazing things I Learnt At Word Camp Sydney 2014WordPressBrisbane
476 views58 slides
Untangling spring week6 by
Untangling spring week6Untangling spring week6
Untangling spring week6Derek Jacoby
364 views17 slides
Untangling the web - week 3 by
Untangling the web - week 3Untangling the web - week 3
Untangling the web - week 3Derek Jacoby
249 views24 slides
Code & Design Your First Website (Downtown Los Angeles) by
Code & Design Your First Website (Downtown Los Angeles)Code & Design Your First Website (Downtown Los Angeles)
Code & Design Your First Website (Downtown Los Angeles)Thinkful
333 views45 slides

What's hot(20)

Untangling spring week2 by Derek Jacoby
Untangling spring week2Untangling spring week2
Untangling spring week2
Derek Jacoby438 views
Untangling the web week 2 - SEO by Derek Jacoby
Untangling the web week 2 - SEOUntangling the web week 2 - SEO
Untangling the web week 2 - SEO
Derek Jacoby386 views
11 Amazing things I Learnt At Word Camp Sydney 2014 by WordPressBrisbane
11 Amazing things I Learnt At Word Camp Sydney 201411 Amazing things I Learnt At Word Camp Sydney 2014
11 Amazing things I Learnt At Word Camp Sydney 2014
WordPressBrisbane476 views
Untangling spring week6 by Derek Jacoby
Untangling spring week6Untangling spring week6
Untangling spring week6
Derek Jacoby364 views
Untangling the web - week 3 by Derek Jacoby
Untangling the web - week 3Untangling the web - week 3
Untangling the web - week 3
Derek Jacoby249 views
Code & Design Your First Website (Downtown Los Angeles) by Thinkful
Code & Design Your First Website (Downtown Los Angeles)Code & Design Your First Website (Downtown Los Angeles)
Code & Design Your First Website (Downtown Los Angeles)
Thinkful333 views
Food blogging at UBC by Tris Hussey
Food blogging at UBCFood blogging at UBC
Food blogging at UBC
Tris Hussey628 views
Modern Front-End Development by mwrather
Modern Front-End DevelopmentModern Front-End Development
Modern Front-End Development
mwrather8K views
Responsive Design Workflow (Breaking Development Conference 2012 Orlando) by Stephen Hay
Responsive Design Workflow (Breaking Development Conference 2012 Orlando)Responsive Design Workflow (Breaking Development Conference 2012 Orlando)
Responsive Design Workflow (Breaking Development Conference 2012 Orlando)
Stephen Hay42.2K views
Getting started with dev tools (atl) by Thinkful
Getting started with dev tools (atl)Getting started with dev tools (atl)
Getting started with dev tools (atl)
Thinkful80 views
CatalystX::SimpleLogin by Tomas Doran
CatalystX::SimpleLoginCatalystX::SimpleLogin
CatalystX::SimpleLogin
Tomas Doran688 views
There Are No “Buts” in Progressive Enhancement [Øredev 2015] by Aaron Gustafson
There Are No “Buts” in Progressive Enhancement [Øredev 2015]There Are No “Buts” in Progressive Enhancement [Øredev 2015]
There Are No “Buts” in Progressive Enhancement [Øredev 2015]
Aaron Gustafson54.9K views
Responsive Web Design for Universal Access 2016 by Kate Walser
Responsive Web Design for Universal Access 2016Responsive Web Design for Universal Access 2016
Responsive Web Design for Universal Access 2016
Kate Walser620 views
High performance java script why everything youve been taught is wrong by Tao Gao
High performance java script why everything youve been taught is wrongHigh performance java script why everything youve been taught is wrong
High performance java script why everything youve been taught is wrong
Tao Gao1.1K views
Word press workshop powerpoint by erezwe
Word press workshop   powerpointWord press workshop   powerpoint
Word press workshop powerpoint
erezwe364 views
Building a real time html5 app for mobile devices by Tony Abou-Assaleh
Building a real time html5 app for mobile devicesBuilding a real time html5 app for mobile devices
Building a real time html5 app for mobile devices
Tony Abou-Assaleh1.2K views

Similar to Tech Thursdays: Building Products

2014 Picking a Platform by Anand Kulkarni by
2014 Picking a Platform by Anand Kulkarni2014 Picking a Platform by Anand Kulkarni
2014 Picking a Platform by Anand KulkarniEuropean Innovation Academy
1.2K views19 slides
Mobile ECM with JavaScript - JSE 2011 by
Mobile ECM with JavaScript - JSE 2011Mobile ECM with JavaScript - JSE 2011
Mobile ECM with JavaScript - JSE 2011Nuxeo
865 views56 slides
Intro to tech stacks bonny by
Intro to tech stacks bonnyIntro to tech stacks bonny
Intro to tech stacks bonnyLama K Banna
86 views27 slides
Joomla as a mobile App backend - ideas, examples and experiences by
Joomla as a mobile App backend - ideas, examples and experiencesJoomla as a mobile App backend - ideas, examples and experiences
Joomla as a mobile App backend - ideas, examples and experiencesAndy_Gaskell
2.7K views62 slides
LATEST_TRENDS_IN_WEBSITE_DEVELOPMENT.pptx by
LATEST_TRENDS_IN_WEBSITE_DEVELOPMENT.pptxLATEST_TRENDS_IN_WEBSITE_DEVELOPMENT.pptx
LATEST_TRENDS_IN_WEBSITE_DEVELOPMENT.pptxchitrachauhan21
51 views28 slides
HTML5 or Android for Mobile Development? by
HTML5 or Android for Mobile Development?HTML5 or Android for Mobile Development?
HTML5 or Android for Mobile Development?Reto Meier
23.6K views55 slides

Similar to Tech Thursdays: Building Products(20)

Mobile ECM with JavaScript - JSE 2011 by Nuxeo
Mobile ECM with JavaScript - JSE 2011Mobile ECM with JavaScript - JSE 2011
Mobile ECM with JavaScript - JSE 2011
Nuxeo865 views
Intro to tech stacks bonny by Lama K Banna
Intro to tech stacks bonnyIntro to tech stacks bonny
Intro to tech stacks bonny
Lama K Banna86 views
Joomla as a mobile App backend - ideas, examples and experiences by Andy_Gaskell
Joomla as a mobile App backend - ideas, examples and experiencesJoomla as a mobile App backend - ideas, examples and experiences
Joomla as a mobile App backend - ideas, examples and experiences
Andy_Gaskell2.7K views
LATEST_TRENDS_IN_WEBSITE_DEVELOPMENT.pptx by chitrachauhan21
LATEST_TRENDS_IN_WEBSITE_DEVELOPMENT.pptxLATEST_TRENDS_IN_WEBSITE_DEVELOPMENT.pptx
LATEST_TRENDS_IN_WEBSITE_DEVELOPMENT.pptx
chitrachauhan2151 views
HTML5 or Android for Mobile Development? by Reto Meier
HTML5 or Android for Mobile Development?HTML5 or Android for Mobile Development?
HTML5 or Android for Mobile Development?
Reto Meier23.6K views
Meetup. Technologies Intro for Non-Tech People by IT Arena
Meetup. Technologies Intro for Non-Tech PeopleMeetup. Technologies Intro for Non-Tech People
Meetup. Technologies Intro for Non-Tech People
IT Arena138 views
Week01 jan19 introductionto_php by Jeanho Chu
Week01 jan19 introductionto_phpWeek01 jan19 introductionto_php
Week01 jan19 introductionto_php
Jeanho Chu340 views
Stapling and patching the web of now - ForwardJS3, San Francisco by Christian Heilmann
Stapling and patching the web of now - ForwardJS3, San FranciscoStapling and patching the web of now - ForwardJS3, San Francisco
Stapling and patching the web of now - ForwardJS3, San Francisco
Christian Heilmann12.9K views
How Open Source / Open Technology Could Help On Your Project by Wan Leung Wong
How Open Source / Open Technology Could Help On Your ProjectHow Open Source / Open Technology Could Help On Your Project
How Open Source / Open Technology Could Help On Your Project
Wan Leung Wong517 views
30 Skills to Master to Become a Senior Software Engineer by Sean Coates
30 Skills to Master to Become a Senior Software Engineer30 Skills to Master to Become a Senior Software Engineer
30 Skills to Master to Become a Senior Software Engineer
Sean Coates775 views
The front end toolkit by samuel-holt
The front end toolkitThe front end toolkit
The front end toolkit
samuel-holt1.2K views
What is cool with Domino V10, Proton and Node.JS, and why would I use it in ... by Heiko Voigt
What is cool with Domino V10, Proton and Node.JS, and why would I use it in ...What is cool with Domino V10, Proton and Node.JS, and why would I use it in ...
What is cool with Domino V10, Proton and Node.JS, and why would I use it in ...
Heiko Voigt843 views
Week01 jan19 introductionto_php by Jeanho Chu
Week01 jan19 introductionto_phpWeek01 jan19 introductionto_php
Week01 jan19 introductionto_php
Jeanho Chu201 views
Native vs HTML by ludlola
Native vs HTMLNative vs HTML
Native vs HTML
ludlola295 views
The Mobile Web Revealed For The Java Developer by balunasj
The Mobile Web Revealed For The Java DeveloperThe Mobile Web Revealed For The Java Developer
The Mobile Web Revealed For The Java Developer
balunasj682 views

Recently uploaded

Module-1, Chapter-2 Data Types, Variables, and Arrays by
Module-1, Chapter-2 Data Types, Variables, and ArraysModule-1, Chapter-2 Data Types, Variables, and Arrays
Module-1, Chapter-2 Data Types, Variables, and ArraysDemian Antony D'Mello
9 views44 slides
ASSIGNMENTS ON FUZZY LOGIC IN TRAFFIC FLOW.pdf by
ASSIGNMENTS ON FUZZY LOGIC IN TRAFFIC FLOW.pdfASSIGNMENTS ON FUZZY LOGIC IN TRAFFIC FLOW.pdf
ASSIGNMENTS ON FUZZY LOGIC IN TRAFFIC FLOW.pdfAlhamduKure
10 views11 slides
Design of Structures and Foundations for Vibrating Machines, Arya-ONeill-Pinc... by
Design of Structures and Foundations for Vibrating Machines, Arya-ONeill-Pinc...Design of Structures and Foundations for Vibrating Machines, Arya-ONeill-Pinc...
Design of Structures and Foundations for Vibrating Machines, Arya-ONeill-Pinc...csegroupvn
16 views210 slides
Ansari: Practical experiences with an LLM-based Islamic Assistant by
Ansari: Practical experiences with an LLM-based Islamic AssistantAnsari: Practical experiences with an LLM-based Islamic Assistant
Ansari: Practical experiences with an LLM-based Islamic AssistantM Waleed Kadous
12 views29 slides
Renewal Projects in Seismic Construction by
Renewal Projects in Seismic ConstructionRenewal Projects in Seismic Construction
Renewal Projects in Seismic ConstructionEngineering & Seismic Construction
8 views8 slides
2023Dec ASU Wang NETR Group Research Focus and Facility Overview.pptx by
2023Dec ASU Wang NETR Group Research Focus and Facility Overview.pptx2023Dec ASU Wang NETR Group Research Focus and Facility Overview.pptx
2023Dec ASU Wang NETR Group Research Focus and Facility Overview.pptxlwang78
314 views19 slides

Recently uploaded(20)

ASSIGNMENTS ON FUZZY LOGIC IN TRAFFIC FLOW.pdf by AlhamduKure
ASSIGNMENTS ON FUZZY LOGIC IN TRAFFIC FLOW.pdfASSIGNMENTS ON FUZZY LOGIC IN TRAFFIC FLOW.pdf
ASSIGNMENTS ON FUZZY LOGIC IN TRAFFIC FLOW.pdf
AlhamduKure10 views
Design of Structures and Foundations for Vibrating Machines, Arya-ONeill-Pinc... by csegroupvn
Design of Structures and Foundations for Vibrating Machines, Arya-ONeill-Pinc...Design of Structures and Foundations for Vibrating Machines, Arya-ONeill-Pinc...
Design of Structures and Foundations for Vibrating Machines, Arya-ONeill-Pinc...
csegroupvn16 views
Ansari: Practical experiences with an LLM-based Islamic Assistant by M Waleed Kadous
Ansari: Practical experiences with an LLM-based Islamic AssistantAnsari: Practical experiences with an LLM-based Islamic Assistant
Ansari: Practical experiences with an LLM-based Islamic Assistant
M Waleed Kadous12 views
2023Dec ASU Wang NETR Group Research Focus and Facility Overview.pptx by lwang78
2023Dec ASU Wang NETR Group Research Focus and Facility Overview.pptx2023Dec ASU Wang NETR Group Research Focus and Facility Overview.pptx
2023Dec ASU Wang NETR Group Research Focus and Facility Overview.pptx
lwang78314 views
Web Dev Session 1.pptx by VedVekhande
Web Dev Session 1.pptxWeb Dev Session 1.pptx
Web Dev Session 1.pptx
VedVekhande23 views
Field Programmable Gate Arrays : Architecture by Usha Mehta
Field Programmable Gate Arrays : ArchitectureField Programmable Gate Arrays : Architecture
Field Programmable Gate Arrays : Architecture
Usha Mehta23 views
IRJET-Productivity Enhancement Using Method Study.pdf by SahilBavdhankar
IRJET-Productivity Enhancement Using Method Study.pdfIRJET-Productivity Enhancement Using Method Study.pdf
IRJET-Productivity Enhancement Using Method Study.pdf
SahilBavdhankar10 views
AWS Certified Solutions Architect Associate Exam Guide_published .pdf by Kiran Kumar Malik
AWS Certified Solutions Architect Associate Exam Guide_published .pdfAWS Certified Solutions Architect Associate Exam Guide_published .pdf
AWS Certified Solutions Architect Associate Exam Guide_published .pdf
taylor-2005-classical-mechanics.pdf by ArturoArreola10
taylor-2005-classical-mechanics.pdftaylor-2005-classical-mechanics.pdf
taylor-2005-classical-mechanics.pdf
ArturoArreola1037 views
Trust Metric-Based Anomaly Detection via Deep Deterministic Policy Gradient R... by IJCNCJournal
Trust Metric-Based Anomaly Detection via Deep Deterministic Policy Gradient R...Trust Metric-Based Anomaly Detection via Deep Deterministic Policy Gradient R...
Trust Metric-Based Anomaly Detection via Deep Deterministic Policy Gradient R...
IJCNCJournal5 views
MongoDB.pdf by ArthyR3
MongoDB.pdfMongoDB.pdf
MongoDB.pdf
ArthyR351 views

Tech Thursdays: Building Products

  • 1. Building Products A brief overview on modern web apps, tech stacks, languages, frameworks, services, APIs and more.
  • 2. Hayden Bleasel Product Designer, Full-Stack Developer, Entrepreneur. Currently working on Presumi, previously working at Palantir, Sumry and Zookal. @haydenbleasel on the internet. Nice to meet you.
  • 3. Quick Question What do you think a “Product” refers to?
  • 4. Overview 1. Products 2. Web vs Mobile 3. Languages 4. Frameworks 5. Content Management Systems 6. Architecture 7. Services 8. Case Studies
  • 5. Let’s just get started I can’t stall much longer. Time to get into it.
  • 6. 1. Products • Working on a website that you personally own and focuses more on your needs? Project • Working on a website that you or a few others own and focuses on user needs? Product • Working on a website that is owned by an entity (company) and focuses users, investors and growth? Startup
  • 7. What is a Product? • Tech startups and larger companies usually focus on a single entity as their business operations. • Slack, Facebook, Twitter, Spotify - all companies focus on a single piece of ecosystem / platform (usually released on multiple devices) • This ecosystem is called a Product.
  • 8. Tech Products • There’s a whole new range of jobs coming out that focus on this, namely Product Design (my job title) • A new spin on Industrial Product Design, this sort of Product Design focuses on the end-to-end creation of an entity. • Facebook, for example, is a massive product. Visualising, understanding and designing for the entire ecosystem at once is usually my work.
  • 9. Distribution methods • Products can come in many forms, but they’re all part of the same ecosystem. • Facebook released a website, an iOS app, an Android app and a Windows Phone app (plus more) • Which of these are the most important? Where do you start? This entirely depends on the context.
  • 10. 2. Web vs Mobile • What works best for your idea? • What skills does your team have? • What is your platform preference? • Do you have the resources to do both? • There are some ways around this…
  • 11. Mobile Apps • Efficient geolocation • Touch and gestures • Push notifications. • Portability • Fingerprint recognition • Focus isolation
  • 12. Web Apps • Multitasking • Screen size • Information density • Work environment
  • 13. How do I choose? • Are you making Uber? Mobile apps. • Are you making Atlassian? Desktop apps. • Are you making Facebook? Probably both.
  • 14. Which do I choose? • You’ve got a few options: 1. Create a responsive website (no native apps) 2. Hire a developer per-platform (web, iOS, Android) 3. Wrap your website in an app frame (Cordova, UIWebView) 4. Bind web code to native handlers (React Native)
  • 15. 3. Languages • Picking a language is one of the hardest parts. Everyone wants to jump on the new hotness. • Go with what your team knows best. It’s better to build a MVP in PHP that actually works, as opposed to a MVP in Node.js that runs like shit. You can always rebuild later on. • Some languages are reserved for back-end development, some for front-end development. The languages you use depend on your platform. What are your options? • And why are there so many coming out recently?
  • 17. iOS App • Objective-C (Old School) • Swift (New Hotness) • Sometimes C++ if necessary
  • 18. Android App • XML • Java • Sometimes C and C++
  • 19. Web App • Back-end: PHP, Ruby, Python, Java, JavaScript (anything can be used to write a website back-end basically) • Front-end: HTML, CSS, JavaScript (but you can preprocess these with a bunch of other languages)
  • 20. Web App • Back-end: PHP, Ruby, Python, Java, JavaScript (anything can be used to write a website back-end basically) • Front-end: HTML, CSS, JavaScript (but you can preprocess these with a bunch of other languages) What? I thought you said languages are separated?!
  • 21. JavaScript hotness • There’s a reason JS is the new hotness. • TL;DR: JS was originally a web browser scripting language written in 10 days by a guy at Netscape. Google made their own JS engine some time later to run Chrome, called the JavaScript V8 engine. • Some yung money™ a few years ago decided it’d be a great idea to pull that engine out of Chrome and make it into a server side compiler called Node.js. Same language on the server and client? Ridiculous. • Node.js now runs GoDaddy, Groupon, IBM, LinkedIn, Microsoft, Netflix, PayPal, Walmart, Yahoo! and Cisco Systems.
  • 23. Side note on machines • I’m not going to argue for Mac or Windows - that arguments been going on far too long. And also because Mac is naturally superior. • There’s plenty of reasons (unix-based commercial software, build quality, cross-platform compatibility, etc.) • I actually made the switch because of development. Running any programming environment (Node, Rails, PHP, etc) is super easy on Mac and super painful on Windows because Mac is based on Unix.
  • 24. 4. Frameworks • Frameworks make creating web apps easier. Native apps don’t need them most of the time (you can make smaller framework-module-things yourself though) • The framework depends on the language you pick and what you want to accomplish. • Every language usually has a few popular frameworks that “everyone” uses. • You can create your own framework of course (really not recommended) or just not use one at all.
  • 25. Picking a framework • PHP: Laravel, CodeIgniter, CakePHP, Symfony, Zend • Ruby: Rails, Sinatra, Cuba, Volt, Lotus • Python: Django, Flask, Pyramid, Turbogears • Node.js: Express, Meteor, Socket, MEAN, Koa • JavaScript: React, Angular, Ember, Meteor, jQuery, Backbone, Knockout, Cappuccino, Chaplin, Echo, Enyo, Ext JS, Google Web Toolkit, JavaScriptMVC, Mojito, MooTools, Prototype, Rialto Toolkit, SproutCore, Wakanda Framework…
  • 26. Why a framework? function router (request, response) { if(request.url === ‘/index.html’ || request.url === ‘/‘) { response.writeHead(200, { 'Content-Type': 'text/plain' }); response.write('Hello World!') response.end(); } var http = require(“http”); var server = http.createServer(router); server.listen(3000);
  • 27. Why a framework? var app = require(‘express’)(); app.get('/', function (req, res) { res.send('Hello World!'); }); app.listen(3000);
  • 28. Plus… • Better wrappers to the request and response • Support for view-engines • Routing mechanism • Cookies manipulation • Basic authentication • Much much more…
  • 29. 5. Content Management Systems • Sometimes you don’t need to build a product from ground up. • If you want to make a store, a blog or a simple website, you could use a CMS • A CMS helps you manage your content on your website and usually the website itself • Usually really easy to install (click to install) and don’t require much (or any) code to operate. A lot like off-the- shelf software for websites.
  • 30. Popular CMS’ • E-Commerce: Squarespace, Shopify, Magento, WooCommerce • Blogging: Squarespace, Wordpress, Ghost • Marketing Site: Squarespace, Wix, Weebly • Pieces of junk: Drupal, Joomla
  • 31. FindMyPlan • The value proposition for FindMyPlan is getting a Sim Card to you from any country in the world to avoid expensive roaming bills when you travel. • There isn’t a huge tech focus - they need a system that works for them and allows them to create value and manage clients easily. • They’ve moved to from a custom Angular/PHP web-app to a Shopify site. Why?
  • 32. Do what works for you • Don’t pick a damn language because it’s hot. Pick it because you love it and know it (or at least want to know it eventually). • Too many startups get told what technology to use and end up regretting it, some are next door. Don’t be pressured into building a product a certain way, or even building a product at all. • A tech startup should be using technology to enable the startup to reach it’s goals, not building a custom product with super hot code for their own satisfaction. • Your tech doesn’t matter to the customer. What matters is how easy it is to reach their goal. • JavaScript is the best tho.
  • 33. 6. Architecture • Picking a language, framework and/or CMS is great but we need to talk about how these things work. • Back in the day it used to be super clear, but modern technology is enabling crazy things that don’t seem normal to traditional developers but they work in amazing ways.
  • 34. TL;DR: How apps work Request a page Fetch things for page Return thingsSend webpage to browser Figure out what’s needed Render HTML, CSS, JS, return all the requests HTTP Requests API requests to DB Find things for pageReload page
  • 36. Why client-side JS is hot Request first page Fetch things for page Return thingsSend webpage to browser Just grab everything Render every page scaffold and controllers and return HTTP Requests API requests to DB Find things for pageReload page
  • 38. Sometimes you can even…
  • 39. This means what exactly • Firstly, the server’s getting a lot less hits. This means server usage could drop dramatically causing less crashes. • Secondly, the server isn’t doing any processing for clients. This means everything is done on the client’s computer, again causing less server usage. • Third, EVERYTHING IS SO FAST BECAUSE WE DON’T NEED TO RELOAD EVERY PAGE. • It also means all our code is on the client’s computer to potentially steal but I dunno, c’est la vie I suppose.
  • 42. 7. Services • Services and APIs are the most useful thing when you’re building a product. • Basically, you don’t have to do all the work yourself. • Products typically have a lot of things in common. Live chat, payment gateway, error reporting. • Smart companies identify these needs, build an entire product out of the one focus, turn them into drop-in widgets or APIs and monetise on them.
  • 43. Examples • Customer Support: Intercom, UserVoice, Drift • Error Reporting: Rollbar, Sentry, Bugsnag, Airbrake • Payment Gateway: Paypal, Stripe, Braintree • Transactional Email: Mandrill, SendGrid, Mailgun • Analytics: Google Analytics, Mixpanel, Kissmetrics • A/B Testing: Optimizely, VWO, Performable
  • 44. Why invest in services • There’s a reason these services are so successful and you should look into using them. • They take a pain point of building products and do it really, really well. • You can chuck out the trash code you wrote to handle user’s error reports and replace it with a Rollbar installation for free!
  • 45. “I’ll just write it myself” <script> var YOUR_API_KEY = “XXXXXXXX”; !function(){var t;return t=window.driftt=window.drift=window.driftt|| [],t.init?void 0:t.invoked? void(window.console&&console.error&&console.error("Drift snippet included twice.")):(t.invoked=! 0,t.methods=["identify","track","reset","debug","show","ping","page","hi de","off","on"],t.factory=function(e){return function(){var n;return n=Array.prototype.slice.call(arguments),n.unshift(e),t.push(n),t}},t.met hods.forEach(function(e){t[e]=t.factory(e)}),t.load=function(t){var e,n,o,r;e=3e5,r=Math.ceil(new Date/ e)*e,o=document.createElement(“script”),o.type=“text/ javascript”,o.async=!0,o.crossorigin="anonymous",o.src="https:// js.driftt.com/ include/"+r+"/"+t+".js",n=document.getElementsByTagName("script") [0],n.parentNode.insertBefore(o,n)})} (),drift.SNIPPET_VERSION="0.2.0",drift.load(YOUR_API_KEY); </script>
  • 46. !function(t){function e(c){if(n[c])return n[c].exports;var o=n[c]={i:c,l:!1,exports:{}};return t[c].call(o.exports,o,o.exports,e),o.l=!0,o.exports}var n={};return e.m=t,e.c=n,e.i=function(t){return t},e.d=function(t,e,n){Object.defineProperty(t,e,{configurable:! 1,enumerable:!0,get:n})},e.n=function(t){var n=t&&t.__esModule?function(){return t["default"]}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="https://js.driftt.com/dist/",e(e.s=316)} ([function(t,e,n){"use strict";var c=Array.isArray;e["default"]=c},function(t,e,n){"use strict";function c(t){var e="undefined"==typeof t?"undefined":r()(t);return!!t&&("object"==e||"function"==e)}var o=n(2),r=n.n(o);e.a=c},function(t,e,n){"use strict";function c(t){return t&&t.__esModule?t:{"default":t}}e.__esModule=!0;var o=n(238),r=c(o),i=n(237),a=c(i),M="function"==typeof a["default"]&&"symbol"==typeof r["default"]?function(t){return typeof t}:function(t){return t&&"function"==typeof a["default"]&&t.constructor===a["default"]?"symbol":typeof t};e["default"]="function"==typeof a["default"]&&"symbol"===M(r["default"])?function(t){return"undefined"==typeof t?"undefined":M(t)}:function(t){return t&&"function"==typeof a["default"]&&t.constructor===a["default"]?"symbol":"undefined"==typeof t?"undefined":M(t)}},function(t,e,n){"use strict";var c=n(2),o=n.n(c),r=n(86),i="object"==("undefined"==typeof self?"undefined":o()(self))&&self&&self.Object===Object&&self,a=r.a||i|| Function("return this")();e.a=a},function(t,e){var n=t.exports={version:"2.4.0"};"number"==typeof __e&&(__e=n)},function(t,e){var n=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},function(t,e,n){"use strict";function c(t){return n.i(i.a)(t)?n.i(o.a)(t):n.i(r.a)(t)}var o=n(76),r=n(146),i=n(11);e.a=c},function(t,e,n){var c,o,r;o=n(304),r=function(t,e){if(null==e&&(e={}),o.isSetup()&&!window.Raven&&! window.RavenConfig)return o.captureException(t,e)},c={info:function(){var t;if(window.__DRIFTT_DEBUG__)return t=Array.prototype.slice.call(arguments),t.unshift("Drift - "),console.info.apply(console,t)},log:function(){var t;if(window.__DRIFTT_DEBUG__)return t=Array.prototype.slice.call(arguments),t.unshift("Drift - "),console.log.apply(console,t)},warn:function(){var t;if(window.__DRIFTT_DEBUG__)return t=Array.prototype.slice.call(arguments),t.unshift("Drift - "),console.warn.apply(console,t)},error:function(t,e) {return null==e&&(e={}),r(t,e),console.error("Drift - ",t)}},t.exports=c},function(t,e){var n={}.hasOwnProperty;t.exports=function(t,e){return n.call(t,e)}},function(t,e,n){var c=n(104),o=n(61);t.exports=function(t){return c(o(t))}},function(t,e,n){"use strict";function c(t,e){var c=n.i(r.a)(t,e);return n.i(o.a)(c)?c:void 0}var o=n(143),r=n(171);e.a=c},function(t,e,n){"use strict";function c(t){return null!=t&&n.i(r.a)(t.length)&&!n.i(o.a)(t)}var o=n(55),r=n(56);e.a=c},function(t,e,n){t.exports=!n(13)(function() {return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(t,e){t.exports=function(t){try{return!!t()}catch(e){return!0}}},function(t,e,n){var c=n(15),o=n(39);t.exports=n(12)?function(t,e,n){return c.f(t,e,o(1,n))}:function(t,e,n){return t[e]=n,t}},function(t,e,n){var c=n(36),o=n(103),r=n(71),i=Object.defineProperty;e.f=n(12)?Object.defineProperty:function(t,e,n){if(c(t),e=r(e,!0),c(n),o)try{return i(t,e,n)}catch(a){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(t[e]=n.value),t}},function(t,e,n){var c=n(108),o=n(62);t.exports=Object.keys||function(t){return c(t,o)}},function(t,e,n){var c=n(69)("wks"),o=n(41),r=n(5).Symbol,i="function"==typeof r,a=t.exports=function(t){return c[t]|| (c[t]=i&&r[t]||(i?r:o)("Symbol."+t))};a.store=c},function(t,e,n){"use strict";function c(t,e){return t===e||t!==t&&e!==e}e.a=c},function(t,e,n){"use strict";function c(t){return!!t&&"object"==("undefined"==typeof t?"undefined":r()(t))}var o=n(2),r=n.n(o);e.a=c},function(t,e,n){var c=n(5),o=n(4),r=n(257),i=n(14),a="prototype",M=function(t,e,n){var s,u,p,l=t&M.F,f=t&M.G,d=t&M.S,b=t&M.P,A=t&M.B,z=t&M.W,h=f?o:o[e]||(o[e]={}),O=h[a],T=f?c:d?c[e]:(c[e]||{})[a];f&&(n=e);for(s in n)u=!l&&T&&void 0! ==T[s],u&&s in h||(p=u?T[s]:n[s],h[s]=f&&"function"!=typeof T[s]?n[s]:A&&u?r(p,c):z&&T[s]==p?function(t){var e=function(e,n,c){if(this instanceof t){switch(arguments.length){case 0:return new t;case 1:return new t(e);case 2:return new t(e,n)}return new t(e,n,c)} return t.apply(this,arguments)};return e[a]=t[a],e}(p):b&&"function"==typeof p?r(Function.call,p):p,b&&((h.virtual||(h.virtual={}))[s]=p,t&M.R&&O&&!O[s]&&i(O,s,p)))};M.F=1,M.G=2,M.S=4,M.P=8,M.B=16,M.W=32,M.U=64,M.R=128,t.exports=M},function(t,e,n){"use strict";function c(t){var e=-1,n=t?t.length:0;for(this.clear();++e<n;){var c=t[e];this.set(c[0],c[1])}}var o=n(184),r=n(185),i=n(186),a=n(187),M=n(188);c.prototype.clear=o.a,c.prototype["delete"]=r.a,c.prototype.get=i.a,c.prototype.has=a.a,c.prototype.set=M.a,e.a=c},function(t,e,n){"use strict";function c(t){this.__data__=new o.a(t)}var o=n(21),r=n(199),i=n(200),a=n(201),M=n(202),s=n(203);c.prototype.clear=r.a,c.prototype["delete"]=i.a,c.prototype.get=a.a,c.prototype.has=M.a,c.prototype.set=s.a,e.a=c},function(t,e,n){"use strict";function c(t,e){for(var c=t.length;c--;)if(n.i(o.a)(t[c] [0],e))return c;return-1}var o=n(18);e.a=c},function(t,e,n){"use strict";function c(t,e,c,r){c||(c={});for(var i=-1,a=e.length;++i<a;){var M=e[i],s=r?r(c[M],t[M],M,c,t):void 0;n.i(o.a)(c,M,void 0===s?t[M]:s)}return c}var o=n(48);e.a=c},function(t,e,n){"use strict";function c(t,e){var c=t.__data__;return n.i(o.a)(e)?c["string"==typeof e?"string":"hash"]:c.map}var o=n(182);e.a=c},function(t,e,n){"use strict";function c(t){var e=!1;if(null!=t&&"function"!=typeof t.toString)try{e=!!(t+"")}catch(n){}return e} e.a=c},function(t,e,n){"use strict";function c(t,e){if(n.i(i["default"])(t))return!1;var c="undefined"==typeof t?"undefined":r()(t);return!("number"!=c&&"symbol"!=c&&"boolean"!=c&&null!=t&&!n.i(a.a)(t))||(s.test(t)||!M.test(t)||null!=e&&t in Object(e))}var o=n(2),r=n.n(o),i=n(0),a=n(31),M=/.|[(?:[^[]]*|(["'])(?:(?!1)[^]|.)*?1)]/,s=/^w*$/;e.a=c},function(t,e,n){"use strict";function c(t){var e=t&&t.constructor,n="function"==typeof e&&e.prototype||o;return t===n}var o=Object.prototype;e.a=c},function(t,e,n) {"use strict";var c=n(10),o=n.i(c.a)(Object,"create");e.a=o},function(t,e,n){"use strict";function c(t){if("string"==typeof t||n.i(o.a)(t))return t;var e=t+"";return"0"==e&&1/t==-r?"-0":e}var o=n(31),r=1/0;e.a=c},function(t,e,n){"use strict";function c(t) {return"symbol"==("undefined"==typeof t?"undefined":r()(t))||n.i(i.a)(t)&&s.call(t)==a}var o=n(2),r=n.n(o),i=n(19),a="[object Symbol]",M=Object.prototype,s=M.toString;e.a=c},function(t,e,n){"use strict";var c=n(149),o=n(84),r=n.i(o.a)(function(t,e,o){n.i(c.a) (t,e,o)});e["default"]=r},function(t,e,n){"use strict";function c(t){return t&&t.__esModule?t:{"default":t}}e.__esModule=!0;var o=n(232),r=c(o);e["default"]=r["default"]||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var c in n)Object.prototype.hasOwnProperty.call(n,c)&&(t[c]=n[c])}return t}},function(t,e,n){var c;c=n(287),t.exports=c({INITIALIZE_LAYER:null,INITIALIZE_LAYER_SUCCESS:null,INITIALIZE_LAYER_FAIL:null,INITIALIZE_API:null,DISCONNECT_LAYER:null,RECEIVE_PACKET:null,FETCH_BOOTSTRAP:null,FETCH_BOOTSTRAP_SUCCESS:null,FETCH_BOOTSTRAP_FAIL:null,FETCH_EMBED_CONFIGURATI ON_PENDING:null,FETCH_EMBED_CONFIGURATION_SUCCESS:null,FETCH_EMBED_CONFIGURATION_FAILURE:null,OVERRIDE_EMBED_CONFIGURATION:null,FETCH_DRIFTT_ORG:null,FETCH_DRIFTT_ORG_SUCCESS:null,FETCH_DRIFTT_ORG_FAIL:null,READY:null,GO_TO_NEW_CONVERSATION:null,GO_TO_LIST:null,GO _TO_SELECTED_CONVERSATION:null,GO_TO_OFFLINE_FEEDBACK:null,SET_SIDERBAR_VIEW:null,FETCH_DRIFTT_USERS:null,FETCH_DRIFTT_USERS_SUCCESS:null,FETCH_DRIFTT_USERS_FAIL:null,AUTHENTICATE_END_USER:null,AUTHENTICATE_END_USER_SUCCESS:null,AUTHENTICATE_END_USER_FAIL:null,FET CH_SEGMENT_MEMBERSHIP_PENDING:null,FETCH_SEGMENT_MEMBERSHIP_SUCCESS:null,FETCH_SEGMENT_MEMBERSHIP_FAILURE:null,FETCH_GEOLOCATION_PENDING:null,FETCH_GEOLOCATION_SUCCESS:null,FETCH_GEOLOCATION_FAILURE:null,ENROLL_IN_CAMPAIGN_PENDING:null,ENROLL_IN_CAMPAIGN_SUCCESS:n ull,ENROLL_IN_CAMPAIGN_FAILURE:null,OPEN_SIDEBAR:null,CLOSE_SIDEBAR:null,CLOSE_SIDEBAR_WITH_TWEEN:null,CHANGE_SIDEBAR_VIEW:null,SHOW_WIDGET:null,HIDE_WIDGET:null,SHOW_WELCOME_MESSAGE:null,HIDE_WELCOME_MESSAGE:null,EXPAND_WIDGET:null,COLLAPSE_WIDGET:null,IFRAME_RES IZE_DONE:null,IFRAME_RESIZE:null,IFRAME_OVERRIDE_SIZE:null,SHOW_TYPING_INDICATOR_BUTTON_ICON:null,OPEN_ACTIVATION_TAKEOVER:null,CLOSE_ACTIVATION_TAKEOVER:null,LIST:null,CONVERSATION:null,NEW_CONVERSATION:null,SET_IDENTIFIED_CONVERSATION:null,OFFLINE_FEEDBACK:null, LOADING:null,LAZY_CAMPAIGN_EVALUATION:null,HANDLE_POST_MESSAGE:null,HANDLE_WINDOW_SCROLL:null,HANDLE_WINDOW_MOUSE_OUT:null,HANDLE_WINDOW_MOUSE_OVER:null,REFRESH_TARGETING:null,REFRESH_TIME_ON_PAGE:null,SUBMIT_OFFLINE_FEEDBACK:null,SUBMIT_OFFLINE_FEEDBACK_SUCCESS:n ull,SUBMIT_OFFLINE_FEEDBACK_FAIL:null,DRIFT_ENQUEUE_MESSAGE:null,DRIFT_CREATE_MESSAGE_PENDING:null,DRIFT_CREATE_MESSAGE_SUCCESS:null,DRIFT_CREATE_MESSAGE_FAILURE:null,DRIFT_CREATE_CONVERSATION_PENDING:null,DRIFT_CREATE_CONVERSATION_SUCCESS:null,DRIFT_CREATE_CONVER SATION_FAILURE:null,WIDGET_STATS_PENDING:null,WIDGET_STATS_SUCCESS:null,WIDGET_STATS_FAILURE:null})},function(t,e,n){var c;c={CUSTOMER_API_BASE:"https://customer.api.drift.com",CONVERSATION_API_BASE:"https://conversation.api.drift.com",EVENT_API_BASE:"https:// event.api.drift.com",EMBED_API_BASE:"https://js.driftt.com",CLIENT_ID:"f6zuizdyhxrm7r",LAYER_APP_ID:"layer:///apps/production/15806ab6-607f-11e5-817e-98d908000a42"},c.COOKIE_PATH="/",c.LAYER_API_BASE="https://api.layer.com",c.SENTRY_DSN="https:// 816fa28dc7cf492ba8ffa277d90f0345@app.getsentry.com/61707",t.exports=c},function(t,e,n){var c=n(37);t.exports=function(t){if(!c(t))throw TypeError(t+" is not an object!");return t}},function(t,e){t.exports=function(t){return"object"==typeof t?null! ==t:"function"==typeof t}},function(t,e){e.f={}.propertyIsEnumerable},function(t,e){t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},function(t,e,n){var c=n(61);t.exports=function(t){return Object(c(t))}},function(t,e){var n=0,c=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++n+c).toString(36))}},function(t,e){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(c) {"object"==typeof window&&(n=window)}t.exports=n},function(t,e){t.exports=function(t){return t.webpackPolyfill||(t.deprecate=function(){},t.paths=[],t.children||(t.children=[]),Object.defineProperty(t,"loaded",{enumerable:!0,configurable:!1,get:function(){return t.l}}),Object.defineProperty(t,"id",{enumerable:!0,configurable:!1,get:function(){return t.i}}),t.webpackPolyfill=1),t}},function(t,e,n){"use strict";var c=n(10),o=n(3),r=n.i(c.a)(o.a,"Map");e.a=r},function(t,e,n){"use strict";function c(t){var e=-1,n=t?t.length: 0;for(this.clear();++e<n;){var c=t[e];this.set(c[0],c[1])}}var o=n(189),r=n(190),i=n(191),a=n(192),M=n(193);c.prototype.clear=o.a,c.prototype["delete"]=r.a,c.prototype.get=i.a,c.prototype.has=a.a,c.prototype.set=M.a,e.a=c},function(t,e,n){"use strict";var c=n(3),o=c.a.Symbol;e.a=o},function(t,e,n){"use strict";function c(t,e){for(var n=-1,c=t?t.length:0;++n<c&&e(t[n],n,t)!==!1;);return t}e.a=c},function(t,e,n){"use strict";function c(t,e,c){var r=t[e];i.call(t,e)&&n.i(o.a)(r,c)&&(void 0!==c||e in t)||(t[e]=c)}var o=n(18),r=Object.prototype,i=r.hasOwnProperty;e.a=c},function(t,e,n){"use strict";function c(t,e,a,M,s){return t===e||(null==t||null==e||!n.i(r.a)(t)&&!n.i(i.a)(e)?t!==t&&e!==e:n.i(o.a)(t,e,c,a,M,s))}var o=n(141),r=n(1),i=n(19);e.a=c},function(t,e,n){"use strict";function c(t){var e=new t.constructor(t.byteLength);return new o.a(e).set(new o.a(t)),e}var o=n(75);e.a=c},function(t,e,n){"use strict";function c(t,e){return e=null==e?o:e,!!e&&("number"==typeof t||r.test(t))&&t>-1&&t%1==0&&t<e}var o=9007199254740991,r=/ ^(?:0|[1-9]d*)$/;e.a=c},function(t,e,n){"use strict";function c(t,e){return function(n){return t(e(n))}}e.a=c},function(t,e,n){"use strict";function c(t,e){var c=n.i(a["default"])(t)?o.a:r.a;return c(t,n.i(i.a)(e,3))}var o=n(47),r=n(135),i=n(145),a=n(0);e["default"]=c},function(t,e,n){"use strict";function c(t){return n.i(o.a)(t)&&a.call(t,"callee")&&(!s.call(t,"callee")||M.call(t)==r)}var o=n(95),r="[object Arguments]",i=Object.prototype,a=i.hasOwnProperty,M=i.toString,s=i.propertyIsEnumerable;e.a=c},function(t,e,n){"use strict";function c(t){var e=n.i(o.a)(t)?M.call(t):"";return e==r||e==i}var o=n(1),r="[object Function]",i="[object GeneratorFunction]",a=Object.prototype,M=a.toString;e.a=c},function(t,e,n){"use strict";function c(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=o}var o=9007199254740991;e.a=c},function(t,e,n){"use strict";var c=n(144),o=n(155),r=n(196),i=r.a&&r.a.isTypedArray,a=i?n.i(o.a)(i):c.a;e.a=a},function(t,e,n){var c,o,r,i,a,M,s;s=n(53)["default"],M=n(205)["default"],r=n(35).COOKIE_PATH,a=n(7),c=void 0,i="",o={ORG_ID_COOKIE_NAME:"DFTT_ORG_ID"+i,INBOX_ID_COOKIE_NAME:"DFTT_INBOX_ID"+i,END_USER_ID_COOKIE_NAME:"DFTT_END_USER_ID"+i,END_USER_EMAIL_COOKIE_NAME:"DFTT_END_USER_EMAIL"+i,END_USER_AUTH_TOKEN_COOKIE_NAME:"DFTT_END_USER_AUTH_TOKEN"+i,END_USER_PREV_BOOTSTRAP PED_COOKIE_NAME:"DFTT_END_USER_PREV_BOOTSTRAPPED"+i,LAYER_SESSION_TOKEN_COOKIE_NAME:"DFTT_REALTIME_SESSION_TOKEN"+i,END_USER_EXTERNAL_ID_COOKIE_NAME:"driftt_eid",ANONYMOUS_ID_COOKIE_NAME:"driftt_aid",LEAD_HAS_PREV_IDENTIFIED_COOKIE_NAME:"DFTT_LEAD_HAS_PREV_IDENTIF IED"+i,LEAD_EMAIL_COOKIE_NAME:"DFTT_LEAD_EMAIL"+i,WELCOME_MESSAGE_DISMISSED_COOKIE_NAME:"driftt_wmd"+i},t.exports=M({},o,{cookiePath:r,getIsConfigured:function(){return null!=c},cookie:function(){if(!this.getIsConfigured())throw new Error("You need to make sure that the cookie library is configured");return c},setCookiePath:function(t){return this.cookiePath=t},getCookie:function(t){return this.cookie().get(t)},clearAllCookies:function(){s(o,function(t){return function(e){return t.cookie().remove(e,{path:t.cookiePath})}} (this))},setCookie:function(t,e,n){return null==e?void a.warn("Tried to write an undefined value to cookie: "+t):(n=n||{},null==n.path&&(n.path=this.cookiePath),this.cookie().set(t,e,n))},clearCookie:function(t,e){return e=e|| {},null==e.path&&(e.path=this.cookiePath),this.cookie().remove(t,e)},setCookieLib:function(t){return c=t},getLeadHasPreviouslyIdentified:function(){var t,e,n,c;if(n=!1,c=this.getCookie(o.LEAD_HAS_PREV_IDENTIFIED_COOKIE_NAME))try{n=JSON.parse(c)}catch(e) {t=e,this.setCookie(o.LEAD_HAS_PREV_IDENTIFIED_COOKIE_NAME,!1)}return n},getUserHasPreviouslyBootstrapped:function(){var t,e,n,c;if(n=!1,c=this.getCookie(o.END_USER_PREV_BOOTSTRAPPED_COOKIE_NAME))try{n=JSON.parse(c)}catch(e) {t=e,this.setCookie(o.END_USER_PREV_BOOTSTRAPPED_COOKIE_NAME,!1)}return n}})},function(t,e,n){var c,o,r,i,a,M,s=[].slice;r=n(53)["default"],i=n(0)["default"],a=n(32)["default"],c=n(7),t.exports.combineHeaders=function(t){return a.apply(null, [{}].concat(s.call(t)))},t.exports.getJSONContentTypeHeader=function(){return{"Content-Type":"application/json"}},t.exports.getFormContentTypeHeader=function(){return{"Content-Type":"application/x-www-form-urlencoded"}},t.exports.getLayerHeader=function() {return{Accept:"application/vnd.layer+json; version=1.0"}},t.exports.encodeQueryData=function(t){var e,n,c;n=[];for(e in t)c=t[e],i(c)?r(c,function(t){return n.push(encodeURIComponent(e)+"="+encodeURIComponent(t))}):null!=c&&n.push(encodeURIComponent(e) +"="+encodeURIComponent(c));return n.join("&")},o=function(t){var e,n;if(200<=(n=t.status)&&n<300)return t;throw e=new Error(t.statusText),e.response=t,e},M=function(t){switch(t.status){case 101:case 204:case 205:case 304:return;default:return t.json()}},t.exports.createFetch=function(t,e){return fetch(t,e).then(o).then(M)["catch"](function(n){throw c.error(n,{request:{url:t,options:e},response:n.response}),n})},t.exports.throwIfFailed=function(t){if("TypeError"===(null!=t?t.name:void 0))throw new TypeError(t.statusText)}},function(t,e,n){var c,o,r,i,a,M,s,u,p,l,f,d,b,A,z,h,O,T,L,N,m,q,v,W,g,_,S,E;L=n(113),m=n(294),v=n(74),o=n(7),N=n(292),T=n(97).mergeWithInitialState,r=n(215)["default"],c="Drift.Targeting",l=function(){var t;return g(),W(document.referrer||"",p(location.hostname)),t=z(),T({visits:O(),referrer:t,ad:f(),device:d(),page:A(t.previousPage),scroll:h(),os:b(),timezone:N.tz.guess(),locale:(navigator.language||navigator.browserLanguage).split("-") [0],userAgent:navigator.userAgent,query:q(document.location.href||"")})},O=function(){return{first:M("firstVisit")||0,last:M("lastVisit")||0,count:M("numberOfVisits")||0,sessionCount:M("numberOfSessions")||0}},g=function(){var t,e;if(e=Math.round((new Date).getTime()/1e3),M("firstVisit")||_("firstVisit",e),t=M("lastVisit"),_("lastVisit",e),_("numberOfVisits",(M("numberOfVisits")||0)+1),null==t||L().diff(1e3*t,"hours")>1)return _("numberOfSessions",(M("numberOfSessions")||0)+1)},f=function(){var t;return t=q(document.location.href),s(t)},s=function(t){return{source:t.utm_source,name:t.utm_campaign,medium:t.utm_medium,content:t.utm_content,term:t.utm_term}},z=function() {return{original:M("originalReferrer"),previous:M("previousPage"),current:M("currentReferrer"),currentDomain:M("currentReferrerDomain"),currentSearch:M("referrerSearchTerm")}},W=function(t,e){var n,c,o;return n=t.replace(/.*?:///,"").replace(/www./ i,"").toLowerCase().substr(0,150),c=n.replace(/(.*?)/.*/,"$1"),o=q(t),t?(-1===c.indexOf(e)&&(M("originalReferrer")||_("originalReferrer",n),_("currentReferrer",n),_("currentReferrerDomain",c),_("searchTerm",o.query||o.q||o.search)),_("previousPage",n)): (_("currentReferrer",""),_("referrerDomain",""),_("previousPage",""))},d=function(){return u(navigator.userAgent)},u=function(t){return t.match(/ipad/i)?"tablet":t.match(/(mobi|phone|ipod|blackberry|docomo)/i)?"mobile":t.match(/(ipad|kindle|android)/ i)?"tablet":"desktop"},A=function(t) {return{path:a(document.location.pathname||""),hostname:document.location.hostname||"",url:a(document.location.href||""),title:document.title||"",search:document.location.search||"",referrer:t,href:document.location.href||""}},b=function(){return v? {architecture:v.os.architecture,family:v.os.family,version:v.os.version,name:v.os.toString()}:{name:void 0,version:void 0,architecture:void 0,family:void 0}},h=function(){var t,e,n,c;try{return c=window.innerHeight,t=document.body.scrollHeight,n=document.body.scrollTop,e=(n+c)/t,{windowHeight:c,scrollHeight:t,scrollTop:n,scrollPct:e}}catch(r){return o.warn("Unable to scroll values from window")}},M=function(t){if("undefined"==typeof document|| null===document||"undefined"==typeof localStorage||null===localStorage)return void o.log("Unable to get from localStorage "+t);try{return JSON.parse(localStorage.getItem(c+"."+t))}catch(e){return o.log("Error getting/parsing targeting -> "+t)}},_=function(t,e) {if("undefined"==typeof document||null===document||"undefined"==typeof localStorage||null===localStorage)return void o.log("Unable to set from localStorage "+t+" -> "+e);if(null!=e)try{localStorage.setItem(c+"."+t,JSON.stringify(e))}catch(n){o.log("Error storing targeting "+t+" -> "+e)}return e},i=function(){var t,e,n,i,a,M,s,u;if("undefined"==typeof document||null===document||"undefined"==typeof localStorage||null===localStorage)return void o.log("Unable to clear localStorage");for(a=[],t=e=0,s=localStorage.length;0<=s? e<s:e>s;t=0<=s?++e:--e)a.push(localStorage.key(t));for(u=[],n=0,M=a.length;n<M;n++)i=a[n],r(i,c)?u.push(localStorage.removeItem(i)):u.push(void 0);return u},q=function(t){var e,n,c,o,r,i,a,M,s;if(r={},!t)return r;if(t+="",i=-1===t.indexOf("?")?t:t.split("?")[1],! i)return r;for(a=i.split("&"),e=0,n=a.length;e<n;e++)o=a[e],M=o.split("="),c=decodeURIComponent(M[0]).toLowerCase(),s=decodeURIComponent(M[1]),r[c]=s;return r},p=function(t){var e,n,c,o,r,i;for(e="dc=tld",c=t.split("."),o=r=c.length-1;r>=0;o=r+=-1)if(i=c[o],n=c.slice(o).join("."),document.cookie=e+";domain=."+n+";",document.cookie.indexOf(e)>-1)return document.cookie=e.split("=")[0]+"=;domain=."+n+";expires=Thu, 01 Jan 1970 00:00:01 GMT;",n;return t},a=function(t){var e,n;try{t=m(t)}catch(n){e=n,o.warn("Could not parse URL '"+t+"'"),t=""}return t.replace(/https?:///,"").replace(/^www./,"")},S=function(t){return parseInt(t)},E=function(t){return parseInt(t)/ 100},t.exports={normalizeUrl:a,toInt:S,toPct:E,load:l,clear:i,parseQuery:q}},function(t,e){t.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},function(t,e) {t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(t,e){t.exports={}},function(t,e){t.exports=!0},function(t,e,n){var c=n(36),o=n(266),r=n(62),i=n(68)("IE_PROTO"),a=function() {},M="prototype",s=function(){var t,e=n(102)("iframe"),c=r.length,o="<",i=">";for(e.style.display="none",n(259).appendChild(e),e.src="javascript:",t=e.contentWindow.document,t.open(),t.write(o+"script"+i+"document.F=Object"+o+"/ script"+i),t.close(),s=t.F;c--;)delete s[M][r[c]];return s()};t.exports=Object.create||function(t,e){var n;return null!==t?(a[M]=c(t),n=new a,a[M]=null,n[i]=t):n=s(),void 0===e?n:o(n,e)}},function(t,e){e.f=Object.getOwnPropertySymbols},function(t,e,n){var c=n(15).f,o=n(8),r=n(17)("toStringTag");t.exports=function(t,e,n){t&&!o(t=n?t:t.prototype,r)&&c(t,r,{configurable:!0,value:e})}},function(t,e,n){var c=n(69)("keys"),o=n(41);t.exports=function(t){return c[t]||(c[t]=o(t))}},function(t,e,n){var c=n(5),o="__core- js_shared__",r=c[o]||(c[o]={});t.exports=function(t){return r[t]||(r[t]={})}},function(t,e){var n=Math.ceil,c=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?c:n)(t)}},function(t,e,n){var c=n(37);t.exports=function(t,e){if(!c(t))return t;var n,o;if(e&&"function"==typeof(n=t.toString)&&!c(o=n.call(t)))return o;if("function"==typeof(n=t.valueOf)&&!c(o=n.call(t)))return o;if(!e&&"function"==typeof(n=t.toString)&&!c(o=n.call(t)))return o;throw TypeError("Can't convert object to primitive value")}},function(t,e,n){var c=n(5),o=n(4),r=n(64),i=n(73),a=n(15).f;t.exports=function(t){var e=o.Symbol||(o.Symbol=r?{}:c.Symbol||{});"_"==t.charAt(0)||t in e||a(e,t,{value:i.f(t)})}},function(t,e,n){e.f=n(17)},function(t,e,n){(function(t,c){var o;(function() {"use strict";function r(t){return t=String(t),t.charAt(0).toUpperCase()+t.slice(1)}function i(t,e,n){var c={"10.0":"10",6.4:"10 Technical Preview",6.3:"8.1",6.2:"8",6.1:"7 / Server 2008 R2","6.0":"Vista / Server 2008",5.2:"XP 64-bit / Server 2003",5.1:"XP", 5.01:"2000 SP1","5.0":"2000","4.0":"NT","4.90":"ME"};return e&&n&&/^Win/i.test(t)&&!/^Windows Phone /i.test(t)&&(c=c[/[d.]+$/.exec(t)])&&(t="Windows "+c),t=String(t),e&&n&&(t=t.replace(RegExp(e,"i"),n)),t=M(t.replace(/ ce$/i," CE").replace(/bhpw/ i,"web").replace(/bMacintoshb/,"Mac OS").replace(/_PowerPCb/i," OS").replace(/b(OS X) [^ d]+/i,"$1").replace(/bMac (OS X)b/,"$1").replace(//(d)/," $1").replace(/_/g,".").replace(/(?: BePC|[ .]*fc[ d.]+)$/i,"").replace(/bx86.64b/gi,"x86_64").replace(/
  • 47. 8. Case Studies • Every product is built differently. • Every product has had complete rebuilds. • Every product has a storied history. • Here’s a couple of them…
  • 48. Facebook • Back-end originally built with PHP, likely with a basic WAMP setup (Windows, Apache, MySQL, PHP). Front-end naturally rendered HTML (rendered by PHP), CSS and JS. No sense of business logic separation (too much effort). • Now, front-end is still written in PHP-backed HTML but runs through their weird crazy “HipHop” compiler: PHP -> AST -> C++ -> G++ -> x64. Business logic exposed through Thrift in PHP, C++ or Java based on service. Also running Java on custom application servers. Database is MySQL, caching is done through memcached (300TB at a time) and HBase. Offline processing done through Hadoop and Hive. Data logging through Scribe, stored in HDFS through MapReduce. Page acceleration through BigPipe (pipelining logic). Varnish Cache for HTTP proxying. User storage through Haystack. • Messenger is another thing entirely with all sorts of insane shit like infrastructure sharding, dynamic cluster management and cell structures. Based on Epoll server developed in Erlang and Thrift.
  • 49. Twitter • Twitter has always run on Rails but originally based on regular Ruby. MySQL database, temporarily sharded. • “Search” replaced Rails with Java server called Blender. • “Messages” replaced Rails with Starling (Ruby) then replaced with Scala. • Database replaces MySQL with Gizzard and FlockDB • Lots of custom stuff - Snowflake, Rockdove, Firehose.
  • 50. Presumi • Back-end in Express and Handlebars (hybrid rendering engine), front- end originally in Handlebars and jQuery. Database on MongoDB. • Live chat with Drift, error reporting with Rollbar, analytics with Google Analytics, payments with Stripe, email with Sendgrid, A/B with Optimizely. • Replaced front-end with jQuery with React, Handlebars with JSX. • Actual build process takes my JSX, transpiles through Babel (+React plugin) and Webpack and spits out JS. Basically I write super hot futuristic code and it converts it to pleb browser code. • Currently replacing internal app hybrid-rendering with full JS rendering and implementing React properly, reducing server usage by >50%.
  • 51. That’s all I’ve got Thanks for listening. I’m here for questions :)