Transcript
Sylor-Miller: I've been a frontend platform engineer for at least the last 10 years. We've felt a little like nobody knows what to do with us. We tend to own bits and pieces of infrastructure but we didn't really fit in very well with DevOps or SRE. We often own large parts of the product code base, but we aren't product engineers. We've never really fit in anywhere. I'm really excited to be here, because it feels like we're getting a seat at the cool kids table finally. I've found my people.
When I was preparing this talk, I chatted with folks that I know that are more like DevOps, SRE, backend, they don't work on the frontend. I wanted to get a sense of like, what do you think about the frontend? A few different themes emerged from those discussions. What I heard from folks overwhelmingly, is that the frontend feels like it's super complicated for no reason. The tech changes super rapidly. There's approximately 5000 different libraries and tools and patterns out there. New ones come out every day, so we don't know how to keep up. I heard a lot about how HTML and JavaScript and especially CSS are really frustrating to work with. How many of you feel this way? My hope is that I'm going to change all of your minds about the needless part, because that really bothered me when I heard that. I wrote this down in my notebook, and I put exclamation points after it. I was like, I can't believe they said this to me. We're going to talk through some of the really hard problems that frontend platform teams need to understand and solve, in order to give you a high-level framework that's going to help you cut through all of that noise of the hot new framework of the month club, and allow you to reason about the complex world of frontend engineering. The reason why I think that it's important that we all talk about this is because our job as platform engineers is the same, no matter what platform we're building for. We need to deeply understand and manage the underlying complexities of all the systems that we're building on top of, so that other engineers, our customers don't have to. Sara said something about how it's our job to build those abstraction layers that help other engineers move faster. We weigh the tradeoffs so that individual engineers don't have to.
The Iceberg Metaphor of Frontend Architecture
I think that this is especially important on the frontend, because frontend platform teams are in this unique situation where we actually have two customers. First the engineers who are building our product, and they use all of the tools and the services and things that we write. We also have the second order customer of the actual users of our websites and web apps. In an ideal world, we would never give engineers tools that are going to be really terrible for UX, and vice versa. We don't want to make decisions that are great for the user experience, but make it harder to ship features. That seems like a no-brainer. In reality, this tension between the needs of engineers and the needs of users can be really hard to balance and navigate. It's what I call the iceberg metaphor of frontend architecture. Above the water is what we traditionally think of as like the frontend, aka the user experience, the HTML, the CSS, the JavaScript that are the fundamental building blocks of the web, all of your client-side frameworks and libraries. Plus, you have to make sure that your frontend is secure, and performant, and accessible. Maybe you care about SEO.
However, that is just the tip of the iceberg. Under the surface, there's a whole bunch of complexity, all of the systems and choices that we make in order to better support the developer experience, all of which actually have a massive impact on our users. How you decide to architect your design system, or do dependency management, or run experiments or build and deploy assets, all of those have just as much of an impact on your end users as the client-side JavaScript libraries that you use. Your frontend architecture is like this whole entire iceberg. We want to avoid a Titanic sized crash into this iceberg of frontend complexity. We're going to learn more about it. We're going to start by developing a better understanding of why the frontend is so complicated. Where does all this complexity come from? What are the hard problems in frontend? Then we're going to talk about the different ways historically that we've tried to solve them. Then we're going to move on and talk about how we navigate all of that complexity, particularly through the lens of your frontend platform.
Hard Problems in Frontend Engineering - HTML, CSS, and JavaScript
What are the really hard problems and constraints that make web development and especially frontend platform development hard? I'm going to talk about nine. I think that a lot of these are the hardest and the most important things that your platform should be abstracting away for you. That's why I picked these. The first constraint we have to deal with is HTML and CSS and JavaScript, the design of the worldwide web itself. The web was not originally designed to be an application framework. This is what the original website that was made in 1991 looked. You can go look at it today. As you can see, it's just a bunch of text and some links. There's no images. There's no multimedia. All there is, is static information. HTML was designed to basically markup term papers so that academics could share them with each other. Obviously, we've augmented the design, we have images now, we have CSS, and we have JavaScript. It's like a true testament to the brilliance of the web, that the same tech that made this happen, powers all of our modern interactive experiences.
What do you need to make a website? You need a web server that's connected to the internet, a web browser client. You need some HTML that defines the structure of your page, CSS to style the content, and then JavaScript to add interactivity. I think the important thing for all of us to think about is the fact that all three of these languages are uncompiled, static text files. You don't build a binary then ship it to a web browser. It's uncompiled, static test files. Anyone can open up their favorite editor and type some words and symbols, and then FTP them up to a web server, and you have a frontend platform. FTPing static files to a server doesn't scale. In order to scale beyond FTPing static files, we had to start creating all of these abstraction layers that would allow us to use other languages that would then generate those static HTML and CSS and JavaScript files that we could return to browsers inside of an HTTP response. In order to do things like reuse code, get dynamic data, run tests, run CI/CD, all of these things, we had to create abstractions on top of the core technology of the web. Over time as the way that we've used the web has changed, we've had to change our abstractions to keep up. That's why there are so many different ways to do things. We're going to talk a lot more about these abstractions historically.
Web Ownership
The next constraint that we have to deal with is the fact that the web is not owned by any individual company or browser manufacturers. There's a standards body, the W3C, or the World Wide Web Consortium, or TC39, which is the ECMA International JavaScript standard body. The process for adopting new standards is designed around consensus building. Anytime you're trying to build consensus, that means that the pace of change is going to be very slow. Everyone has to come together and agree on what the right APIs to build are, and how they should be designed. Then individual companies can choose or not choose to go off and implement the standards. A lot of the complexity has arisen over time, because engineers and designers are zooming ahead of the standards. They're solving problems before the standards and the browser implementations can catch up. Why was jQuery so successful? jQuery took all of these low-level JavaScript APIs that had different definitions and different API signatures in different browsers, and it created this really easy to use abstraction layer on top of that, that allowed engineers to just write the same code and execute it everywhere and not think about all of those differences cross-browser. In the case of jQuery, jQuery zoomed ahead, but then what happened is standards bodies learned from the lessons of jQuery success, and now a lot of those solutions are baked into the specs. jQuery is obsolete now. It's because the standards process learned from what jQuery was doing, and that cycle is going to continue.
Users Come First
The third hard problem is that when it comes to the web, users come first. With great power comes great responsibility. We have to protect user privacy and security, and we have to ensure that the web is accessible to everyone. I really love how the W3C's newly released web platform design principles talks about this, calls it the priority of constituencies. User needs come before the needs of webpage authors, which comes before the needs of user agent implementers, which come before the needs of specification writers, which come before theoretical purity. I love that theoretical purity isn't there, because that feels like a real subtweet. Somebody was like, theoretical purity, and they were like, "No, that's last." I'm on the W3C Web Performance Working Group. I'm helping to create the standards and the specifications for the future of web performance. It's been really fascinating to me the number of times that I am just like, let's expose that timing data. I just want to know like, how long did it take for this JavaScript to load? Did it come out of the cache? Did it not come out of the cache? We actually can't know that because that could be a vector for someone to get information about what websites someone has been to before. The answer is no. As somebody who writes code that tracks performance of websites, that's frustrating to me. As a user of the web, I'm really reassured by the fact that our needs come first.
You Don't Control Where Your Code Executes
The fourth constraint, which I think is really the biggest difference between frontend platforms and other kinds of platform engineering, is that the browser is a code execution environment that you have no control over whatsoever. You write a bunch of HTML, and CSS, and JavaScript, and you send it off. From there, your code runs on other people's computers, and not the cloud, but some ancient laptop that's running IE6. This is bananas when you think about it. I am so jealous of all the people who are setting up Kubernetes clusters, because you get to control everything about where your code executes. You know exactly what OS is running. You know the version of the OS. You know what the CPU is like. You know what the RAM is like. You push a button and you set the CPU the way you want it to be. On the web, it could be anything. Websites are accessible via pretty much any device these days: smartphones, smartwatches, laptops, desktops, TVs, refrigerators have web browsers in them now, video game consoles. If you could stop playing Tears of the Kingdom for like 5 minutes, you could actually pull up the web on your Switch. It's wild. We don't control any of that. We don't control how big the screen is. We don't control how the user is interacting with the code. Maybe there isn't even a screen because they're using a Braille display. We don't know if they're using a mouse. We don't know if they're using a touchscreen. Maybe they're using neither of those because they have a physical disability and they're using a switch mechanism. This is why CSS is a declarative language. CSS is actually, in fact, awesome. CSS was designed to manage this lack of control, using a declarative language. I want all of us, every time somebody complains about CSS, you say, "Actually, CSS is really well designed to solve the problems that it's solving."
The Web Is Designed to Be Backwards Compatible
The next big foundational problem that we have to manage is that the web is designed to be backwards compatible. What that means for us is that our code has to account for the last 20-plus years of technology, all different browsers running on different operating systems and different devices. The long tail of browsers is really long. The site, whatismybrowser.com, has over 219 million unique user agent strings in their database. Every single one of those represents a unique combination of factors: different browsers, different devices, different capabilities of those devices, different rendering engines in the browser, different JavaScript engines. Maybe different implementations of APIs, different levels of API support, historical versions of APIs plus modern versions of APIs. There's so much complexity inherent in managing all of this backwards compatibility. The next big foundational constraint is that you have to deal with all these combinations, but you don't actually know what combination you're dealing with in advance. That's because as Scott Hanselman, so very aptly puts it, lies, damned lies, and user agents. Those 219 million strings don't actually tell you anything useful that you can trust. They are supposed to be this identifier, but actually what they are is like a bunch of random gibberish that is perfectly easy to spoof. Spoofing a user agent is the easiest thing to do in the world. For privacy reasons, browser manufacturers are actually now starting to freeze user agents and send you less information because it's a vector for fingerprinting. What this means we have to do is that you don't know the capabilities or what JavaScript APIs or CSS features are supported, until you actually get your code into the browser, and check to see if the new hotness is supported. This is very unusual, I think, that a lot of other platforms don't have to deal with this. You don't know the boundaries of the execution environment until you get code executing in the execution environment, and then you have to write a fallback. If it's not supported, what do you do? Maybe you do nothing. Maybe you're just like, whatever, it's too cool for my users.
Another thing that you can't trust is the network. There's a whole other class of design decisions on the web that are ways to work around unreliable network connections. That's really because every request that you make is another opportunity for failure. Either you run the risk of a slower connection that slows down the user experience, and the user has a bad time, or you run the risk of losing connectivity in the middle of a session. To help alleviate the need for web browsers to go back over the network and re-request every file, there's a cache in the browser that stores your assets for you. Now we have a new problem, and it's one of the two hardest problems in computer science, cache invalidation, naming things, and off-by-1 errors. Managing the browser's cache effectively is actually one of the hardest things that your frontend platform has to do for you. There's APIs that help out with this. You do not want your product engineers to have to think every day when they write code, how do I invalidate the browser cache? You have to do it for them.
Browsers Are Single-Threaded
The next constraint is that browsers are single-threaded. This has a little asterisk there, because I need to caveat this. Modern browsers have multiple processes, and multiple threads running. There are threads outside of the browser's main thread that do things like networking. Newer browsers have some things that they hand off to be multi-threaded. To understand a little bit more about what I mean when I talk about why it's so important that web browsers are single-threaded, we're going to have a crash course in how browsers work. I gave a talk a couple years ago called, Happy Browser, Happy User, that goes really in-depth into this. Let's walk through the classic, like, what happens when I type a URL into my browser interview problem. I enter my URL. The browser makes an HTTP request back to my server. There's a lot of stuff that happens with DNS and TCP and all that, ACK and SYN, whatever.
My server returns the HTTP response, index.html. What the browser does is it starts to parse that file into the document object model, or the DOM tree. Remember, it's an uncompiled static text file. It has to turn it into this in-memory representation tree structure that represents the HTML document. As the parser has gone through and parsed my HTML, and encounters links to JavaScript, and CSS, so it goes over the network to make HTTP requests for those. CSS is a higher priority, so it gets requested first, and it comes back first. The browser gets sort parsing all that CSS into another tree called the CSSOM, or the CSS Object Model. It's another tree structure. What it does is it basically takes all of the style rules that you defined in your CSS plus the browser default styling, plus users can have their own custom CSS, and mushes them all together. Then the reason why CSS is so important, is because once the browser has both the DOM and the CSSOM, it can combine them together into another tree called the render tree, which it uses to first lay out the screen as a bunch of boxes, and then paint pixels to the screen. That's how we show something to users. We need the DOM and the CSSOM and then party, you just see something.
Let's talk about JavaScript. That comes back over the wire, and again, it gets parsed into another tree. Browsers love trees. This one is called the JavaScript AST. Basically, the JS AST gets compiled into machine code. The browser executes the code. Then it kicks off this JavaScript runtime event loop pattern, which is like this asynchronous message queue that just constantly runs in the background. When something happens, say, when the user taps on a screen, they're opening a login overlay. That action generates an event that gets put onto the event loop. Any event handler code that's listening for that event gets executed. That handler code then modifies the DOM tree directly, which kicks off this re-rendering of the render tree, relayout, and repaint of all of the pixels onto the screen.
The reason why I wanted us to really understand that is because of the fact that the browser is single-threaded means that every single one of these things is happening on one thread. This is so important when you think about performance and architecting for the web. If the main thread is busy downloading and parsing and executing 3 megabytes of JavaScript, and your user in the meanwhile is trying to scroll the page, the main thread is not going to be able to respond to the user in time. To get a smooth scrolling experience, we have to animate 60 frames per second. If the browser is busy doing other stuff, it can't animate, it's going to drop frames, and you're going to have a janky, crappy experience. Again, browser manufacturers are very smart. There are some things that are handled off the main thread like GPU compositing. Your frontend platform teams really need to understand this. I don't think we do a good job of this as an industry teaching people about this fact. You have to be able to build around that.
The Observability Problem
Our last hard problem under discussion is observability. Observability is hard in the frontend. When you take into account all the other things that we already talked about, like you don't own the execution environment, unreliable network connections, user privacy means that the user can just completely turn off all of your ability to collect telemetry. There's also this other phenomenon from physics called the observer problem, or, as I like to call it, Schrodinger's JavaScript. In order to monitor the health of your website that's probably executing a whole bunch of JavaScript, you have to write more JavaScript that also gets executed on the same main thread, as all of the code that's actually making your website work. If you aren't careful, trying to observe the system can actually radically change the behavior of the system itself. If you add too much JavaScript to try to do performance monitoring, you're going to make the site slower. This is a problem. One of my main jobs is performance monitoring, and this is a huge problem that we have to work around.
The Client-Server Pendulum
To wrap up our discussion of why the frontend is so complicated, we're going to address the elephant in the room, namely, all of those millions of different frameworks and libraries that feel so overwhelming to keep up with. I think it's useful to look at this problem through a historical lens, or what I call the client-server pendulum. Back in the dawn of time, like 20-something years ago, when I first started making websites, everyone did it pretty much the same way. You rendered multi-page apps on the server. You generate your HTML response with like a server-side language, like PHP, or .NET framework, or ColdFusion. Then you'd layer on a little bit of CSS to make it look nice. Then you use jQuery, or script.aculo.us, or MooTools to do that sweet DHTML interactivity. Maybe if you went and go really wild, you would AJAX load parts of the page. At that time, really, anytime you wanted to update or change the contents of what is on the screen, you had to make a network request. At the time, network requests were actually really slow, so that resulted in a bad user experience. Every time you want to change something on-screen, having to go all the way over the network was bad.
The pendulum swung. In order to help develop better experiences for web apps, we started using the single-page application pattern, frameworks like React. What that does is instead of sending your HTML in your initial payload, you send this big JavaScript bundle, and your big JavaScript bundle has to execute, then it modifies the DOM tree directly in-memory in order to make pixels appear on-screen. We made this tradeoff where we slowed down the initial load of pages, but it made the experience of staying on a site and interacting with it way better, because you're not going over the network for HTML, it's all there in the client for you. Over time, especially as React got really popular, people started using React for everything. It's a better developer experience. When you're using React to render a product page, or a blog article, or something that's not a long running interaction, the performance cost of waiting for all that JavaScript before you can see anything makes a pretty bad user experience.
In the last few years, the pendulum has swung a little into the middle here, networks are faster now. With the growing prevalence of low-powered mobile devices, especially in emerging markets, the biggest bottleneck is now the CPU of the user's device. These new patterns and frameworks have arisen that are like a best of both worlds mix of both of the prior approaches. Your initial view is rendered using JavaScript on the server, SSR, it's called server-side rendering. That same JavaScript then gets sent to the client where it's hydrated, for example, it takes over the interactivity. You can have it be the whole page, and you can have it be component islands, so little islands of interactivity on your page. All of these are still totally valid ways to build a website in 2023. At Etsy, we actually use all three of these: different parts and pieces for different experiences. The number of options is actually growing, like static site generation where you generate static HTML at build time, and you serve that from a CDN, lightning fast. Edge side rendering. This is why there are so many ways to do things. If you put all the different options in context like this, it's not the same problem that we're solving over again, just using slightly different methods. All of these different libraries are solving different problems in different ways. This is why there are so many options.
Taming the Complexity
Now that we've talked a lot about the problems and constraints and all the options, let's talk about how we can try to navigate all of this complexity. I'm going to start off with four very high-level approaches that you should be thinking about, and that your platform teams should be thinking about. The first thing you need to do is put users first. All of us need to do that. Without our users, none of us would have a job. Put your users first, establish UX principles. Why does this matter? If you're trying to make a decision between a bunch of valid alternatives, if you have a core set of UX principles to fall back on, that's going to help you to make a decision between different alternative options, like which of these choices is going to align with our UX goals? If you're interested in establishing UX principles, I very much love Scott Jehl's ASPIRE principles. A, because I love a good acronym. B, I love that it's aspirational. Because, pragmatically, none of us are going to be perfect. We're not going to be able to make a perfect website. Good websites aspire to be accessible to users with different abilities and disabilities. We want to be secure and reliable. We want to be performant on a wide range of devices and in unreliable network conditions. We want to be inclusive to diverse audiences. We want to be responsive in adapting to all those different screen sizes. We want to be ethical in how we handle user privacy and security. We want to be ethical about the impact that we have on the planet. The other reason why you really have to establish these first is because trying to bolt these things on later is going to fail. It's going to be an expensive failure if you're trying to make your site or your app fast when you didn't design that in from the beginning. Start with these goals and then you're going to have a better time and it's going to cost you less money.
The next big strategy is to be like Elsa and let it go. Let go of the need to control every detail because, ironically, the less that you try and control every detail, the more resilient your website or your web app is going to be. I love this quote from Steph Eckles because it really gets at the heart, "Using adaptive layout techniques is a trust exercise between designers, developers, and the browser." Steph is talking specifically here about giving up the idea of pixel perfect layouts. This idea of writing code that works with the browser, that trusts the browser to do the right thing is applicable to all the different ways that we have to design within those constraints that we talked about. Backwards compatibility relies on trust.
The next foundational thing that we can do to tame complexity is to be more like our users. What do I mean by that? All of us in this room here are in a privileged minority of people who have high-powered modern devices, and fast, stable, reliable network connections. The way that we experience the web is very different than the experience of most of our users. When we're making websites, and we're testing them, we're sitting at our desks on fast connections, and high-speed computers. We're not standing on a crowded subway train with spotty network service. This chart is from Alex Russell's talk that he gave at performance.now() conf last year, The Global Baseline in 2022. This is a historical graph of Geekbench scores that rate the CPU performance of high-end versus middle-of-the-road versus lower-end devices. What's really interesting is like 10 years ago, there wasn't a huge difference, and over time, the split has gotten bigger. That top line, that's my Apple smartphone, the very top, versus the orange line, which actually represents the vast majority of smartphones that are being sold today, is three to four times difference. We experience a web that's three to four times faster than someone who's on a low-end or a middle-of-the-road device. If you are not thinking about performance, if you're not testing performance on lower-end devices, then you're missing out on opportunities for your business, because your users probably aren't experiencing the web that way.
My kind of high-level strategy to tame the complexity is to use the power of modern HTML and CSS. I spend a lot of time griping about standards. These days, it actually feels like the standards in the browsers are not just catching up, but they're speeding full steam ahead with brand new platform capabilities. What they do is they're taking all of these things that you used to have to write a metric ton of JavaScript to do in the browser, like you used to have to write JavaScript to center a div, you don't have to do that anymore. Join me in the anti-JavaScript JavaScript club. I love JavaScript. JavaScript is my favorite programming language. My favorite thing to do is not write any JavaScript at all, and write it in HTML and CSS, because that's going to be way more robust, and it's going to be faster. The thing is, CSS can do amazing things. This is pure HTML and CSS. Isn't this amazing? This is not our typical use case. It just goes to show the power of the platform and how much it's evolved. We couldn't dream of this 20 years ago. You would have had to write JavaScript to do this. You don't have to do that anymore.
There's No Right Way to Build a Website
What's the right architecture? This is where I get to say my favorite line, because I am a staff engineer, but it depends. I love it so much, I made this website, Ask a Staff Engineer. Anytime you want to ask a staff engineer question, go there, and they'll tell you, it depends. The needs of an e-commerce site are going to be very different than if you're providing software as a service. There's no one-size-fits-all solution. We need to look at tradeoffs. As always, we start with our users. Think about your user experience. Are you displaying mostly static content so you can render your HTML on the server? Is your content more interactive and task oriented? You probably want to look at SSR or SPA? How long is the user typically having for a session? We all want like that sweet engagement. Realistically, if users typically have very short session lengths, you don't want to waste a whole bunch of time downloading and executing 2 megabytes of JavaScript, you want to get content to them fast. If somebody's logging into their account, and they're going to perform a bunch of complicated tasks, they're probably going to be better served by a SPA. They can handle that initial wait.
You also have to take into account your business goals when you're deciding on a frontend architecture. Where are your customers located and what kind of devices they typically use is going to be a factor. If you want to grow a user base in India, where most people are on lower-powered Android devices, you're going to have to care even more about performance. Maybe you want to even look at supporting a progressive web app. SEO for e-commerce and media especially is really big. SEO is important for everybody. With the advent of Core Web Vitals, Google search is now taking the performance of your site into account when they do search ranking. If you're e-commerce, speed is the name of the game.
Finally, it's important to think about what knowledge and experience your team has. Maybe all of your frontend engineers already know React, but you're a media company and you're like, "We got to care about performance now, what do we do?" You probably want to look at SSR. You want to render your React components on the server, and then layer on component islands when you get to the client. Also, think about the size of your platform team. If you have a smaller team, you're probably better served choosing boring tech. I love that Suhail talked about choosing boring. I work at Etsy, that's where choose boring tech club came from. I am team choose boring tech. Choose things that have a big ecosystem of tools around them. Most importantly, you don't have to write the documentation. You don't have to have training materials because Stack Overflow exists.
Once you've thought about all of these different factors, then you can make a start on deciding the right architecture. Maybe different parts of your site warrant different architectures. I love this breakdown by Ryan Townsend. He gave this talk just recently called, The Unbearable Weight of Massive JavaScript. He suggests actually using different approaches for different pages on an e-commerce site, based on all of these different factors that we've talked about, like static versus dynamic content, SEO, performance, interactions. As a platform team, the thought of having to support four different architectures, one for each page, is terrifying. I would probably turn that on its head and say that figuring out how to build a platform that supports four different rendering patterns, and doesn't turn into a giant mess, is actually the reason why I became a platform engineer. I love that stuff. Yes, give me a system, and I will build it and it will be beautiful, and everybody else will come in and ruin it.
Wrap-Up
When we started out, a lot of you were thinking this, like the frontend is just way too complicated. Hopefully, I've changed your mind. I've convinced you that the frontend is actually solving some of the hardest problems in computer science, like distributed computing, and asynchronous I/O, and not owning the execution environment where your code executes. The solutions that we have exist for a reason. CSS, which so many people find frustrating, is actually designed that way for a very good reason. The main thing I really want you to take out of this is like, focus on core web technologies. Don't get caught up in the framework hype. Understand the underlying reasons for the complexity.
Questions and Answers
Participant 1: I've been doing web development for quite a long time now as well. It used to be that every two or three years, it was a new framework, and we were going through a bit of a rewrite. Although in the past three, or four, maybe five years, it feels like things have slowed down a bit. Is that your experience as well? React has been here longer than any other framework I can recall.
Sylor-Miller: I think React has basically taken over. There's a lot of reasons why React has taken over with it. There's a lot of money and a lot of energy from Meta going into shipping React. I think that we as an industry have this tendency to want to have simple and easy answers. Just like everybody uses React, I'm going to use React, I'm not going to think about it. That's just the way that everything goes, I think is like an attitude that has cropped up. It is what it is. I'm a pragmatist, so you have to manage it and navigate it. I think that is why we're seeing what we're seeing. A lot of these newer frameworks and ideas are really designed around taking the core patterns of React and making them faster, and working around the problems that are inherent in using a SPA framework.
Participant 2: Writing a unit test for frontend is hard. What is your opinion on that?
Sylor-Miller: I'm a big fan of integration tests for frontends. I really like behavioral tests, integration tests, because the worst thing that you can do when you're writing a unit test is to have to mock out the APIs that are happening inside of the browser. Right now, the best option that I see for unit tests, it's called React Testing Library, which is more of a behavioral driven test where you're defining more actions that a user is taking in the browser, and then looking for the results of that, versus writing a pure unit test. You probably are writing very few pure unit tests for your frontend interaction code, like maybe your frontend backend code, because there can be frontend code in the backend.
Participant 3: I have a question about bringing this to platform engineering. When we think about platforms, it's very often like, how to be Kubernetes but better. I feel like we neglected runtimes a lot of the time, [inaudible 00:41:29]. What are we missing? How can platform orgs really accelerate frontend engineers, and make their lives less terrible?
Sylor-Miller: I think that you need to learn about it. In all of my years as a frontend platform engineer, sometimes I report to the infrastructure org, sometimes I report to the UX org, sometimes I report to product. Nobody knows what to do with us, I think because the code that we write, and the problems that we're solving span across this entire distributed system of all of these web browsers and all of our servers and all of the different bits and pieces. People tend to think that frontend engineering is not as cool. We don't get paid as much as backend engineers do. I think and I hope, especially now that JavaScript is everywhere, that platform teams are going to have to learn about it a lot more and learn how to support it.
Participant 4: Can you think of any times circa to us, where you've been tempted or decided to put things into your platform abstraction away from the frontend engineers, and it hasn't gone well, [inaudible 00:43:10] for other reasons?
Sylor-Miller: I was on a design systems team for quite a long time. The job of a design system is to provide reusable UI components that other engineers can then use. They are Lego blocks of UI components, basically. We noticed this problem where other engineers were basically copying and pasting HTML around and all of their PHP in mustache views. What that meant is that every time we had to go in and change a component, we couldn't find it because maybe they copied and pasted the wrong thing, or they modified it a little bit. If we had to fix the accessibility of something, it would be impossible, because there were all these different versions everywhere. We created this abstraction layer in our mustache templates that would allow you to reuse components using like a shorthand. I think the problem is that we built this thing to solve our problem and we didn't explain to engineers well enough why it was going to solve their problems, too. The adoption of it was really low. What we ended up doing was we ended up talking to a bunch of people, and we made a really small change where the default code view in our design system documentation defaulted to showing this pattern, because people were just copying and pasting the default. People started actually copying and pasting the thing we wanted them to copy and paste. The lesson there is, meet engineers where they are, and make sure that you're understanding how they're interacting with your tools and where they're looking at your tools. Then that's going to allow you to better sell to them why the things that make your life easier also make their lives easier.
See more presentations with transcripts