00:00:20.320
all right now that i've suffered through
00:00:21.760
that um so hi everyone my name is nick
00:00:24.880
simmons
00:00:27.039
and here i'm uh today i'm here to talk
00:00:29.760
to you about uh how shopify we built a
00:00:32.640
single page web app
00:00:34.160
and why in the end we decided to
00:00:37.440
go back to
00:00:39.040
a non-single page while that
00:00:42.640
so before i start i'd like to say uh
00:00:44.800
this is actually my first time speaking
00:00:46.399
at a conference um so it's
00:00:48.719
very exciting for me
00:00:55.039
so it's very exciting and also very
00:00:56.559
terrifying so if i make any mistakes
00:00:58.800
please bear with me
00:01:00.320
um
00:01:02.160
so let's get started
00:01:03.680
uh tell you a little bit more about
00:01:05.280
myself
00:01:07.200
so first of all uh i'm canadian
00:01:11.840
there's some very uh stereotypical
00:01:13.200
canadian things you might have heard of
00:01:14.320
and i would say that i'm very similar to
00:01:16.320
a very stereotypical canadian uh so
00:01:18.560
first of all
00:01:19.680
my favorite sport is hockey uh how many
00:01:22.400
how many people here are hockey fans his
00:01:24.320
hand
00:01:25.439
wow five more people than i expected
00:01:27.439
that's amazing
00:01:28.560
uh
00:01:30.400
second of all um canada's not really
00:01:32.720
that well known for food
00:01:34.560
but
00:01:35.600
maple syrup
00:01:36.960
my absolutely
00:01:38.400
favorite thing to to eat um whenever i
00:01:41.119
have pancakes or waffles if i don't have
00:01:43.439
maple syrup i'm extremely disappointed
00:01:46.399
uh and last of all
00:01:48.079
uh in canada we unfortunately have to do
00:01:50.240
with winter so
00:01:52.079
this is a picture of the city where i
00:01:54.479
live
00:01:55.360
and uh you see those things there on the
00:01:57.520
right those are actually cars
00:02:00.479
so a very important thing when you live
00:02:02.399
in canada is to get underground parking
00:02:04.399
cannot tell you how important that is
00:02:07.680
so the other interesting fact about me
00:02:09.440
is that i actually used to live in
00:02:10.560
singapore um so i was here for about a
00:02:12.640
year and a half
00:02:14.000
and i was working for lucas arts so
00:02:16.560
it was super cool getting to work on
00:02:18.080
star wars stuff living on the other side
00:02:19.760
of the planet getting to travel a lot it
00:02:21.920
was great
00:02:23.360
i was actually a back-end developer for
00:02:24.959
some online games that we were working
00:02:26.640
on unfortunately none of them shipped
00:02:29.360
and there's a good reason for that
00:02:31.360
about six months after i had started at
00:02:33.599
lucas arts
00:02:34.879
we were acquired by disney
00:02:38.239
so
00:02:39.760
you know
00:02:42.080
disney
00:02:48.239
disney seems like a really nice you know
00:02:50.480
family-oriented company and they are uh
00:02:52.560
but they're a little bit ruthless when
00:02:53.599
it comes to the business so when they
00:02:55.280
bought lucas arts or lucasfilm i should
00:02:57.200
say they decided that they were really
00:02:58.800
into the movie idea but not so much into
00:03:00.480
making games
00:03:01.840
so
00:03:02.560
in the end well
00:03:04.800
that was the end of that
00:03:08.640
but it's not all bad news
00:03:10.480
in the end i ended up moving back to
00:03:12.159
canada and i got this awesome gig at
00:03:14.239
shopify so this is basically what i'm
00:03:16.000
doing now
00:03:17.280
i've been in shop 5 for a little over a
00:03:18.800
year
00:03:19.920
and this is actually the first time
00:03:21.920
i started working with ruby and rails so
00:03:23.840
i'm still relatively new to it
00:03:25.920
actually another interesting fact is
00:03:27.120
that it was also the first time i've
00:03:28.159
ever used a mac
00:03:29.440
not programming mac i mean literally
00:03:31.120
using a mac i had no idea how to even
00:03:33.519
install an application
00:03:35.519
but yeah it's been a wild ride and i
00:03:37.360
really loved it
00:03:38.879
so specifically at shopify
00:03:40.799
i'm working on the admin interface
00:03:43.440
so this gives you an idea what it looks
00:03:45.040
like basically it's a pretty large web
00:03:47.920
app
00:03:49.280
there's lots of different sections
00:03:51.120
lots of different configurations that
00:03:52.480
our shop owners can do
00:03:55.280
so it has as i said lots of pages
00:03:58.080
basically all form submissions um and
00:04:00.959
lots and lots of data going on
00:04:04.400
so i'd like to talk a little bit about
00:04:05.519
the evolution of the shopify admin
00:04:09.360
so in the early days
00:04:11.280
the classic version of admin was
00:04:14.560
rails app using some templating with erb
00:04:17.919
and some jquery sprinkled around to do
00:04:20.000
any sort of cool stuff we wanted to do
00:04:21.280
in the clients
00:04:23.120
but a couple years back a decision was
00:04:25.360
made that they wanted to
00:04:27.280
build a single page web app now the
00:04:28.960
original reasoning for that was they
00:04:30.720
were thinking well hey if we could have
00:04:33.520
the same
00:04:34.960
application for both
00:04:37.440
mobile devices and for the web that
00:04:40.080
would be great basically just to
00:04:41.360
abstract
00:04:42.560
abstract the client away from
00:04:44.800
the server and also to be able to build
00:04:47.120
our json api which the time did not
00:04:48.880
exist
00:04:49.840
and just treat the client as another
00:04:52.000
consumer of this api
00:04:54.160
so when they were initially evaluating
00:04:56.000
the js nbc frameworks that existed none
00:04:58.240
of the solutions that were out there at
00:04:59.360
the time really met
00:05:00.960
the needs uh for the team so they
00:05:03.600
decided to build their own
00:05:05.759
and from this uh batman js was created
00:05:10.080
so when we started building admin 2 this
00:05:12.000
was still before my time
00:05:14.720
batman gs was the framework that it was
00:05:17.039
built on top of
00:05:19.360
so we finally released admin 2 in july
00:05:21.520
of last year
00:05:22.840
2013. and funny enough six months after
00:05:26.479
releasing admin 2 we decided that it was
00:05:29.360
time to move away from this framework
00:05:32.160
uh so our new admin is called admin next
00:05:35.039
because i'm getting tired of using
00:05:36.840
numbers um so you might be curious what
00:05:40.160
admin next is about
00:05:41.680
well
00:05:43.199
i'll talk about that soon but when i say
00:05:45.120
soon i'll only briefly mention it in
00:05:46.960
this talk at the end
00:05:48.800
to be honest we're not completely
00:05:50.000
finished with what we're doing
00:05:52.560
and i'd like to make sure that maybe in
00:05:54.000
the future we'll give another talk
00:05:55.759
we'll explain exactly what we've done
00:05:58.319
and
00:05:59.440
hopefully we'll open source it
00:06:04.400
so
00:06:05.199
start my story with uh
00:06:07.440
when i began working at shopify so when
00:06:10.080
i come in um i was sort of interested in
00:06:12.319
the idea of doing a jsnbc app in a
00:06:13.919
single page web app you know it sounded
00:06:15.440
like a really cool thing um really
00:06:17.840
interested in it but i never actually
00:06:19.520
got to work on anything like that before
00:06:21.280
so when i joined shopify batman was
00:06:23.759
basically finished admin 2 was almost
00:06:25.759
out the door
00:06:27.440
and everyone was really excited about
00:06:28.880
this new direction that we were going
00:06:30.639
i mean with this me we had no more full
00:06:32.240
page reloads on paint transitions that's
00:06:34.319
really cool all of our html endpoints
00:06:36.560
that we had in the code were completely
00:06:38.319
removed and we had all of our templates
00:06:40.160
stored in the client
00:06:42.720
json api which was shared between admin
00:06:45.440
as well as any third-party apps
00:06:47.600
so that was cool basically the server no
00:06:49.599
longer cares about any of the ui
00:06:51.039
concerns
00:06:52.160
and the admin api i said it's just
00:06:53.680
another api client great
00:06:56.400
but there's a little problem
00:06:58.880
batman is super hard to use at first i
00:07:02.800
thought it was just me
00:07:04.080
like okay i'm new to this stuff i've
00:07:05.759
never done it before so just there's a
00:07:07.039
learning curve there
00:07:08.720
i'll pick it up eventually
00:07:10.800
but it turned out that a lot of people
00:07:12.000
were having this problem
00:07:14.400
so
00:07:15.280
when i first started
00:07:16.560
at shopify i assumed there would be a
00:07:18.560
certain learning curve and it would look
00:07:19.919
something like this so
00:07:22.160
over time i would slowly pick up more
00:07:23.919
and more of the framework and have an
00:07:25.280
understanding everything works and by
00:07:26.560
the end of it maybe a couple months
00:07:27.759
later i feel like i'm basically an
00:07:29.280
expert
00:07:30.560
unfortunately
00:07:32.000
i found my learning was a little bit
00:07:33.199
like this
00:07:34.639
so it took a lot longer to wrap my head
00:07:36.479
around what was going on
00:07:39.520
so to explain this sort of learning
00:07:41.840
curve
00:07:43.120
initially as most of us do whenever you
00:07:45.280
need to solve a problem you try to look
00:07:46.800
for other examples uh throughout the
00:07:48.560
code base
00:07:50.479
the problem was
00:07:51.759
admin 2 is a pretty large code base so
00:07:54.879
there's a lot of stuff going on
00:07:56.639
because of the complexity of batman of
00:07:58.240
stuff living in multiple places it was
00:08:00.479
really hard to sort of piece everything
00:08:01.840
together and figure out what's going on
00:08:03.440
so the next logical step is all right
00:08:05.120
let's dig into the into the docs so
00:08:07.919
batman docks existed
00:08:10.080
but i would say they were far from
00:08:11.599
complete uh there were many pieces that
00:08:14.240
were missing uh and the most important
00:08:16.240
part was that there wasn't really a good
00:08:17.840
onboarding into batman you couldn't just
00:08:19.840
uh follow a simple tutorial get started
00:08:22.080
and have a batman app up and running
00:08:23.520
very quickly
00:08:26.000
so
00:08:27.360
uh i gathered a little bit from that you
00:08:29.520
know good overviews some of the some of
00:08:31.360
the things were covered so i felt okay i
00:08:33.120
don't have a full understanding but i i
00:08:35.120
think i'm ready to uh to dig back into
00:08:37.200
the admin code
00:08:38.880
and shortly after doing that i started
00:08:40.800
running into those things were
00:08:41.839
undocumented so now i'm kind of stuck
00:08:44.080
what do i do all right well i'm on the
00:08:46.000
admin team obviously there's people on
00:08:47.360
the team that can help me out so i
00:08:49.200
started asking for help
00:08:51.360
problem was
00:08:52.560
is that batman was built by
00:08:54.959
several developers at shopify and most
00:08:57.120
of them had actually moved on to other
00:08:58.640
projects so on the admin team uh there
00:09:01.680
were two people that were really the
00:09:03.440
experts at batman and the rest of them
00:09:06.480
were all new hires including me
00:09:09.200
so there just wasn't enough experts to
00:09:10.959
go around to help us out all the time
00:09:14.320
so finally the ultimate way to learn how
00:09:16.560
to use batman was to dig into the source
00:09:18.320
code of batman itself now in the end
00:09:20.480
this is always a good idea if you really
00:09:21.760
want to understand the underlying stuff
00:09:23.040
that you're doing but as a newbie trying
00:09:25.440
to ramp up and be productive quickly
00:09:27.360
this was a daunting challenge and a very
00:09:29.279
slow uh
00:09:32.399
it took a long time to get through it
00:09:36.080
so uh a month later was hack days uh so
00:09:40.240
hack days at chop fish you get a couple
00:09:42.640
days everyone in the company can work on
00:09:44.240
whatever they want to
00:09:45.760
and a lot of people had decided that
00:09:47.760
with i've been to shipping uh soon that
00:09:50.320
they wanted to try out batman for their
00:09:51.600
own projects and see what they could do
00:09:52.800
with it
00:09:54.160
so
00:09:54.880
people were like yeah let's use batman
00:09:56.720
let's see what we can do
00:09:58.000
uh so okay where do i start
00:10:00.160
they follow the same natural progression
00:10:01.680
as me okay let's look in the docs you
00:10:03.760
know let's get something up and running
00:10:06.000
okay that's not really working so well
00:10:07.920
so oh crap someone please help me please
00:10:10.320
help and of course a lot of them were
00:10:12.079
coming to me and this was still at the
00:10:14.399
very beginning of my learning curve i
00:10:15.760
had no idea what's going on still
00:10:17.760
freaking stuff out um so it turned out
00:10:20.000
that most people were just like well
00:10:21.839
that's enough of that and nobody ended
00:10:23.600
up using batman for the project so that
00:10:25.600
was definitely like a big hit to the
00:10:27.120
team like wow that sucks you know this
00:10:29.120
is what we're moving forward with and
00:10:30.959
other people in the company aren't
00:10:32.079
really comfortable using it
00:10:35.760
so the first big lesson we learned
00:10:37.760
was that solid documentation and
00:10:40.640
excellent examples are so important if
00:10:42.959
you want people to use your framework
00:10:44.800
brandon the other day had touched on
00:10:46.000
this uh really guarding the open source
00:10:48.560
projects well we were not very good
00:10:50.399
gardeners
00:10:51.600
um so after hack days
00:10:54.160
we set about improving our documentation
00:10:56.560
uh making sure that all the gaps were
00:10:58.240
filled in and
00:11:00.240
we moved on from there
00:11:03.839
so for the next couple of months after
00:11:05.360
we'd shipped admin 2
00:11:07.440
the focus was on new features we had to
00:11:09.519
expand our feature set and keep our shop
00:11:11.680
owners happy
00:11:13.279
now as i mentioned before most of the
00:11:14.720
admin team was actually new to shopify
00:11:17.760
and on top of that many of them were new
00:11:19.839
to rails
00:11:21.040
so we were spending most of our time
00:11:23.440
in the client which was written in
00:11:24.640
coffeescript
00:11:26.480
now the thing with batman is batman
00:11:29.040
our approach or the approach that they
00:11:30.720
take him with batman was that it was mvc
00:11:32.880
to the max so we had all of our models
00:11:35.519
including all the associations in the
00:11:37.519
client you had the controllers and you
00:11:39.040
had view state you had everything you
00:11:40.399
could possibly ask for so that meant
00:11:42.320
that we could do a lot of things in the
00:11:44.320
clients
00:11:46.399
so first question we'd always ask
00:11:47.760
ourselves on a new feature is
00:11:49.839
where should we put this code
00:11:51.920
well
00:11:53.279
frontend dev uh client has all the state
00:11:55.519
that i need so let's
00:11:57.600
do what we can there
00:12:01.680
now
00:12:02.720
there's an obvious problem that comes up
00:12:04.240
with this
00:12:05.760
we weren't just building our features
00:12:07.360
for the admin a lot of these features
00:12:09.040
were to be used by other applications so
00:12:11.839
along comes pos which is our point of
00:12:14.079
sale application
00:12:15.360
they were developing in parallel to the
00:12:17.200
admin maybe a couple months behind us
00:12:19.920
so what would happen is they will come
00:12:21.440
along to a feature that they needed to
00:12:22.800
implement that we'd already done in the
00:12:24.079
web admin and say oh okay well not
00:12:26.880
everything is supported in the api so
00:12:29.120
we're kind of comfortable developing in
00:12:30.880
in
00:12:31.680
objective c
00:12:32.880
so they followed the same path as us and
00:12:34.639
implemented stuff in their client
00:12:37.680
a lot of duplication not ideal but the
00:12:40.160
worst part was that there were just
00:12:42.000
these tiny subtle differences between
00:12:43.920
how we implemented it and how they
00:12:45.360
implemented it which ended up leading to
00:12:47.200
a lot of bugs
00:12:48.880
um specifically related to how we handle
00:12:51.360
orders
00:12:53.200
so when you have problems like this it
00:12:54.720
becomes very difficult um
00:12:57.200
for third party especially third-party
00:12:58.560
apps that are pulling down this data and
00:13:00.000
then trying to understand what are the
00:13:01.120
sudden discrepancies and
00:13:03.200
why why does this data not all look the
00:13:04.800
same so we weren't doing a very good job
00:13:06.639
of enforcing uh consistency throughout
00:13:09.680
our system
00:13:10.880
so in the end what we really should have
00:13:12.160
done is we should have been moving as
00:13:13.839
much of this business logic into the
00:13:15.600
server the server is the authority on
00:13:17.839
the data
00:13:18.839
um and on top of that you can't really
00:13:22.079
trust the client anyways
00:13:23.920
the client especially in a web client
00:13:25.680
all of your code is just there and
00:13:26.880
someone can go in and manipulate it and
00:13:28.480
do whatever they want
00:13:31.200
so the second big lesson that we learned
00:13:33.200
so we really need to minimize the
00:13:34.639
business logic we have in the client put
00:13:36.639
stuff into the api
00:13:43.120
so it was around december
00:13:44.800
2013
00:13:46.399
that i personally started my super deep
00:13:48.880
dive into batman towards the end of my
00:13:50.639
learning curve in the graph i had before
00:13:52.240
and trying to really understand the
00:13:53.279
fundamentals of how it works uh and what
00:13:55.600
i can do to help make it better
00:13:57.760
at the same time there were a lot of
00:13:58.720
people on the team that were starting to
00:13:59.920
say you know what the admin looks pretty
00:14:01.760
janky like it's not loading as fast or
00:14:03.839
as smooth as we would have hoped so you
00:14:05.600
know what's what's going on here
00:14:07.760
the expectation was that the initial
00:14:09.680
load downloading all the assets would be
00:14:11.279
a little bit slow but from then on it
00:14:12.560
should be pretty smooth
00:14:17.279
so here's where i have a little video
00:14:19.839
uh that shows
00:14:21.920
the first clip uh shows what we would
00:14:24.880
hope that the admin would look like and
00:14:26.959
the second part of it shows what was
00:14:28.480
actually happening in admin 2.
00:14:40.639
so here i'm clicking on a link going to
00:14:42.560
an order
00:14:44.720
and when the order loads everything's
00:14:46.000
snapped into place now here this is in
00:14:48.399
admin 2 and you noticed that some of the
00:14:50.560
sections sort of popped in
00:14:52.160
over time it wasn't all just like
00:14:54.320
loading immediately so let me show that
00:14:55.600
one more time
00:14:58.560
so this is the desired effect we would
00:15:00.480
hope to have
00:15:01.600
everything's just there
00:15:03.199
and this is what was happening admin 2.
00:15:06.000
so we considered this a form of jank it
00:15:08.079
was it was not something that we wanted
00:15:09.600
to happen
00:15:10.720
and actually it's a little bit of
00:15:12.000
foreshadowing the first example was how
00:15:14.320
admin next is working but the second one
00:15:16.240
was admin too
00:15:18.720
so the reason behind this
00:15:20.959
uh was related to how batman's binding
00:15:24.320
and rendering was working
00:15:27.600
so for any of you that aren't familiar
00:15:28.880
with bindings
00:15:30.079
i have another quick example here that
00:15:31.680
shows a great application of a binding
00:15:33.759
system
00:15:46.240
so here i'm typing in something in the
00:15:47.759
title
00:15:48.720
you'll notice down below it's a little
00:15:49.920
hard to see
00:15:50.959
that that section was being updated at
00:15:53.040
the same time so we have some client
00:15:55.279
state
00:15:56.720
hasn't been persistent to the server yet
00:15:58.320
we want to make sure that those two
00:15:59.600
fields are tied together
00:16:01.360
that is a great example of how you can
00:16:02.800
use bindings
00:16:05.199
to basically tie two fields together or
00:16:07.199
possibly to link some of your javascript
00:16:09.199
objects to html
00:16:14.959
so now if we look at
00:16:17.120
another example of the order page in the
00:16:18.639
admin
00:16:20.480
how many bindings do we have on this
00:16:21.680
page well let's see
00:16:23.680
if we got a binding up here for the time
00:16:26.000
stamp when this order was created
00:16:28.240
uh we also have another binding here for
00:16:30.639
whether it's a test order or not we just
00:16:32.000
put a little warning message
00:16:33.759
some more bindings here related to the
00:16:35.440
line items on the order and the details
00:16:37.519
about the pricing
00:16:39.199
for tags notes that we can associate the
00:16:41.680
address
00:16:42.880
and also all of these events so
00:16:45.040
there's a hell of a lot of things going
00:16:46.240
on there but how many of those bindings
00:16:49.600
are actually like dynamic and just kind
00:16:51.440
of happening on the client well the
00:16:53.040
reality is all of that stuff only
00:16:55.040
changes if we do a request to the server
00:16:57.120
and when we get back the response then
00:16:58.880
we apply any updates on the bindings so
00:17:02.079
the thing is like wow we can kind of do
00:17:04.240
the same thing if we just done a an html
00:17:06.959
request and let the server take care of
00:17:08.240
it so not really getting much on this
00:17:09.839
page out of the binding system
00:17:11.760
um and the problem with that as well is
00:17:13.839
that there's an overhead to having this
00:17:15.520
sort of binding system in the client and
00:17:17.439
rendering everything in the client
00:17:21.120
one of the primary overheads that we had
00:17:24.480
was our asset bundle
00:17:26.640
so you might be wondering well how do
00:17:28.400
you how are you rendering all of this
00:17:29.600
stuff uh client-side where's all your
00:17:31.600
html coming from
00:17:33.039
our solution was to bundle every single
00:17:35.919
page in our app which as you saw was a
00:17:37.520
lot uh from the first slide i showed how
00:17:39.840
the admin looked every single page
00:17:41.760
whether you used it or not was bundled
00:17:43.679
together converted into basically a
00:17:45.919
string
00:17:47.280
and
00:17:49.280
put into a js file and bundled up like
00:17:52.720
that so we had our two main ones was
00:17:54.799
batman itself
00:17:56.480
and the admin 2 templates so this is a
00:17:59.039
lot of overhead for possibly a user
00:18:00.960
that's only visiting maybe one or two
00:18:02.559
pages
00:18:03.679
now obviously you have some advantages
00:18:05.440
if you if you uh some caching in the
00:18:07.440
browser but at shopify we tend to deploy
00:18:10.080
a lot sometimes a dozen times a day so
00:18:12.480
the cache is constantly being busted as
00:18:14.320
we change these templates
00:18:16.400
and
00:18:17.200
for someone that's using a very slow
00:18:18.880
client or a slow connection 3d
00:18:21.440
or
00:18:22.240
just doesn't have very good internet
00:18:23.840
this is obviously a lot of overhead
00:18:25.120
that's not really desirable
00:18:30.559
so
00:18:32.160
the big lesson we learned in the end was
00:18:33.840
that starting to feel like jsnbc we
00:18:36.720
still liked the idea of it but it wasn't
00:18:38.320
really working that well for our app we
00:18:40.160
had a lot of state that was only
00:18:42.559
changing we would do a request response
00:18:44.640
from the server
00:18:45.919
and there was all this overhead with
00:18:48.000
really that much of a of a benefit
00:18:50.400
so everyone agreed that there was some
00:18:51.760
parts of it that were really great and a
00:18:53.120
big improvement over admin classic the
00:18:54.720
main one being bindings there were
00:18:56.080
certain cases where we weren't we really
00:18:57.520
wanted to keep those bindings the first
00:18:59.520
example i had shown with basically that
00:19:01.760
updating a title and another section is
00:19:03.440
being updated that was a great case this
00:19:04.960
is not something that's coming from the
00:19:06.080
server something that's changing
00:19:07.440
dynamically in the browser that's great
00:19:09.840
but for using bindings to update stuff
00:19:12.559
when it comes back from the server well
00:19:14.080
it wasn't really helping us that much
00:19:17.679
so
00:19:18.480
in the end we decided that
00:19:20.720
pros versus cons was better off to see
00:19:23.280
if we could try a new approach
00:19:25.919
try to get all the same benefits that we
00:19:27.280
had in mn2 but at a much
00:19:30.320
much cheaper cost in terms of asset size
00:19:33.360
and also complexity
00:19:36.880
so decision was made to reboot the admin
00:19:39.200
and kill batman
00:19:46.400
so some of the key goals for admin next
00:19:49.440
was it had to be easy to use we learned
00:19:51.919
from that hack days that people really
00:19:53.600
struggled
00:19:54.640
ramping up and onboarding with batman so
00:19:57.120
any any new framework we would build it
00:19:58.880
had to be something that we could bring
00:20:00.160
in someone new they could mess around
00:20:01.600
with it for a day and be comfortable
00:20:02.880
using
00:20:04.840
it we wanted to keep the good bits so
00:20:08.080
full page reloads
00:20:09.520
didn't like that we definitely wanted to
00:20:11.200
keep the ability to have uh pages
00:20:14.000
basically just load the sections that we
00:20:15.280
needed to change
00:20:16.559
um but at the same time minimize our
00:20:18.799
client states
00:20:21.440
really wanted to make sure that if we
00:20:23.039
were going to make the switch it better
00:20:24.400
at least be as fast as batman or better
00:20:28.799
so the other key thing we were thinking
00:20:30.480
is
00:20:32.840
that at shopify we become very very good
00:20:35.760
at scaling the server
00:20:37.440
so
00:20:38.559
um
00:20:39.520
by building batman and pushing more
00:20:41.679
stuff to the client one of the big
00:20:43.039
challenges we had is that we have no
00:20:44.640
control over what our customers are
00:20:46.400
using so they might be using a super
00:20:48.159
fast mac macbook pro or they might be
00:20:50.480
using some crappy phone
00:20:52.400
that's only supporting 3g so because we
00:20:54.320
have no control over that there's only a
00:20:56.159
limited amount we can do to help scale
00:20:57.760
the client but on the server we can just
00:20:59.840
keep throwing more servers at it or we
00:21:01.600
can improve caching or whatever so
00:21:03.600
pushing the rendering back to the server
00:21:05.840
seemed like a good idea
00:21:09.039
so
00:21:09.840
what exactly is admin next well for the
00:21:12.400
most part it's just rails um
00:21:17.679
plus we started using turbo links and
00:21:20.240
this is the part where i'm expecting
00:21:21.360
somebody to throw something at me
00:21:24.080
but to be fair we took turbo links the
00:21:26.159
idea of turbo links and modified it for
00:21:29.200
our own purposes so the general idea of
00:21:31.280
triple links is basically that instead
00:21:33.520
of doing a full page reload it just does
00:21:35.520
an ajax request and replaces the body
00:21:38.159
so we like that idea but that was a
00:21:39.600
little bit too
00:21:42.400
a little bit too simple we wanted the
00:21:44.720
ability to replace specific sections of
00:21:46.960
the admin depending on what was
00:21:48.640
happening so a good example of that is
00:21:50.480
let's say we update an order
00:21:52.640
uh update the let's say we capture some
00:21:54.799
funds the only thing that really changes
00:21:56.480
is the total amount that's been captured
00:21:58.080
maybe a small little text section
00:22:00.640
um and
00:22:02.080
something simple like that so we added
00:22:04.400
the ability similar to how pjax works
00:22:06.159
actually
00:22:07.360
that we could just specifically replace
00:22:10.000
a set of nodes
00:22:11.520
on the page with the response that comes
00:22:13.200
back from the server
00:22:14.480
but on top of that we weren't forced on
00:22:16.480
the server side to necessarily
00:22:17.760
understand what the client was doing so
00:22:19.760
the server could render any amount of
00:22:22.159
the html respond back with it and the
00:22:24.960
client would be able to decide what bar
00:22:27.039
what parts of that html i wanted to
00:22:28.640
insert into the dom
00:22:33.679
so we're still using the same json api
00:22:36.400
endpoints that we had before just the
00:22:37.919
difference now is that if you're in the
00:22:39.360
admin it's responding back with html
00:22:42.720
and as i mentioned we wanted to keep a
00:22:44.559
binding system so we built a new binding
00:22:47.200
system in only 255 lines of javascript
00:22:50.480
very very simple and basically works the
00:22:52.559
same as it did in batman
00:22:57.039
so that's what we've called
00:22:58.000
bindings.coffee
00:23:01.039
so really what we have here is not
00:23:02.480
necessarily a full-size framework we're
00:23:04.240
just using a few simple technologies to
00:23:06.480
achieve the same goal as what we did
00:23:07.760
with batman
00:23:11.120
so the big lesson we learned in doing
00:23:13.120
this reboot is we really want to try to
00:23:15.440
keep things as simple as possible so
00:23:17.520
that it scales well now when i say scale
00:23:19.360
i don't just mean the performance of
00:23:21.600
in the browser i also mean scaling with
00:23:23.600
the number of employees we have at
00:23:24.720
shopify we're growing rapidly and it's
00:23:26.799
really important that we can onboard new
00:23:28.320
people quickly and have them comfortable
00:23:30.240
working in our stack
00:23:33.280
so how's it going so far
00:23:35.039
well we're not finished yet we've got a
00:23:37.280
couple sections that we've shipped we've
00:23:39.200
seen great results so far
00:23:42.000
the biggest difference that we've seen
00:23:43.840
is that people are saying wow this is
00:23:45.760
just so easy to use and that's great
00:23:48.400
after our experiences with batman
00:23:51.600
the client side logic has been
00:23:53.039
significantly reduced most of the
00:23:54.799
decisions we make now we can just do an
00:23:56.480
erb
00:23:58.320
now any logic that we do have
00:24:00.080
client-side is specifically related to
00:24:02.640
ui concerns
00:24:06.720
and even after building some of the most
00:24:08.080
complicated views specifically being
00:24:10.000
orders
00:24:11.200
we found that very very little
00:24:12.640
client-side code has has has been added
00:24:16.840
so the fact that the client is just so
00:24:19.520
simple to understand and so little code
00:24:21.600
and we still have all the same
00:24:22.559
functionality batman is really a
00:24:24.000
testament
00:24:25.600
to
00:24:29.600
to the testament to how uh
00:24:32.080
sorry lost my train of thought anyways
00:24:33.840
it's been a great thing
00:24:37.679
so before we ship this open source um
00:24:40.880
we definitely want to improve the
00:24:42.080
documentation a lot more we don't want
00:24:43.360
to make the same mistake we did with
00:24:44.480
batman
00:24:46.080
there's certainly some optimizations we
00:24:47.679
can do as i mentioned when we're
00:24:48.960
rendering stuff on the server uh
00:24:50.640
sometimes we're rendering far more html
00:24:52.400
than is actually required by the client
00:24:53.840
so there's some things we could do there
00:24:56.640
but overall we're very satisfied with
00:24:58.240
our decision to move away from a full
00:25:01.360
single page web app now
00:25:03.679
i'm saying it didn't really work for us
00:25:05.120
but i still believe that jsnbc makes a
00:25:06.960
lot of sense for certain applications
00:25:09.039
and in our case
00:25:10.960
it wasn't for us
00:25:12.480
so
00:25:13.679
batman is dead but for us it's terrible
00:25:16.000
time
00:25:16.799
thank you
00:25:24.720
thanks nate
00:25:25.760
any questions for him
00:25:28.080
a question for you um
00:25:30.720
would you reconsider
00:25:33.279
doing a single page app
00:25:35.200
with sort of the developments in a lot
00:25:37.679
of frameworks such as ember require.js
00:25:40.720
angular and stuff like that
00:25:43.200
uh for me personally yes i i would be
00:25:45.279
interested in exploring other frameworks
00:25:47.279
uh i think
00:25:48.640
part of it now is that we've uh with our
00:25:50.799
experience with batman we've sort of
00:25:52.559
shied away from it but i do believe that
00:25:54.559
uh as jsnbc frameworks are improving
00:25:57.279
that a lot of these problems are being
00:25:58.720
solved that we had i would actually
00:26:00.559
attribute a lot of our problems
00:26:01.679
specifically to batman and how we've
00:26:03.200
built batman not necessarily jsnbc
00:26:05.200
frameworks as a whole
00:26:07.679
cool
00:26:08.480
second question it
00:26:10.799
doesn't look like anyone else um
00:26:13.679
with
00:26:14.720
how much of a role would you say
00:26:17.360
jason api played in the decisions he
00:26:20.400
made on the front end
00:26:22.720
and stuff like that inspiring
00:26:25.919
how are your diet reloads and stuff like
00:26:27.840
that
00:26:30.240
um sorry in terms of what
00:26:32.400
i um the way in which your data is
00:26:35.120
structured and yes sent through to your
00:26:37.279
front end
00:26:38.559
so if you're sending ids that then
00:26:41.600
require another
00:26:43.200
fetch from the api for more data right
00:26:46.000
he showed that
00:26:47.520
um page where it was loading data and
00:26:50.080
conventional
00:26:51.679
that just a um
00:26:53.600
artifact of the way you designed your
00:26:55.600
api
00:26:57.200
actually the api was returning
00:26:58.720
everything in one response so we just
00:27:01.679
had one json request that was coming
00:27:03.520
back
00:27:04.320
the problem you were seeing there was
00:27:05.919
totally related to how batman was
00:27:07.360
handling that response it's it's related
00:27:09.440
to some of the details of how we we did
00:27:11.200
uh some of the bindings how the bindings
00:27:13.600
would basically render uh render out the
00:27:16.000
html um it's
00:27:18.799
it's beyond the scope of this talk for
00:27:20.799
sure there's some deep complexities in
00:27:22.640
there that i would prefer to forget
00:27:25.600
um but yeah it was it wasn't related to
00:27:27.760
to the how the api was responding
00:27:29.919
cool thank you
00:27:35.039
hey tried to uh did you try to
00:27:37.279
contribute to batman or like contact
00:27:39.200
maintainers and talk to them about these
00:27:41.600
issues that you had i mean i'm wondering
00:27:43.840
if it's developed and if your experience
00:27:47.679
somehow made maintainers to to to change
00:27:50.640
to improve the library
00:27:52.960
so
00:27:53.679
actually uh it was around december when
00:27:55.520
i was doing that batman deep dive that
00:27:57.840
uh we had started to discover um some of
00:28:00.559
the flaws in batman and i started to to
00:28:03.600
come up some for uh come up with some
00:28:05.279
solutions for this
00:28:06.720
but there was a lot of work that would
00:28:08.480
have been involved
00:28:10.080
one of the problems with batman is the
00:28:12.080
amount of complexity that was built into
00:28:13.520
there was a very large framework there
00:28:15.200
was a lot of things going on and making
00:28:16.960
any change was was very difficult
00:28:19.600
whereas we figured it's probably going
00:28:21.840
to be just as expensive to just do a
00:28:23.440
reboot and go from there so that's why
00:28:25.840
we went the the prototyping
00:28:28.240
solution
00:28:32.159
any more questions
00:28:34.640
if not thank you nick
00:28:47.039
so
00:29:01.039
you