The Great Migration: Redesigning and Rewriting our App in Ember.js
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Title of Series | ||
Number of Parts | 37 | |
Author | ||
License | CC Attribution - ShareAlike 3.0 Unported: You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this | |
Identifiers | 10.5446/34717 (DOI) | |
Publisher | ||
Release Date | ||
Language |
Content Metadata
Subject Area | ||
Genre | ||
Abstract |
|
EmberConf 20168 / 37
4
5
7
10
11
13
14
15
16
17
20
23
24
25
26
27
29
30
31
32
00:00
VideoconferencingCodeMobile appCartesian coordinate systemComputer animation
00:30
InternetworkingWave packetComputer animationMeeting/Interview
01:07
Content (media)TendonData managementReal numberStatisticsFormal languageOpen sourceGame controllerSoftware engineeringCache (computing)Configuration spaceService (economics)Content (media)Data managementSoftwareFunctional (mathematics)Real-time operating systemAnalytic setDemosceneContent delivery networkLevel (video gaming)Computer animationLecture/Conference
01:59
ResultantProjective planeLecture/ConferenceComputer animation
02:25
RewritingContent (media)MathematicsProjective planeVideo gameSoftware frameworkSoftwareComputer architectureMobile appInformationAxiom of choiceGoodness of fit
03:38
CodeConsistencyArchitectureSystem programmingMobile appConfidence intervalControl flowMathematicsProjective planeBitCartesian coordinate systemCASE <Informatik>CodeDecision theoryRoutingPhysical systemDoubling the cubeStack (abstract data type)Process (computing)Software testingInteractive televisionReal numberVector spaceConsistencyJava appletSoftwareNatural numberScripting languageComputer animation
05:41
Common Language InfrastructurePoint (geometry)Cartesian coordinate systemNumberRemote procedure callIntegrated development environmentBitComputer programmingInformation technology consultingCommon Language InfrastructurePhysical systemGoodness of fitLecture/ConferenceComputer animation
06:33
RewritingSoftware testingMobile appProgrammierstilScheduling (computing)MIDIData structureInformation technology consultingCodeStability theoryBuildingConnectivity (graph theory)Order (biology)Software testingGoodness of fitAxiom of choiceRewritingFocus (optics)Confidence intervalLatent heatText editorCode refactoringMereologyBitNumberSheaf (mathematics)Fitness functionCartesian coordinate systemTracing (software)Execution unitAreaClosed setProcess (computing)
09:33
FlagConcurrency (computer science)Projective planeLibrary (computing)Common Language InfrastructureValidity (statistics)FlagData managementPower (physics)Computer animation
10:23
ResultantRewritingGoodness of fitWeb 2.0CodeFunctional (mathematics)Interactive televisionWeb applicationSoftware testingCodierung <Programmierung>Lecture/Conference
10:49
CodeComponent-based software engineeringFunction (mathematics)Modal logicEmulationDependent and independent variablesCache (computing)Conditional probabilityData typeLink (knot theory)Lemma (mathematics)Default (computer science)EmailInformationCross-site scriptingCodeCursor (computers)Condition numberConnectivity (graph theory)Computer configurationMobile appModal logicSheaf (mathematics)Group actionFunctional (mathematics)Strategy gameCache (computing)Data managementMathematicsState of matterLine (geometry)Cartesian coordinate systemSoftware testingWhiteboardPattern languageSoftware developerInteractive televisionConfiguration spaceEndliche ModelltheorieMetropolitan area networkTouchscreenDependent and independent variablesEmailComputer animation
13:05
Transport Layer SecurityComputer configurationServer (computing)Continuum hypothesisMereologySet (mathematics)Mobile appConnectivity (graph theory)Group actionLine (geometry)Endliche ModelltheorieElectronic visual displayComputer animationLecture/Conference
13:32
Error messageEquals signInclusion mapIntegerError messageCodeSampling (statistics)Translation (relic)InterpolationMultiplication signInternationalization and localizationConnectivity (graph theory)AreaSoftware developerSet (mathematics)Computer animationLecture/Conference
14:09
Transport Layer SecurityComputer configurationServer (computing)Formal verificationPublic key certificateStorage area networkFinite element methodTransportschichtFamilyComputer networkInstallable File SystemSoftware developerRight angleInformation securityFormal languageType theoryInteractive televisionProcess (computing)Software testingForm (programming)Domain namePublic key certificateComputer animation
15:07
Metric systemMetric systemMobile appMeasurementCartesian coordinate systemProcess (computing)Lecture/Conference
15:28
Software testingCodeProcess (computing)Multiplication signDirectory serviceGraph (mathematics)Line (geometry)Software testingCodePoint cloudCartesian coordinate systemAverageRadical (chemistry)Scripting languageScheduling (computing)Overhead (computing)Metric systemData storage deviceTask (computing)GoogolMobile appComputer animationLecture/Conference
16:45
RewritingSoftware testingComponent-based software engineeringInternationalization and localizationWeb browserOpen sourceSoftware testingRange (statistics)Web browserRevision controlVariety (linguistics)Enterprise architecturePhase transitionMultiplicationRight angleMobile appFunctional (mathematics)Multiplication signType theoryDifferent (Kate Ryan album)Library (computing)MereologyLevel (video gaming)Software frameworkStagnation pointRule of inferenceProjective planeMixed realityFeedbackSoftware bugEvoluteConnectivity (graph theory)Metric systemCartesian coordinate systemConfiguration spacePosition operatorFocus (optics)Combinational logicCuboidState of matterBitSuite (music)Process (computing)PlanningAnalytic continuationImplementationBuildingMultilaterationOpen sourceAmsterdam Ordnance DatumGraphical user interfaceTransport Layer SecurityTask (computing)Line (geometry)RandomizationStandard deviationDrum memoryScripting languageSpring (hydrology)
25:05
XMLComputer animation
Transcript: English(auto-generated)
00:12
I'm gonna get this mic out of the way so that you can all see me.
00:21
Well, welcome. Thank you for being here. Good afternoon. Today I'd like to share with you the story of redesigning and rewriting our application in Ember. First let me introduce myself. My name is Jade Applegate, and here is me, a picture making a friend at an owl cafe in Tokyo.
00:40
You can find me online at Jade Applegate, most places on the internet. Here I'm on the left in the pink sweater, and I wanted that microphone so bad. I think I thought I'd grow up to give a talk at EmberConf, and I wanted to get prepared early. So last year was my first EmberConf,
01:01
and this year I am speaking, so I guess dreams do really come true. I work for Fastly, which is a real-time content delivery network, and I am a software engineer on our user experience team.
01:21
Fastly is a global CDN with caches all around the world, as you can see on this map, and our global network is built in Varnish, which is an open-source cache control language. As I mentioned, I'm on the UX team, where we work on the customer-facing UI. This is one UI for all customers
01:40
where they can manage their account, manage their billing, manage users, see real-time analytics and stats, and we also put a lot of functionality into the hands of users through advanced configurations for managing their cache services.
02:00
So what are we going to discuss today? Here's a quick overview so you know what to expect for the next 30 minutes. First, we'll talk about the rationale for migrating to Ember, the approach that we took, the results of our work, the many, many lessons we learned along the way, and the next steps for what's next for our project and team.
02:24
So let's get started. Remember this guy from last year? Last year at EmberConf, I met a lot of people who were using Ember for side projects, but not in their day-to-day life as engineers. And as more and more companies adopt Ember
02:41
as their framework of choice, it can be helpful to hear about a company's successful move to moving to Ember. So whether you're considering a migration yourself or are already in the midst of a similar project, or maybe just getting your feet wet with the framework, I hope there's some content here for everyone. So now that I've given you the rationale,
03:00
let's ask ourselves a question. Why would you ever do a rewrite? I've heard those are bad. So what were we thinking? This project was originally only a tech rewrite, a port from a backbone CoffeeScript app to Ember. But of course, like any good software project,
03:23
the scope changed, and that led to some design changes, which led to some information architecture changes. But regardless of the scope, there were a few things that were not really possible with our existing legacy app. It was hard to quickly make changes in the app,
03:43
and we had no test coverage, which meant that we had a lack of confidence in any change that we made. We had a lack of code consistency, so for example, there were about five or six different ways that I found that you could implement a modal throughout the application.
04:02
And that's probably bad, so. We also had a lack of modern architecture, and our backbone app was deprecated, and no one wanted to write in CoffeeScript, to be honest. So it was hard to find people that wanted to work on the project.
04:21
Our application lacked rich interactions because we were too busy trying to figure out whether something was working or not, or whether it would break somewhere or not. And the design decisions that were made for it were made based on a designer's feelings, rather than perhaps user research and testing, which would have been a better route.
04:41
The code base had no real ownership, so anybody that knew even just a little bit of JavaScript or CoffeeScript in this case could contribute to it, which in a way is good, but in another way is very, very bad way to maintain your code. There wasn't a user experience team or anything that kind of kept it all together,
05:01
and there were dependencies on other systems throughout our stack. A really strong example of this was our very slow deployment process. It took around one hour to complete, and maybe two if something went wrong. It was just completely unfeasible in software. So we had to do manual Chef builds,
05:24
manual Jenkins builds, and lots of double checking to make sure that once we did deploy, the changes were propagated across our app, and it didn't break something else that we weren't thinking of. Because there was no test coverage, that was the only way we could really ensure something was working.
05:42
So an important point that I want to make here is that you can fix every single one of those problems without Ember. We could have definitely started working on those things in our legacy application and fixed them, but we wanted a few additional things to go along with it. We wanted to use Ember CLI for the built-in conventions
06:03
that it comes with and all the goodness that Ember CLI has. We had some in-house knowledge of someone who had done a little bit of Ember programming before, so we wanted to take advantage of that. And proxying to a remote dev environment meant that we didn't need to rely
06:21
on any other systems in our stack, so this meant that new team members could contribute on day one. It also meant that the consultants who worked with us were able to get up and running almost immediately. So with those things in mind, we decided that the rewrite was best for us, and rather than resurrecting the old app,
06:41
we began a rewrite. We decided to use Ember, of course, or I wouldn't be here, and this included a few steps. So step one was for us to learn Ember, and we went through Ember's docs, online tutorials, in-person workshops, and the consultants that came and worked with us in-house, as I mentioned.
07:01
Those all really brought us up to speed in Ember land. So in the beginning or mid of 2015, we got started with porting over our account and billing sections, and that was really before we had a sense of pod structure or components, or really even how to use Ember data well. So those sections, they work, they're not elegant,
07:22
but they still need a little bit of a refactor now that we're done with some other more complicated places in our code. Another part of our modern approach was a focus on testing and the importance of test coverage in our app. We used Ember QUnit and Mirage, and having every feature tested
07:41
helped us feel confident in our code, and we didn't want to get into a scenario like before where we had to manually test things to see if things were working. We also wrote custom test helpers to make it easier for us to write more semantic tests, and the test coverage and the confidence in the app that it stemmed was a big upgrade
08:02
from our old application, which had none, but it also made us feel more comfortable working in the code. So components, we used components like it was our job, because it was, and rather than always be closing, I like to think of our new mantra as always be componentizing.
08:21
I'll show you later how components helped us develop features more rapidly in our app. Choosing modern tools in Ember helps you make good tooling choices generally, adopting code style preferences using Suave and JSHint led to some more specific editor tooling choices like atom packages that helped us develop more easily.
08:44
And it's a really good idea to rely on community solutions rather than build something in house. It can seem costly to stay current in Ember in order to keep up and to be able to take advantage of these things, but the more you do, the more that you can leverage the community.
09:00
But it's also important to note that every team and every app has to find their own pace. So as we all know, Ember moves incredibly fast, and not everyone has to or can keep up to the latest build, and there are some stability and priority reasons not to. And on the flip side, there are quality and performance reasons why you might want to.
09:22
But don't feel bad if you're not on the latest build. You need to choose the upgrade and dependency schedule that fits your build and your needs. As I mentioned, we relied on a lot of community solutions. So we're currently using Docker at Suave,
09:42
Ember CLI Mirage, Ember Feature Flags, Ember IATN, and we'll talk about that a little more in the beginning, or in the middle, and Ember validations, and then finally, SVG for everybody. And I'd also like to point out that there are some libraries that we're not using yet,
10:02
but we will be soon. So a couple future libraries, Ember Power Select, Ember Concurrency, and I'm sure there are many others that we'd like to get our hands on and work into our app. And at this point, I'd just like to say a huge thank you to everyone in the community that helps to support and maintain all of these projects that we're able to take advantage of.
10:24
So now that you know the approach that we took, what was the result of our rewrite? Rewrites are generally really, really hard and sometimes not a good idea, but Ember made it a lot easier on us. It allowed us to write an ambitious web application,
10:40
I'm sure you've heard that before, and we had rich features and interactions, so I'd like to share a few of those pieces of functionality and code with you. So generally, we were able to develop more rapidly. We were able to develop with feature-rich interactions. We used reusable components
11:01
and we had tested reliable code. I would say those are the four things that we were able to do across the board. So more specifically, I'd like to share with you a few examples about how Ember's conventions helped us with our migration. So this is code from our modal component and there's only one, unlike the old app.
11:22
So we used this throughout our app to manage state for modals and functionality. And I know it's not super impressive to see it on its own but if you think about these handful of lines of code being used over and over in our application, it's a great example of how components work
11:41
and how far things have come for us. And I'll show you a GIF of one of our modals in action in a few minutes. So in our app, there's a section where you can configure and manage your headers, responses, health checks, gzip policies and more and they're all related to your caching strategy and needs.
12:03
In this example, we were able to use the one modal component for attaching a condition and you can see that option next to my cursor on this screenshot. We were able to also extend that condition's functionality in modals across the app with just three separate components.
12:21
So these were add condition, remove condition and edit condition. And these resources were reused throughout our application in the configuration section over and over again. So this made development in our application quite rapid and easy to test and we also had predictable patterns to follow.
12:41
So if we made a change in one, we were able to also see those changes propagate over to the rest of the application wherever they were needed. So this is the GIF of the condition functionality and since you can add a condition to every section and configure, it's nice that we only have to rely on the one modal component and the one add on component
13:03
to do this in many places across the app. So here's an example from our disclosure component which hides and shows particular parts of the app. Since it's a reusable component, we were able to use it in multiple places across the app like to hide and show advanced settings
13:21
and to display inline tips. So here's that modal in action, or that component in action. So besides reusable components, we used Ember IATN and we were able to set ourselves up well for internationalization.
13:41
This is a code sample from our translations file, specifically the errors hash and you can see the interpolation of the specific errors that would arise. So we focused on adding translations in English as we added features so that when the time came to internationalize, to say Spanish or Japanese,
14:02
all of that foundation would be in place. Since Ember made development so much easier on us, we were able to focus on developing feature-rich interactions that had a direct benefit to our users and we went through a user experience research
14:22
and testing process that revealed to us that we should really be providing terminology and best practices to our users. And an example of this type of feature-rich interaction is this new TLS form. Our security team at Fastly worked with us so that we would have the right language in there
14:41
and the right best practices so that if someone decided to not verify a certificate, for example, it would surface a warning almost automatically and show them the kind of best practices in the security world. And generally the form is much more clear, it has better recommendations,
15:01
and it leverages best practices through outside of our own user experience domain. So how can we measure a successful rewrite? I'd like to say to you that we were able to grab metrics from the old app and have metrics from the new app and compare them but they didn't exist in the old application.
15:22
But even though we didn't have those measurements in place, there are some key places that are measurable, specifically with our deploy process. It uses Varnish, Ember, Google Cloud Storage, and Fastly. And it takes one command, I'm sure this looks familiar,
15:41
and about two minutes to complete versus one or two hours before, as you remember. And that two minutes is mostly related to PCI tasks, it's not really just sending Ember to deploy in your terminal. So now there are no manual Chef builds, there's no data bag updates, there's no messing around with Jenkins,
16:01
and it's a major improvement over our old applications deploy process. And it lets us deploy on a regular schedule without a lot of overhead. Another metric to share and a major improvement is our test coverage. This is, I was able to write a script that compared lines of code in our app directory
16:21
to lines of code in our test directory. And this is a graph of that work week by week throughout the process. As you can see, this is a pretty dramatic increase over our past test coverage. I mean, one, because it's greater than zero. And two, because we have at least one to one ratio
16:41
of test to code at any given time. So metrics aside, what did we learn through the migration process? I'd hope to share with you a couple of highlights. We learned that it's a really bad idea to ignore deprecation warnings and let your version of Ember stagnate
17:00
and not upgrade to the latest version. We also learned to pay down tech debt as we went, so we worked on a mix of feature, infrastructure, and tech debt stories every sprint. And this made keeping up with the latest versions more manageable and it made our app more stable.
17:21
We also learned to be more selective with the types of external libraries we chose and to evaluate how fully functioned and how fully featured they were. We also thought to ask ourselves what features do we need now and what features will we need for the library to support in the future?
17:40
Not only do we want the functionality that comes with it out of the box, but is there a time later on that we are going to need to add additional functionality and this wouldn't be supported by the library that we chose. So what we didn't want to get into was implementing something, getting it to work, and then finding out later that oh, we needed additional functionality
18:01
so then we'd have to rip it out, replace it, and then move on from there. So we tried to see if the libraries that we chose, are they a community standard? How commonly are they used? How well maintained are they? So maybe just don't go with the first one that you find online.
18:20
Do a little bit more research to see if it's the one that's really right for you. So if you want your app to be tested, you have to start early. It's not really something that we learned that we could catch up on or do later because we knew that we never will and we thought we'd get ourselves back into a scenario like before.
18:41
So I prefer to do TDD to test my features because it helps me make sure the tests get written, but of course your mileage may vary. But testing each feature has been an important focus for us, and throughout the migration with the combination of the out of the box configurations for tests and our custom test helpers,
19:04
we had a really easy time of writing tests. Again, components, we talked about those a little bit before, but they made it easier for us to build things and build things later. So you or someone like you will be working on an app like this in the future
19:20
and you don't want to kind of leave things in a state where it would be hard to add to something. But I don't want to go too far into component evangelism because I think there's more to the story. But it's been really, really helpful for us to add new features to our app using components. And it also made working with design a lot easier
19:41
because we were able to capitalize on existing infrastructure when we were adding new features. We also learned to internationalize as we went, and it saved us a lot of work later on. We have plans to internationalize the text in our app because we have so many users all over the world.
20:02
And like with tests and components, you'll thank yourself later for putting this foundation in place, so it's something that I'd like to stress. So what are our next steps? What happens now that we are almost finished with this rewrite? So our work continues.
20:21
We continue to work on bugs, features, and design implementations. And we also learn how to maintain an app while we add these new features. So that's a new exciting phase for our team. We've been just porting things over for about a year, and it can get a little boring.
20:41
We are building a responsive strategy so that we can have support for multiple devices. But first we want to make sure that we do the right kind of user research and testing so that we find out which features would be most likely to be accessed on which device. And a majority of our users are on Chrome,
21:03
but we need to support a variety of browsers and versions including IE 10. Since many of our customers can be enterprise customers, we need to support that range of browsers so that everyone has a seamless experience. So right now we're in a private beta,
21:22
and we will go to general availability later this year. So we will switch everybody over to the new version. And we're getting feedback and bug tickets from those people that are doing the private beta for us. Those are customers of ours that wanted to get in early and play around with the app. And through their feedback we'll be improving
21:40
the general experience overall in the application. So finally I'm excited to announce that the entire project will be released as open source later this year. It was really important to us, thank you, to do this for a couple of reasons. One, we wanted to be a really good example of what a modern application would look like.
22:02
And two, we wanted to give customers the ability to fork the project and add any customizations that they might like. It's been so exciting to see the evolution of the framework over the past year as we've worked on the migration. And I'm really thankful to be such a part,
22:20
a part of such a fantastic community and for the opportunity to speak here today. I don't think I can get off the stage without saying this, but we're hiring for a handful of senior JavaScript rules at Fastly, so if you're interested come talk to me and we'll chat. And if we have a few minutes I'd be happy to take any questions.
22:42
Thank you. Thank you Jade for your talk. Can you tell us more about what you learned about what you mentioned of user research and user feedback? Sure. Before we started the rewrite project
23:03
we got into user testing with a variety of people, with a variety of experience using CDNs. And we were able to see how they would react to different designs and different experiences in the app. And then to build those experiences to best suit the experience that we wanted them to have.
23:24
So that's how we found out about having best practices for things like TLS, how we found out that we needed to give them tips and explain things better throughout the app. So we're continuing to go through that process every time we add a feature, which is really valuable to us.
23:41
Thank you. So now that you've been in the Ember community for a year and change, what do you think would be a topic or a resource or something that would be really valuable to newcomers to Ember that you wish existed a year ago when you started? Yeah, I don't know if you were able to see Liz's talk this morning,
24:02
but it was about testing and everything that she had wanted to learn over the past year. She gave a talk last year, a lightning talk, where she was kind of at the last minute encouraged to give a lightning talk about testing. And she likened herself to the chemistry dog,
24:20
where he had no idea what he was doing. And I felt a lot like that when I first started learning Ember. But her talk today went through a lot of different things that she wished she would have known over the year, in the past year. And it's been really nice to see the evolution of the Ember docs and things like that, all the resources online,
24:42
because those things really weren't in that great of a state about a year ago. So I think we're in a really good position now for newcomers coming to Ember to see the types of things that they would want to see. We're in a lot better position than we were about a year ago.