Building Resilient Frontend Architecture • Monica Lent • GOTO 2019

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

btw if anyone has followup qtns based on this talk, ask away, i’ll try to get her to swing by and respond

she also wrote 7 absolute truths I unlearned as junior developer

👍︎︎ 1 👤︎︎ u/swyx 📅︎︎ Dec 12 2019 🗫︎ replies

This is a 34 minute talk from GOTO Berlin 2019 by Monica Lent - Lead Frontend Engineer at SumUp. I've dropped the full talk abstract below for a read before diving into the talk:

Change is inevitable. So is legacy. And too often, we as developers (who love to solve problems by coding) fall into the trap of believing the only way to fix it is by rewriting everything again and again. But how can we design an application architecture that is more resilient to change in the first place? How can we defend against entropy in a system where people are pushing changes every day?

In this talk we’ll define what architecture means for the frontend, dispel some commonly-held myths, and look at specific tools and techniques on a scale from micro to macro that you can use today to keep your app from turning into that infamous big ball of mud.

What will the audience learn from this talk?
The audience will learn specific practices and techniques they can use to preserve their frontend application's architecture over time. We'll walk through why developers tend to rewrite code over and over again, discuss the concept of "enabling constraints" and how they map to software development, as well as three specific constraints developers can place on their applications to ensure they evolve in a more sustainable way. Although specific examples from React and web development are given, the principles apply to many kinds of applications.

👍︎︎ 19 👤︎︎ u/goto-con 📅︎︎ Dec 12 2019 🗫︎ replies

This is a great talk and not React-specific. I have gotten so suspicious of "code reuse" in my old age

👍︎︎ 6 👤︎︎ u/harried-dad 📅︎︎ Dec 12 2019 🗫︎ replies

Great talk, and also helps me understand why I tend to generally enjoy opinionated frameworks.

I’ve just started using tailwind as a css framework, and it has turned style design from a nightmare of choices to a much nicer and easier constrained system of styles.

👍︎︎ 6 👤︎︎ u/valtism 📅︎︎ Dec 12 2019 🗫︎ replies

This is a question on not having shared components.

Maybe too specific of a question, but I have an IconButton component that does exactly what it says. It creates a button that can also have a prefixed or suffixed icon on it. How would something like that be handled? It seems like a waste of development to have every user recreating the same markup over and over again.

👍︎︎ 3 👤︎︎ u/gonzofish 📅︎︎ Dec 12 2019 🗫︎ replies

I feel like a lot of these problems mentioned would benefit from decent code coverage and tests. Also keeping things simple and concrete. Having a bunch of solid well covered building blocks can help improve speed and confidence.

Although I watched the recommended video that followed about "agile is dead" and the speaker mentioned how he doesn't do tests anymore unless it's an algorithm because he's been doing it so long he keeps all those thoughts in his mind as he writes it.

Good watch, nonetheless

👍︎︎ 2 👤︎︎ u/bstriker 📅︎︎ Dec 12 2019 🗫︎ replies

I think there are some great thoughts here from a pure code standpoint, but all the decision flow was discussed as one way. Like new business requirements fracturing a generic shared component. But I also like to look at things like that in a reverse flow of thought.

Sometimes a designer has created a piece of UI that is complicating the code of a shared component and rather than saying "then we should split this code" you should consider if it's a smell that the designer is breaking pattern of the design system. Why should a one-off coded component be created to meet a one-off design need rather than the design using the already provided component? Sometimes it's necessary, but I think using the introduction of complexity to an architecture can be a good canary for why it's happening rather than just blind implementation.

