Kent C Dodds === [00:00:00] Hi there. And welcome to pod rocket, a web development podcast brought to you by log rocket help software teams improve user experience with session replay, error tracking, and product analytics. Tried for free at log rocket. com. Today. My name is Paul and joined with us once again is Ken C. Dodds. He's software engineer, educator, and blogger. We're here to talk about how you should stop lying to your users when you're developing. ~Transcribed ~What a headline. We're all lying, right Kent? it's a little bit presumptuous, but I think that people will be able to see this lie within themselves and accept it. Yeah, I'm excited to dig right in because this is something that everybody who has ever used a website is probably interacted with, and it will be cool to actually discuss how we can tackle this problem, because I'm sure if you go to somebody, you're like your website does this, and it does content layout shift, and they're gonna go, Wow that's just ~that's ~the stack. And we can't really do anything about that. So we're going to talk about how you can do [00:01:00] stuff about that. And I also would love to get an update on The epic stack because last time we were on we were talking about the epic stack and how's that going? How's adoption? I myself made a little mvp in it. It was a lot of fun appreciated the template. So just curious ~Yeah. ~Yeah. Super. I'm glad that you had a good experience. Yeah, the Epic stack is going super well. ~The the. ~A big reason that I put the epic stack together was because lots of the JavaScript frameworks don't have enough opinions for people to just hit the ground running. Like you can boot up a blog pretty quick on anything, but when you want to build an ~app, ~Application that has user authentication and all of the complexities around data management and stuff. There's a lot of work that you have to do. And yeah, I just said there's a lot of overlap between the different types of apps that we're typically building. And so if we have a template that has all of those things already done for you, then you can proceed from there. ~It's not quite as ~it's not quite [00:02:00] like what you get from Laravel or rails where everything is weren't, yeah, in the JavaScript ecosystem, we just piece together a bunch of tools and we wire them together. And there we could have a whole podcast about why that is. But yeah, so it is here's a bunch of tools that are already prewired for you rather than a cohesive. Application development experience. But in the future, maybe it will be something like that. But yeah, things have been going really well there. It's incrementally adopting new features of the various tools that we're building on top of. I've got a lot of contributors to the stack as well, which is really cool because with the stack, ~the ~there's not a lot of direct personal gain that people get by contributing back because once you generate your projects, you just had to work on your own project and you can make all the changes you want. Having some changes in the template doesn't really affect your experience ~as~ as you're building your app. And so anybody who's contributing back is just doing it because they're awesome and nice [00:03:00] and like just trying to give back, which I think is cool. But yeah, lots of really great contributions over time. ~And so ~and then Epic web, of course, is the series of workshops, or at least what's on there right now is a series of workshops of how to build the epic stack. So you really get a deep understanding of how the stack works, and then how to build efficiently with it. So anyway, I'm glad that it was helpful for you. Yeah, definitely those ~like ~strong opinions and the way things were pre wired. It let you focus on the app logic So was definitely was a fan and I recommend people checking it out if you want to ~like ~just Crap out an app as fast as possible. You just want to hit the ground running. Like you said, it was really great for that. So I'm glad it's still going. I'm glad the community is thriving. We got contributors. I'm improving the template. So I did mention content layout shift. We mentioned line. Let's hop right into that because maybe people are thinking, Oh, I know what these guys are going to talk about. They're talking about the button that was there when it wasn't there initially. And on, on your blog [00:04:00] posts, you have some great examples. My favorite one actually was the Wikipedia one. So could you please explain to me the concept of lying to users straight from the Sure. Yeah. So in the blog post on Epic Web, I give a couple of examples to see if people can guess what the lie is that I'm talking about, what lie we're telling our users. And yeah, I give a couple of examples. The Wikipedia one is where you load up the page. ~This,~ The video I took was back in like December, I think when they were doing fundraising. ~And so yeah, ~you load up the page and then once it's finished loading, you start reading the article and then the fundraising banner shows up and pushes the article down. And~ like we, ~we've all experienced this ads are probably the most notorious culprits for this frustration for us. And what's funny is the article that I am demonstrating is the Hawaiian missile alert. ~Like the what was it? The ~the false missile alert back in 2018. And ~then ~At the time, there was this joke that was going around of like how this [00:05:00] possibly could have happened. And somebody put together like a little video that showed like a web app that had send test alert and send real alert. And when they went to click on send test alert, an ad popped in and bumped it down and they accidentally sent a real alert which I also included an article. Because yeah, like this is our experience. I experienced this on Amazon. I experienced this on on chase on YouTube, like you see this everywhere where things are just~ bop~ popping around in different parts of the UI and not just on the web. Another example that I give is on~ chess~ chess. com, the mobile app. There's an ad that pops in when you want to click on rematch, you might accidentally buy a Coke or something like, so it's just you know, pretty pervasive, but it's not just about content layout shift either. So really ~the~ the last example that I give is YouTube. And ~what is, ~what happens with YouTube is you load the app and initially you get like a basic HTML document. That has like just nonsense. There's [00:06:00] nothing in there that's useful. It downloads 1. 3 megabytes of javascript and which just like it's so stupid. But so once that javascript finally is downloaded, it runs and it can render a UI that is specific to you and it's got like videos to suggest and stuff and it includes the search bar. But they prevent the default behavior of the browser which would make the search bar function. It causes a full page refresh. That's what the browser does by default. But~ yeah, ~so they prevent that default because we don't want to get full page refreshes. But they haven't downloaded enough JavaScript for it to actually work. ~They,~ you need another 500 kilobytes of JavaScript. For it to work. So what they do is they prevent default and then they clear your search term. But then nothing happens other than that, which is just supremely frustrating because the web platform knows how to deal with that. And so if they just don't prevent default, then it would work fine. And so it's more than just content layout shift. It's also when an app [00:07:00] appears to be ready to use, and then it's actually not. And that is what, like my personal crusade is to get people to not make their app look like it's ready when it's actually not. There's of course, there's a spectrum to this my own personal website. If you're looking at it on mobile the menu nav is all Powered by javascript because it's doing some fancy animations and I'm not very good at that. And I actually had a contributor help me with that. And so yeah, until the javascript downloads that menu button is not going to do anything. So like I admit that yes, I also am lying to my users in certain scenarios. But this is something that I think we should ~just ~be ~So ~Constantly thinking about is, are there situations when users are using my app that my app appears ready but is not actually ready for them to interact? And how can I prevent those problems? Yeah, it totally seems like there's a spectrum like you said there's different [00:08:00] levels of offense You have the regular content layout shift, which might be frustrating I guess but then you have like content layout shift where they Strong handed my arm into buying a coke Which feels like notably worse than the last one Yeah. ~And then they had ~and then there's like the YouTube when you talked about so if I were to can that it's You ~put your you could ~put your search term in and then it clears it on the second javascript load because of The way they handled the no reload No it's even worse. You type in your search term. ~So ~so there are three things that happen. First, it loads the nonsense. There's nothing on their html document that's coming from a cdn. And then ~and ~that starts the loading the 1. 3 megabytes javascript. Once that is finished downloading, then they render the U. I. That includes a search bar. And then they start loading 500 additional kilobytes of javascript to make that search bar function. But while that 500 kilobytes of javascript is loading, The search bar you type in it, you hit enter and it just clears so you can type in it [00:09:00] like six times hit enter and it just clears ~the~ your search over and over again until that 500 kilobytes is done downloading. I experienced this as an actual user. I wasn't ~like ~hunting around the Internet to find really bad user experiences so I can talk about them in my blog post. So I Was just really frustrated because I was on a poor network connection. I typed in my search return. It went away and I was like, what the heck happened here? What is this? Such garbage. And it's been like this for three years. I discovered this three years ago. They haven't done anything about it. Which is just silly to me, but yeah, that's probably to me of all the examples. That one's ~the~ the worst Because it's just so easy to not get wrong. First of all, I shouldn't have to download 1. 3 megabytes of JavaScript to do a search anyway, because the browser knows how to handle a form. You don't need JavaScript to do the form. It'll do a full page refresh without the JavaScript. Okay, that's fine. It like because I'm downloading a [00:10:00] whole bunch of stuff I'm not going to use anyway because I'm going over the search page and so may as well full page refresh. It doesn't make it a big difference. Or if it really mattered to you, you could make the search function with JavaScript with just like 10 lines of JavaScript that's just in line in that HTML document you have on the C. D. N. So like you could like a lot of people when they go to YouTube, they're going to search for something. So maybe there are reasons that they have for this. Like they want to make sure that you have a chance to see their algorithm suggestions and stuff. So they don't want you searching so fast. There could be stupid reasons like that. But I'm just talking about what Is a good user experience and that's not it. That is a really bad user experience for me. I guess we can hop into some of the things that you think would remedy this. Oh, yes, that's exactly what's going through my head. So if I remember back to the epic stack, one of the things that was a little bit refreshing when I was [00:11:00] using it is the hail to web standards. It's let's use web standards. It'll probably be fine if you do it with the web standards. Do you think that applies here for line to users like is because line is like happening because people are trying to do fancy custom this fancy custom that and it's like there's a lot of things you need to take into account to do fancy custom correctly, Yes. ~Yeah. ~100%. And the web platform is continuously evolving as well to make it so that we need less custom stuff and we can rely on the platform that has taken accessibility into account a lot better than we typically do as regular developers. And. Also progressive enhancement, all of that stuff. Yeah, 100%, if you rely on the platform, the end result will most likely be better than if you try to do your own version of a thing that's not always the case. And there are definitely holes in the platform and the [00:12:00] user experience that has to offer just as a really easy example. The web platform says you put a form for any mutation that you do. So let's say we're building x. com or Twitter, I guess it's still twitter. com. So Elon, if you want us to call it X, you got to change the domain. But anyway, so let's say we're building that and you've got the heart icon. And if you click on that, the web platform says, okay, that's going to trigger a full page refresh. So we can go get the updated version of the page. Because when you first got it, that post wasn't favorited. And now the post is going to be favored. So we got a full page refresh. That's what the platform says. And so that's one of the, like a really great example of how you can enhance the user experience to make it better by preventing the default behavior and building your own implementation of reloading. At least the portions of the page that are important. ~The but ~the fact is ~like ~the web platform does a lot for you. And so if you are building your own version of that, then you have to think about a lot of things. What do [00:13:00] you do with race conditions? What if they click it like 30 times? ~What if~ and~ there are like,~ maybe you've got a sum total of the number of favorites. You got to make sure you update that because the web. Like the default behaviors refresh the whole page. You never end up with stale data unless you've got like some server side cash or something that's separate to this conversation. But yeah, so the web platform is like it's going to be correct. It may not be the best UX possible, and you can enhance that with JavaScript. ~But but ~the baseline is functional. And so this is why progressive enhancement is so important is that The enhancements that you're bringing along with JavaScript or even CSS those don't show up right away. The user's got to download those. So they get the HTML first and then they get all of the your enhancements. And so during that brief time period between when they get the HTML and when they get the JavaScript, you're showing them stuff that looks like it works. You're showing them buttons, you're showing them links. And if those things don't work, then that's a really. Poor user experience [00:14:00] on top of all that, of course, is the like whether or not your server rendering dynamic stuff. And I think a big reason why we experienced a lot of this cumulative layout shift is because ~the ~A lot of us just decided, you know what? I don't care about server rendering because it's really complicated for some reason. And we're going to just load all of the data on the client. We'll have, maybe we'll do SSG. So we generate some of the stuff, but like anything dynamic cannot be SSG. And so we have to load it on the client leading to a really terrible user experience there too. This is the chase. com example where they have an index HTML on their CDN that like literally has the header, And the footer and none of the middle content and they load the middle content. After the JavaScript shows up on the page, it's garbage. It's so bad. And I don't mean that the people who are building it are garbage. They're people and they're great and I love them, but the thing that they put together, yeah, that's garbage and they should make it better and they can there are, of course there are constraints that are in [00:15:00] each one of these apps that I'm not privy to, but I think that if we cared a little bit more about the user experience and, like that actually does affect the bottom line. So even you can convince the business people that this does matter also. But yeah, if this was a priority, then our experience using web apps wouldn't be so bad. Yeah, I would love to continue delving into some of these things that you're getting into now, Kent, which is like how you could maybe avoid it. Like maybe you could server side render what is a really good one. Maybe you could use the form and just let it refresh because maybe that's fine. And You get to progressively enhance it. There's a couple others that I know you, you have in your head. Before we hop into those, though, I just want to remind our listeners that this podcast is brought to you by log rocket. So if you're building an app, and you want to figure out how to make a better user experience, get ~he map ~heat maps of what your users are doing full session [00:16:00] replay about where their mouse is moving. Go get it. get log rocket, you'll spend more time building less time in the console log debugging, and you can try it for free at log rocket. com. So hopping back into what people can do, just in general, to get a better user experience, stop lying to their users. Something else is cookies, right? Because we're always talking about people say, Hey I need this custom thing, because it has to go fetch the data, then it has to figure out like what options to put there. How could cookies solve that? so the thing is that for a while with a single page app era that we were in, and a lot of people are still building apps this way. When. You request the html document. You can't have anything dynamic in there because it's shared across every user that you have. And so you have to request that document and then you're going to check local storage or something for your JWT, your jot that you've got in there. So you can make requests for data. And so this is a waterfall that [00:17:00] results in spinners all over your page and A really not great user experience there. But the problem is that if that is your architecture for your authentication or user preferences, then you're actually, your hands are tied because when even if you do server render stuff because when the browser makes a request it's not going to send that JWT that you've got sitting in your local storage, whatever, which, by the way, I should say that you should not put authentication information in local storage is very insecure. Don't do it. But cookies, on the other hand, they are secure and When the user goes to that URL, they're going to be making a document request and cookies are going to be included automatically. The browser handles that for you. And so then you can server render all the dynamic stuff. And so when it shows up for the user, you have no spinners necessarily. And you can have that experience loaded instantly. And some people will say, Oh, but that's gonna, [00:18:00] that means I need to have a server running to handle generating that html. And my question is always you already have a server running to generate that json. It's not more expensive to serve html than it is to serve json. The servers don't care. It's all just strings to them. That argument never made sense to me. But yeah. So ~I, ~I. Recommend server render your stuff and if performance is a really important thing to you, then distribute your application, distribute your data. If you can there are certainly situations where that is a really difficult thing to do, but many situations you can have read replicas all over the world and everything. That's the way I build my apps. That's the way I teach people to build apps and it's awesome because, you can have your performance. ~It, ~this is actually the funny thing here is Vercel likes to say that what they deliver is dynamic without limits. But there couldn't be anything further from the truth in my mind. And actually for cell backtracked on the edge. And the reason is because when you deploy to [00:19:00] the edge, you're going to have your database in one region and then the edge servers have to go all the way to the database for every query they're making. And it ends up being a lot slower. And yeah, that's 100 percent the truth. And so ~they, ~they backtracked and now they don't recommend deploying your app to the edge. But what they missed is you have to deploy your data to the edge as well. When you deploy your data to the edge also, and again, like not everybody can deploy their data to the edge. Maybe they've got just like way too much data to replicate or they have ~too many~ too much incoming data. Like maybe you're log rocket and ~you're taking a bunch of like ~you're ingesting a bunch of events from like a bunch of apps. That's like too much. You can't replicate that, but you don't have to replicate that part. Like you could replicate other parts. But anyway if you. For the vast majority of us who can do data replication and deploying our apps to multiple regions all over the world, then yeah, your app can be crazy fast all over the world, totally dynamic, no limits. And I guess I should, Caveat the no limits by saying I just [00:20:00] literally described a limit where if you're ingesting too much data, then maybe that's a limitation. But for the vast majority of us, it is a much better experience for the user if they can hit ~your, ~Your app and they get all of the data that they want right on the initial load. No spinners make your app faster. ~There, ~there's so much, like we could go so deep into all the nuances with this and maybe you want to have some dynamic loading of some stuff. And so out of order streaming that react is enabled in the last couple of years, it's making that possible and stuff like that. But anyway, um, the idea of stop lying to your users is just think about the situations where. You have an app that's showing that is not quite ready for the user to interact, whether that be additional stuff that's going to be loading and like moving things around or like buttons that don't actually work quite yet and see how you can minimize that as much as possible. The other thing that I mentioned in there is like how ads are popping [00:21:00] things in and out of place and stuff. And Ads are an especially ~tricky ~tricky one. My first recommendation is just to burn the ads and find a different revenue model, but not everybody can really do that. And instead of what you do is you push back on the ad companies and say, this is the window that you get. It's gotta be the, this, these dimensions and that's it. And I've never worked in that industry, so I don't know how well that would fly, but that's what I, To do so that then you can use aspect ratio and CSS and you can say, here's the block for the ad. It's not going to move anything because we've got a spot for it and that can load in the background or maybe see if you can server render the ad to like, why not? So just look for ways that you can make the user experience better, please. Yeah, like how succinct it is in the end. And I also appreciate the myriad of examples that we have went over. And right now you just hit the last one that I want to ask you about, which was like proper sizing of stuff [00:22:00] like make boxes make placeholders. Is that the general takeaway there? And it's not just ads it's also images and things. So in my blog post, as I was writing it, I was like, Oh yeah, I've got a really bad lie on my own website that it's been an annoyance for a long time for me. So on the top of every page on my website is an image that will load in and it animates in, and it looks really cool. So I liked the animation. Technically is like stuff moving on the screen after load. But I think that it's actually cool. So this is what, where things get nuanced, ~but~ but it shouldn't move text on the screen. ~And ~and it was because like, if the image wasn't in your cache or something, or it took a while to load for some reason, then the text would just be up here and then the image would load and I'd get pushed down. And yeah, just use aspect ratio on that thing. And now there's a placeholder for it. So if it does take a while to load you, you might look at that and be like, Oh, that's weird that there's so much space there, but you're going to start [00:23:00] reading and when it finally does load in, it's not going to bother your experience. Like I said I am guilty of this just as much as anybody else. What I, so this isn't just me telling the world that they're wrong. This is me telling us all that we can do better. And that's my goal. We love improvement and it's, and again, it's very concise and it's a very honest, call out for everybody who builds on the web. We keep mentioning your blog. Also, Kent, and we're like, Oh, yeah Kent said on his blog, and you have this example on his blog. For everybody listening, Kent has a blog. I'm sorry, we didn't go over this in the beginning, per se. But where can users read more about what you're writing? Yeah. So I have a personal blog at kentcdodds. com and then on epicweb. dev I have another blog there where I write lots of my more recent stuff as well as I have other instructors who are on epicweb. dev That are writing articles there as well. So and there are also like free video tutorials. I've got one on how to use AI [00:24:00] assistance ~and one how to~ actually I have one on how to deploy a distributed application with distributed data that is also free. We've got one. About using Git that is another free one. Lots of really good stuff on there. And then I just ran Epic Web Conf, year one, couple weeks ago, about a month ago. And all of the talks for that are up on Epic Web as well. It was very good. People should definitely take a look at all of that free stuff that's on Epic Web right now. Awesome. And that's epic web. dev. Yep, because I want to make you an Epic Web Dev. I love it. Kent, thank you again for your time coming on a pod rocket. Always appreciate it. And we'll look forward to having you on in the future to talk about some more of these ~like ~esoteric topics about development and the quality work that we're putting out. Super. Yeah. Thank you, Paul. I always appreciate being invited back. That's the best compliment anybody can give as inviting somebody to do it again. So thank you. Heck yeah.