👍︎︎ 1 👤︎︎ u/alejalapeno 📅︎︎ Dec 13 2019 🗫︎ replies
Captions
Hello, so yeah, I hope you guys have some energy left for the last breakout session. My name is Monica. And for the last five years I was working at sum up which is a FinTech company based here in Berlin and a lot of what I'm going to talk about today is based on my experience working there growing the company from About 80 people to more than 1,500 people worldwide So we're gonna dive a little bit into what that looks like when it comes to scaling front-end architecture for a team that is both distributed and growing. But before I go into that I want to ask a question and that is Why do we rewrite software? I don't know about you. But there are pieces of code that I have written so many times , then I told the product manager I will quit if you make me do it again. All right. I don't know maybe some of you can relate to that. I think there's not just one reason why we end up rewriting software. In fact, There's a ton of different reasons and to illustrate one of these I want to tell you about my first ever job in tech. I was 19 years old my job title was student webmaster, which is a pretty awesome job title when you think about it because you get to be both a student and a master at the same time I think it's a lot cooler than senior engineer or whatever it is. We call nineteen-year-olds these days now when I was working as a student webmaster I was there to write PHP and my sequel which I had been teaching myself in my childhood bedroom for the last couple of years So when they asked me how much experience do you have? I thought I had four or five years of good experience anyways, so I joined and I inherited the code from the previous student webmaster and When I looked at this code, it was not exactly what I was expecting to find it was written in object-oriented PHP But the kind of PHP that I know how to write was basically like HTML templates with a couple of sequel queries thrown in there, so Yeah, I didn't really know what to do with it So like any good developer ,I decided to rewrite it. Why because I didn't understand what was going on and frankly I didn't really have the maturity to figure it out spend the time and in reality I think a lot of software gets rewritten for this reason comes down to inexperience You just don't want to spend the time to understand someone else's code and frankly, It's a lot of work Another big reason why code just gets rewritten is because well, it's fun I mean, I don't know about you But I spent every Christmas giving my statically generated blog a new theme why not because I need it But because it's fun I have the time and I think if we were honest with ourselves There is probably a good amount of product code. That is also rewritten for exactly this reason Sometimes It's because we have a better solution available Especially on the web. We are often hacking our way around the platform and Sometimes eventually the platform gives back and then we get to replace our homebrewed solutions with something That is finally native but the reason we usually rewrite code in my experience is Another reason entirely when you ask a developer who's in the middle of a big rewrite They will usually give you this reason for why their project absolutely couldn't wait any longer and That's technical debt. Technical debt is one of my favorite terms in software development. Why? Because you can ask every single person in this room what is technical debt and they will tell you something different. Is it code I didn't write? Oftentimes sometimes you know technical debt kind of tends to boil down to that. Or if you've been working at the same company for a while, It is code I wrote before I knew what I was doing. I Can tell you I have got a lot of that. Is it things like old libraries? I don't know you want to upgrade in the front-end. We love upgrading things and maybe those libraries are keeping you from using some new features or is it features no one uses because Migration is the name of the game in front-end development If you're not migrating something right now you are behind so if you have features that nobody uses you have to migrate them Which is kind of terrible and yeah, you could say it makes you slower so if I were to come up with my own definition It would look something like this code that negatively and repeatedly affects the speed or quality of delivery can be code tools infrastructure, whatever and We know what it looks like, right? You start building something. It's super fast. You think this is amazing. It's green field I'm so happy This is why I'm a developer And then over time your productivity Slides right down to the bottom and you wonder how did this happen to me? but what I've also seen is that sometimes this effect occurs and then the developer gets to a point where They can't take it anymore. And they tell the product manager or the tech lead or whoever it is Like you're not gonna retain me if you don't let me do my refactor So you take a sprint or two and you start refactoring! but unfortunately, what often happens is that you could slide right back down and why is that I Like to think about this as recurring technical debt or technical debt on a subscription model it's like I Can't figure out how to cancel my technical debt subscription and I'm getting charged for it on a regular basis Now you've probably heard this term it's called the second system effect basically what it means is you had something you thought it was terrible Then you decided to rewrite it. But thanks to the fact that you were overconfident and You probably made the new system too complicated. In fact, the second system is worse than the first This is also summed up in a really excellent quote by the inventor of C++. he says "legacy code" often differs from its suggested alternative by actually working and scaling. Now I don't know about you but this is like utterly depressing for me When I think about my life as a software developer if this is really like a fundamental truth I have to live by. What's the point ? Is this my destiny I'm just like in this endless cycle of refactor it's gonna be terrible I don't know if it's gonna be terrible. Maybe it's gonna be good and you just keep going over and over again and That's kind of the reality in some ways. The real cost of software is not about the initial development, but maintenance over time, because requirements change you have new feature requests the business changes direction and that means our software has to. change too So the question is not really why do we rewrite software? I think there are a lot of really good reasons Why software needs to be rewritten sometimes but rather? How can we make our systems more resilient to that inevitable change? So that instead of having something that looks like this, We can have something that looks a little bit more like that, where in fact the speed of adding new features increases over time. How do we reach this promised land now. There is one answer and it is an answer that most people are very unsatisfied with. Good architecture. But when you tell this to someone, you know, and they are in the middle of problems that are maybe caused by poor architecture. They're gonna look at you and say Thanks for that. Like I really appreciate your endless wisdom, you know your philosophizing about how I'm gonna fix my problem. It's really nice And what why is it that this is the kind of reaction elicited when you when you give someone this response? Well, I think it's because to your average software developer Architecture. It's kind of like a dirty word You know because on the one hand a lot of people don't necessarily know What does the Software Architect at my company do all day? Really? You should try asking them. A lot of them. Don't really know they'll think okay this person maybe transcended coding But what comes after that? meetings writing on a whiteboard maybe writing something in the wiki. there's also the fact that software architecture doesn't really have a common definition people love to argue about what architecture really is. You can imagine if in the world of front-end. We are still bickering over things like view versus react versus sass CSS NGS whatever That you could never get all Of the developers from all of the programming communities to agree on a single definition of software architecture. We love arguing about things as developers. So that's not gonna happen and then the last and most important thing is I think most people find That this response feels pretty detached from their daily problems when I'm a software developer and I'm working in an app What I have to do is I have to change the behavior of a button Right. That's my ticket But for whatever reason in whatever context the previous person made that task extremely difficult for me. So when someone tells me well good architecture would have fix that doesn't exactly give me a warm fuzzy feeling inside so instead of trying to come up with a new definition of Architecture and telling you that now you are in this room and you have to listen and believe everything that I say. I want to kind of reframe it and think about it from a different angle and that's thinking about architecture as enabling constraints so Constraints that you put on the way that you use code and the way you use data and the way your structure your application That ultimately it can help us to move faster and more safely over time Now if this sounds a little bit abstract it helps to start with a real-world example Think about driving in a car, so I'm from the United States But when I first moved to Germany I learned about the Autobahn and I learned that there are parts of the road you can drive On them and there is no speed limit at all, which sounds like a recipe for disaster but somehow all these people managed to drive at absurdly ridiculous speeds and yet there are Comparatively few accidents and the reason for that is that there are constraints on the way that we operate on the road for instance There are physical barriers between cars driving really fast in one direction and cars driving really fast in another direction You have lanes you have conventions like using your turn signal and all of these constraints that we put in place Also help us to move fast and in a safe way. You can think about this pretty similarly in software development. Consider what happened what kind of constraints we introduced with OOP? Instead of being able to structure our programs more freely, we had to structure them in terms of classes. But because of the fact that we kind of gave away some of the freedom that we might have had, We could actually decouple the structure of our applications from the way that the code is organized, Now, think more about functional programming, this is something that Front-end developers are much more familiar with these days and one of the core restraints that you have in functional programming is immutability. Strictly speaking. You could say that mutable data is more powerful than Immutable data ,because you can just do more with it Right, but because of the fact that we give away our ability to mutate data We can eliminate an entire class of problems because we don't have different parts of our applications thinking that they own and can do anything with shared data. similarly in front-end development there have been a lot of connected progressions in the last years a super simple example. We are no longer really using "var" right now. We're using "const". and while this might seem small it can give you a bit of security because you know that that variable is not going to be reassigned to something totally different during the course of whatever function or whatever scope it's in. So you have more predictability in the way that your data is being used now. JQuery to react we're getting to the controversial part. Okay, so What I find interesting about this is that jQuery is strictly speaking gave us a lot of power right you could go into the Dom you were really like operating on it and of hands-on way and React tries to get you a bit further back from that you can always reach into the Dom but you would be going against some best practices and Now because of the fact that we are not doing direct Dom manipulation We can have more predictable and more testable user interfaces. And now this is the real controversial one and Now CSS in JS. So You know, some people don't like it. There will be a new Twitter thread every day about why it's bad but one thing that I've noticed using it for about a year and a half, maybe two years by now is that it really forces me not to rely on side-effects because of the fact that I have to explicitly share styles between different components and Maybe you have more discipline than me. But if I didn't do that you'd better believe I was would be relying on some global names and in the end this helps us to write code that is just safer. so the point I want to make is we are constraining ourselves all the time and we do it on purpose and We do that specifically to trade constraints for safety and for speed We're not looking for ways to be more powerful in how we exhibit our ability as software developers. We're rather looking for more best practices and things not to do , so for the second half of my talk I'm going to share three specific constraints that you can use not today, but maybe next week for having a more resilient architecture on the front-end and Of course, I need to make a disclaimer. It's not gonna be exhaustive right? I have 15 minutes left. but this will be something that I hope is really practical for you and Let's dive in. so we're going to talk about three constraints and specifically what they enable as a result The first thing has to do with source code dependencies what I find very interesting especially in the front-end development community is there is a lot of discussion about directory structure. Everyone is wondering well, how should I organize my components in my what directory structure should I use but very few people also think about Actually, what parts of the application is allowed to depend on which other parts? Now there are a couple of really commonly recognized ways of organizing our internal dependencies. I'm not talking about third-party dependencies. Probably the most famous one, you know is the big ball of mud. And what I like to say is that if you don't know What may not depend on what in your app if you don't have any rules about this may not touch that and so on there is a very high probability that you are operating in a muddy environment and Yeah in innocence. That's how it goes. We also have a more layered approach So you have some rules about what may depend on what and it needs to go into a single direction And you also have a modular approach I hate to break it to you, but creating new JavaScript modules does not make the code modular In fact when I talk about this, I'm more referring to things such as a micro friends approach or maybe a mono repo things where you have Elements with a really small API service area and then those things are able to call up to other things I'm not going to talk about modular because for the vast majority of people working in front end apps we are working still in a single repository in a monolithic way, so what's the big difference and Why should you care? Well, think about what happens when you introduce a change in a big ball of mud What is the potential scope of regression when you make that change? The answer is you have no idea, right you can make a promise to your QA engineer Don't worry. I made this change and nothing else is going to break but you know how it goes Once you burn that bridge there is no coming back and The reality is is that when you have a big ball of mud kind of architecture You just don't know what's going to break when you make a change and on top of that It also can introduce this unintended side effect of creating cross team conflicts Because nobody lines to have a ticket showing up on their board that has urgent marked everywhere Because another team made a change and they didn't realize it was going to affect them. On the other hand with a layered approach when you change something well, there is a certain surface area that can be affected but it's much more limited and in some way it is knowable and Hopefully if you've organized your application similarly to the way that your teams are set up, then the chance of having cross team effects is relatively contained so this is really the key difference between these two different approaches is How the internal dependencies of the application are organized? So let's look at a slightly more specific example So imagine you have an application that is kind of roughly set up like this You have your router which is the entry point to basically everything you have a separate API and data layer Which is where all of the requests are going through and you probably handle some caching duplication things like that then you have different pages or sections in your application which have UI components and hopefully some of the business logic is also going to be separated out somewhere else for easier testing and so on now the important thing is that these two pages need to be isolated from one another. so they should not be sharing things causing one page to have side effects when the other one changes and An easy way to think about that is that for each page the rest of the application may as well not exist This is not necessarily an easy thing to do It's not the most convenient but the result is that it is so much easier to isolate the impact of changes and That's something that leads directly to having a more resilient app Now when you look at that diagram, you're probably thinking to yourself if you are in front end developer You are definitely thinking to yourself What about the shared components? Because we are developers. We love sharing things. When we write shared code. It makes us feel very good about ourselves and I'm a little bit hardcore when it comes to how to handle shared code in a code base and I pretty much believe that if you can take out the business logic, there is a good chance you can stick it into the design system if that's really where it belongs or You may be better off copying and pasting that piece of code instead of introducing a dependency between those two pieces and This brings me to my next point which is being a little bit more conservative about code reuse, then you may have traditionally been taught because as developers We love dry code when you see code that you can make dry by introducing some abstraction It's like a very unique euphoric feeling and that feeling is what keeps us in software development Despite the fact that we have been rewriting the same thing over and over again for years but the problem is that sometimes in the name of dryness we tend to bind together pieces of code that Ought not to know about each other and that makes the code brittle and more prone to side-effects So I want to give you a more concrete example think about this situation you're introducing a new page in the app that you're working in and You see a component on another page and you think that component looks a lot like the component that I need So what do you do? You see that component and you generalize it and you put it in the shared folder and You think to yourself? Man, the rest of the team is gonna be so grateful to me. I Just generalized a specific component and I put it somewhere shared other people can use it You know, it's like they're gonna give me so many thumbs up on my PR. I'm gonna get promoted and That makes you feel good at the end of the day but What often happens is that you have? New feature requests new business requirements and over time that component that lives in the shared folder Tends to want to diverge but the fact that it's in the shared folder is like a really strong magnetism that keeps it together and you'll notice that this happens when you see signs like If statements or the component starts to have an existential crisis, like where am I and how should I render? and you see this kind of like branching in the component and and at the end of the day the components that Started out being so general. It could be used anywhere Can now only be used in two very specific places so thing I would just want to remind all of us is that When in doubt it is more important that code remains decoupled than it is that the code remains dry Because code reuse is not the goal in and of itself The purpose of code reuse and the reason that we want to keep code dry is to avoid introducing bugs unnecessarily, right because if you have less code By some standards you are less likely to have as many or more bugs But at the end of the day if you introduce dryness in a place that binds unrelated code together You are exactly eliminating the benefit that you made it dry in the first place to achieve So there is this very nice tweet, which I thought summarized this sentiment It says a regular person sees either a glass half-full or half-empty But an engineer sees them both and then learns in what context to see it half full and in what? context to see it half empty and If you ask me, sometimes you just need two glasses so Two people need to be able to drink water at the same time and if one person's glass slips and breaks on the floor The other person should not look at them and immediately need to draw up their glass as well because they are a couple together So the point about being more conservative about code reuse is just being critical I'm not saying that anytime you need to reuse something like please just copy-paste it like that would also not be sustainable But think about it critically and not just as an abstraction waiting to happen And that helps us to avoid coupling together code that diverges over time The last part I want to talk about is enforcing your boundaries, so how many of you have been in a team or at some point you all get together and you say Guys, it's time. We had an architecture plan You know, like things are getting a bit out of control and we need to do something about it so the whole team gets together and You make some decisions You document them? maybe you put them in in a wiki because documenting decisions is a very good thing and then you Make some diagrams perhaps to help on board the next people that will join your team and you have this amazing documentation and It starts to collect dust by the very next week and Whenever someone creates a new feature they are not looking in the wiki to check how to do it first unfortunately Yeah, so that's kind of awkward, right You spent all this time making this amazing documentation. And even the people who wrote it are not regularly consulting it. So What's the point? Why should we even try to put some? architectural constraints into our apps if at the end of the day everyone is going to ignore it and systems will just tend towards entropy and then we're gonna have to Rewrite it all over again So let's think about a solution to this now imagine you have an application That looks something like this. You have some components. There's a bunch of shared business logic Eventually you decide to clean up your internal dependency tree and you find something that could be shared among two pages you decide to implement a little bit of duplication and Overtime that logic begins to specialize based on the context in which it was in But the question is this what happens when someone joins your team a new person and They see that code they look in one place and they see this looks suspiciously similar to this code over here and Then they have that like spidey sense like an abstraction coming on and you're thinking you Know but they're really excited. They're probably thinking I'm gonna impress this team. It's my second day I'm so excited. And the question is, how can we stop them? Now there's a pretty neat technique which we introduced at Summa Which is called forbidden dependency tests now if you're not familiar with forbidden dependency tests essentially if you think about tests as a way or application tests as the way you test the behavior of your Application then forbidden dependency tests allow you to test the structure of your application From a dependency standpoint. So for example if you introduce Some kind of page or let's say I'm writing a page. I can actually write a rule that runs as part of the CI That's gonna cause the bill to break if anybody tries to depend on my code Which is like pretty empowering, right? So if you are working in the node and JavaScript ecosystem There is one specific tool that I've found for this purpose, which is called dependency cruiser and it has a lot of other options besides just Checking whether something can depend on something else. It can also do things like checking for circular dependencies it's super customizable and What I can tell you is that if you don't have some kind of system that's checking these things You can also implement it yourself if you would like to do that You really just don't know what's happening inside the application You can think you have a very clear directory structure surely Everyone's going to be following the existing conventions, but you just don't know until you're enforcing it so what this allows us to do is that it allows us to preserve the Architecture that we have in terms of its internal dependencies over time in an automated way so we don't have to wait until somebody opens a pull request to Start arguing about it. In fact, the CI is going to argue about it for us And that's more impersonal and in this case leads to less conflict. So I think that's a good thing Yeah, so Let's recap a little bit about what we've learned. So the first thing we talked about is this unfortunate truth that Software changes and that means that our code needs to change to write because we have new business Requirements new features coming up and that means sometimes rewriting things or migrating them or whatever is just inevitable We've also learned that Architecture can be seen in a way as applying enabling constraints so restrictions on the way that we use code and data that actually enable us to move faster and more safely as the time as time goes on and finally, we also learned there are some really small changes that you can make to your projects to help them evolve in a more organized way first thing is just thinking directionally set some rules in your application about what is allowed to depend on what in Order that you can build parts of your app that don't necessarily Find themselves bound to the other parts of the app. And this is also going to reflect positively on the team environment that you're in Also being a little bit more conservative about code reuse, then you might have been taught beginning in your software development career rise just thinking critically about whether it's appropriate to reuse that code and where exactly it belongs and Finally, that's all of the good intentions in the world. Don't necessarily matter if you're not enforcing them and One really useful way to do. This is by using automation and when such automation is forbidden dependency to us I'm gonna leave you guys with just two last takeaways the first thing is this anytime we build out a feature as an individual contributor even there are still architectural decisions that need to be made so Sometimes when you talk to people who our thinking about architecture, especially in the front end The first thing that comes to their mind is things like Redux and flux, and I don't know whatever is the new latest thing but oftentimes the the solution is smaller than you might think and If we start with thinking about this on the function level or the module level then that means that also the individual contributor individual contributors on the team are involved in those decisions, too and Finally, this one is like dedicated to everybody who is like part of the the front-end development community in the room I don't know how many of you there are out there And that's this that you don't have to derive Architecture from first principles. What do I mean by that? so what really commonly happens when people have problems in their web applications is they go to Google and they search for something like react Architecture or view architecture or whatever it is. They're looking for framework specific Architecture solutions, but so often the problems that they're actually encountering are not really specific not only to the framework they're using but even to the web it's just software at the end of the day and sometimes What I have found is that people who are working on the web myself or past self included are Reluctant to learn and be open to the input from other Communities of other programming languages or paradigms. It's really common to hear someone say something like you know, that's like OOP and like I thought we don't do that anymore or Well, the examples are in C++ So, of course, I'm not going to read that book but the reality is there is there are so many communities of Programming languages and paradigms that have been building huge apps for way longer than we have been on the front end So I just want to encourage anybody from the front-end community who is in this room and thinking about it To you know, just be open minded and open to learning from others So that's about it. I will tweet the slides later if you're interested I saw some people taking photos and then I change too soon. So sorry about that I'll tweet them out and yeah, thanks so much for being here
Info
Channel: GOTO Conferences
Views: 76,842
Rating: undefined out of 5
Keywords: GOTO, GOTOcon, GOTO Conference, GOTO (Software Conference), Videos for Developers, Computer Science, Programming, GOTOber, GOTO Berlin, Monica Lent, SumUp, frontend, Frontend Architecture, Software Architecture, React, User Interface, Developer Productitivty
Id: TqfbAXCCVwE
Channel Id: undefined
Length: 33min 46sec (2026 seconds)
Published: Thu Dec 12 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.