EPISODE 1731 [INTRODUCTION] [00:00:00] ANNOUNCER: React is an open-source, frontend JavaScript library maintained by Meta. It was first released in 2013 and is now the most popular web framework. Ilya Gurevich is a Senior Software Engineer at the New York Times. Last winter, his team set out to implement React 18 for the Times flagship core news site. Ilya recently wrote a viral blogpost about this decision and how the team tackled some of the engineering challenges along the way. Today, he joins the podcast with Gregor Vand to talk about adopting React 18 to enhance the performance of the New York Times website. Gregor Vand is a security-focused technologist and is the founder and CTO of MailPass. Previously, Gregor was a CTO across cybersecurity, cyber insurance and general software engineering companies. He has been based in Asia Pacific for almost a decade and can be found via his profile @vand.hk. [INTERVIEW] [00:01:09] GV: Hi, Ilya. Welcome to Software Engineering Daily. [00:01:12] IG: Thank you, Gregor. Happy to be here. [00:01:15] GV: Yeah. You are a senior software engineer at New York Times. We're going to be diving into kind of quite specific topic today of a React 18 upgrade that you and your team went through fairly recently. But it would be great to just hear actually what's taken you from before New York Times, up to New York Times in terms of your software career. [00:01:39] IG: Yeah. I graduated from Georgia Tech in Atlanta in 2016. And I, at the time, was working for an elevator company, ThyssenKrupp. I was working on touch screens for the elevators on the system that was kind of the new thing about elevators. But my brother actually was one of the original people at a startup called Loadsmart, which was focused on trucking and shipping optimization and logistics. And he had been there for two years and he wanted me to, I guess, work with him. And that basically led me to have a job in New York, New York City working for Loadsmart. We both worked there. My brother was there for four or five years. I was there for three and a half years. It was just an incredible opportunity. And it was one of those places where the house is always on fire and you're also trying to take care of the baby that's in the house. And it was very intense. But I learned an incredible amount from that kind of scenario. And taking accountability for your own projects and just being kind of a self-starter. And the company ended up kind of growing in many ways. But after that, I ended up leaving and I ended up getting a referral at the Times. I was giving a talk in Brazil about converting from Angular to React for Loadsmart. And another guy from The New York Times, he saw me there and he, I guess, was impressed and gave me a referral to want to work at the New York Times. And then I've basically been at the Times since 2019 now for about more than 5 years. It's definitely been an interesting path to go from a startup to what is essentially like a pretty large company, very high visibility. It's just like a totally different realm. But I feel like with my startup experience, just being really self-motivated to tackle problems head-on no matter how large or small they might be has really helped me, I think, be successful at the Times. For some reason they feel like, "Oh, it's just like a simple website. Text and images. How hard can it be?" But we have a pretty serious operation. Yeah. It's just everything spanning from CMSs, to payment subscriptions, metering paywalls, all that stuff that's like a lots of teams are involved there. [00:04:00] GV: Yeah. Wow. I mean, as you call out high visibility, I mean, there are few platforms that people get to work on where it probably touches just the number of people each day that New York Times hits. [00:04:13] IG: Yeah. For sure. For sure. I mean, it's a system with billions of requests a year. Millions of views a day. You're definitely working on caching layers on CDN all over the world. How you distribute things effectively and quickly? It's definitely a question that we focus on pretty frequently, I think, internally. [00:04:35] GV: You wrote an article. It appeared on - I believe it was like New York Times Open Team. Is that the - [00:04:40] IG: Yes. It's sort of our blog area for technical writing. [00:04:44] GV: Yeah. Okay. Great. Yeah, listeners can go look it up. New York Times Open Team. It's on Medium, I believe. And this article caught our eye at SE Daily about how New York Times had upgraded to React 18. I guess we're going to kind of just start with the basics of why upgrade to 18. I think I'm aware that New York Times a while back was on Angular. And then React 16 was the first version of react, I think, that New York Times went to. But you can maybe correct me there and then carry on. [00:05:18] IG: Yeah. I think when I came in, the website was, at least the core news website, was on React. React 16. But I think before that, many of the content was actually rendered in PHP. And I've actually never had thankfully the chance to look at any of that code. But I came in on the sort of the last leg of migrating pages from PHP to React. I migrated a few of the bestsellers in the video page and a few other minor pages that were still on PHP at the time to React. But as far as sort of the decision to migrate to 18, I think it was just really one of those things that's kind of a natural impulse to keep your systems up to date. And it's the same thing as we're on Node 18. Let's upgrade to Node 20. And many times, for no other reason, then maybe it's just best practice. I think that was sort of the initial - maybe we hadn't quite recognized how different React 18 was from 16. Maybe the approach was just, "Oh, it's due diligence. Let's upgade our dependencies." I think as we got really started to become aware of and realize that React 18 is kind of a significant paradigm shift for React, it kind of just became more critical for us, especially with some of the newer features that it has to offer. And we can sort of get into those specifics. But a lot of the stuff around concurrency and batching state updates in a more efficient manner, this future that many people are still kind of navigating around as it relates to React server components, I think those are sort of some of the guiding, really just, I guess, lights to strive for and to realize in part of this upgrade. [00:07:05] GV: Yeah. Before we kind of maybe touch on what it brought, and, also, there's a sort of very specific, I think, area we'll touch on the embedded interactives, which was a huge sort of part of the article and as a huge part of New York Times the way the platform is able to deliver content and be able to help journalists deliver the content they want, maybe just walk us through just literally the steps. You sort of detailed out the critical steps that were actually needed to go through this upgrade and a couple of kind of gotchas. And I think that's kind of interesting just to touch on. [00:07:36] IG: Yeah. I mean, from the outset, it became clear to us that before we could even tackle the upgrade itself, we needed to get rid of a deprecated library that essentially - or maybe not a deprecated library. But just a library that's not compatible with React 18, which is the enzyme test library. And I think it was one of those things where you look at the code base and you're like, "Oh, man. This is going to be a lot of work." Because it's like upgrading or migrating your CSS styles from one system to another and you have thousands of classes. It was definitely one of those things where we realized, "Okay, we want to actually explore React 18." We can't even do that because all of our test files will just fail. And we're not going to just ignore these pretty critical integration and unit tests that allow this functionality to operate. I think, over time, we just sort of made a decision to, "Okay, React 18 is pretty far off for us to tackle in a concrete way." And we have a lot of other priorities to manage at the same time. Let's just slowly but surely try to edge ourselves away from enzyme in general and maybe move to this newer library, the React testing library, which was already becoming kind of this new standard for testing. Particularly in the unit test environment. And let's just soften the blow and just really distribute that over even over the course of like a year or maybe a year and a half. And that's kind of what happened. We first migrated essentially hundreds of files to this new library, these test files. And it's actually interesting, you kind of realized that some test files might not even have been written in kind of the right way at that time. And as you develop an intuition for how a component should be tested and then you kind of look at how it was written at that time, maybe you realize maybe we're not actually getting value from this unit test. Let's rewrite it. And maybe we can actually give it the opportunity to validate the behavior that we actually want to validate to begin with. It's sort of like let's revisit some tests that maybe are not serving us any longer. And then, also, let's migrate it at the same time. That process kind of lasted, as I said, a year and a half, if not longer. But as we realized we're getting closer to the end of it, it became sort of like a mini-marathon of like, "Okay, we only have 100 more tests. Let's just crank them all out." And it became like a mad dash in a way of the next two or three weeks of just like let's just try to get as many of them out there as we can. And eventually we finished that side of the work. We felt confident that we were in a good place. What would it look like to actually start upgrading not just React but the associated dependencies that React requires? But we wanted to do that without actually implementing the latest APIs. React has these two new APIs that allow server-side applications to hydrate content when that content is rendered on the browser. And that API is hydrateRoot. And the other one is if you just want to render something on the client, that's called createRoot. Versus like reactdom.render and reactdom.hydrate. We actually wanted to just upgrade all the dependencies but not turn on any of those features. Because when you actually upgrade the dependencies in place without upgrading or using the new APIs, you still have to actually have - there's a lot of other steps in between like fixing all your type definitions. There's actually a few tests that broke as a result of that that we needed to modify. Basically, things of that nature. But once we, again, very slowly but surely cross that off the list, you've updated all your dependencies, you've released it out into production, nothing is breaking, now you start to get an intuition for, "Okay, let's actually try to use the new APIs and sort of see what happens." And I've actually upgraded a few other systems to React 18. And many of the time, it was actually quite uneventful. Our CMS, which is also custom-built that is a sort of like a Google Docs-like engine that uses like ProseMirror, and React, and Firestore, a bunch of other integrations, a whole other complex system, I had actually upgraded that from 16 to 18. And there was like a minor issue related to automatic batching that I resolved. But for the most part, it was like relatively uneventful. I felt that, okay, New York Times website is not even like a real-time editor. It doesn't support support like comments and the way that Google Docs does. This should probably be a little bit simpler. But the reality is it turned out to be completely the opposite. It was significantly more complicated. You sort of turn on the engines and you feel like you're kind of going forward and everything is smooth. But then the engine starts sputtering. And that's kind of exactly what happened particularly with our embedded interactives. Almost all of them on the production website looked bad. And the newsroom and the graphics editors that take a lot of care and take a lot of time to make these look good for critical news stories immediately started ringing alarm bells. And we're like, "What's going on here?" The news room is critical to have the news displayed in the right format. Especially because of that visibility that we mentioned before. And we realized immediately, "Oh, okay. Maybe we didn't actually do our due diligence here. Let's revert. Let's peel back the complexity here. Let's just go back to the way things were. No big deal. No harm, no foul. Let's investigate." And that started a pretty long process of fixing the things you mentioned earlier, like the embedded interactives question. Because most other bits of functionality on the website were actually not impacted. [00:13:17] GV: A couple of points there. One's like a softer point. And then we'll maybe go into the engineering. I'm curious what kind of - maybe you didn't have to do a ton because you were to like revert so quickly. But did you have to do any kind of like retro report on like why is an engineering team you did push this out. I'm speaking from experience here where I did something very, very similar. Managed to completely block buy buttons on a website once. And, yeah, we had a team that - it was actually for a company, a multinational. But this was for their Argentinian team. The Argentinian team were incredibly frustrated at me and had to write a lengthy report to show why we were not going to - why we took this very seriously. But that seemed to completely turn around the situation. I'm just curious if you had anything like that. [00:14:02] IG: Yeah. We definitely did. It's not like we just deployed to production without checking. We definitely did have a QA process. And that QA process really just involved like let's look at all of our main asset types, like articles with videos, articles with slideshows, articles with so and so feature, opinion articles. Basically, we had a list of what we thought were sort of encompassed article types. And you give that to the QA team. You test across. We actually don't have a single web server that powers nytimes.com. We also have an additional web server that powers article and homepage content inside of the apps. Sort of those are web views. It's not actually built natively. We have two web servers powering NY Times content. And so, that QA process tried to be thorough. And I think the reality of what happened is that actually we were probably just using outdated articles and outdated content. And what I think was probably a normal QA process. It's actually quite rare to make completely overarching sitewide changes. Most of the time, you QA, you're kind of testing out a button here, a button there, a feature here, a feature there. It's pretty rare to make a comprehensive change across that may or may not affect millions of published articles. Not to mention that being like pretty difficult. There was a QA process. We followed it. But it, obviously, was short of the mark. And, obviously, the newsroom and the graphics was clearly not happy with that outcome. And I think when it became clear that the issue was much larger than it appeared on the outset, we completely shifted our focus to really just try to be as thorough as possible next time. I think one of the other sort of - this is perhaps like a somewhat cultural component of the Times itself is that, oftentimes, you have to work at the pace of the news. Because as everybody knows, the news can change on a dime. And our release process is pushing domain. We often times have to make changes so quickly that following a QA process in a preview branch, we're just going to be pushing directly domain and it's going to go on to production 10 minutes later. And that's how frequently we might have to or how quickly we might have to make changes. And I'm not saying it's a good thing. But that's sort of how the culture operates a little bit is people tend to work fast. And I think I was just personally guilty of that. But after it became clear that this was a bigger issue, we totally reevaluated. We spent the next like 2 or 3 months months digging into this problem and coming up with the most comprehensive QA lists we could amongst our core graphics types or our core embedded graphics types. There's actually a lot of different - and maybe this is like where we can get into like the meat of what the issue was. We have embedded interactives that allow graphics editors and the newsroom to sort of publish one-off little self-contained HTML, CSS and JS, I guess, blobs of visual information without necessarily needing to publish that from our CMS or without necessarily needing to do like a redeploy of our core infrastructure. [00:17:15] GV: Yeah. These are sort of like graphs, maps, charts, that kind of thing. [00:17:19] IG: Yeah. And some of them could be very simple. Sometimes it could be just like a satellite map that has information displayed. And that could be an image but it has information display played in a slightly different way that it's better to render as an SVG. And that SVG is just much quicker to be rendered through some system rather than uploading it as an image and then have the image have be not as high of quality as you want it to be. Other times, it can be much more complex embedded interactives that might span the whole length of the page. Whereas you're scrolling down, you have things flying in and out. You have texts being highlighted and unhighlighted it and then text moving up and down. And there may be a video in the background that's playing as you're scrolling. It can span from the simplest to the most complex component. But one of the things that graphics developers have always appreciated is that they don't necessarily have to fundamentally care too much about how they wrote their component. If it works in a self-contained environment, not even wrapped in an article, for example, if it just works on its own, then they're trusting that when they put it on the website on an article it's going to work as the way that they saw it when they were testing it out. And that's sort of like the benefit really is just you kind of give people freedom. Let's say they want to do it in VanillaJS, or they maybe want to do it in Svelte, or they maybe want to do - there's another kind of embedded interactive type known as AI to HTML, which is an Adobe Illustrator embedded interactive type where you can create a chart in Adobe Illustrator and just export it as HTML and it'll just go straight into the article. And that's an unbelievable workflow that allows you almost pure freedom. And I think that's just something those graphics developers really value. But I think as far as the issues that ended up happening, to get into the weeds a little bit, there's a concept I think I maybe need to explain a little bit which is the concept of hydration and what that actually means. When you render out a page on the server, you're letting your web server know to generate some HTML and then upload it to some CDM. And then when the reader accesses that URL, they're going to retrieve a very - they're going to retrieve a response very quickly because it's service-side-generated HTML. And then that HTML is going to hydrate. And, usually, that's kicked off by scripts that are in lined at the top, at the head, which call this hydration event. And this hydration event really just means give me interactivity on the page. Don't just give me this static HTML blob. I want React's client-side functionality. That usually comes in the form of hooks. I want those hooks to kick in. But we server-side generate content because we want users to see the article or the homepage as soon as possible without there being some pre-processing time that the browser has to compute to then render out HTML on the page. And that served us quite well. That's basically the model that we use right now and a lot of other websites with high traffic patterns that rely on SEO. That's usually how they handle it too. And what ended up happening is that, in the moment before React hydrates, if anything about the overall structure of the DOM is changed before the hydration event occurs, that will trigger what's known as a hydration mismatch. A really simple way to maybe think about it is let's say you generated, you had a date. Oftentime, this occurs with dates where you use the date on the server and then you calculated the date on the client. And then the server-side date, usually in the form of like the current time, is different than the current time that's used in the browser. And that will cause a mismatch and throw an error. Another example is if sometimes even a third party extension might manipulate content on the page as soon as it's displayed and React is going to - basically, it's not going to like that. It's going to say, "Oh, what I wanted to hydrate is now different. And I can't reconcile that. Therefore, I'm going to re-render completely from scratch on the client." The chain of events is you have HTML that's rendered on the browser level. A hydration mismatch might occur for any number of reasons. Sometimes an extension. Sometimes you didn't use the right pattern. Maybe use the date when you shouldn't have. And React is going to try to reconcile and hydrate. It's going to realize a problem has occurred. And then it's just going to render the entire React tree all over again. And to the user or to the reader, you're actually not really going to notice that happening. Because it happens almost instantaneously. The hydration event is within milliseconds. And if there's an issue, a re-render event is also usually quite fast. But the drawback is that embedded interactives, when rendered and React, we don't actually know anything about the embedded interactive. We're just sort of given arbitrary HTML. And we're just told, "Hey, render that on the page." We generate HTML. Not just our main React tree. But, also, all the other independent sub-trees of the embedded interactives that might exist on the page. And those sub trees have their own script tags that will actually fire more quickly than the hydration event might occur. If you have a script tag that might resize an embedded interactive based on page width, you're actually not even going to notice the resize happening because it's so quick. That script is going to operate much more faster than you're able to process that. And it'll automatically resize the embedded interactive based on the CSS that you give it and so on and so forth. Other times it will pop - it'll just start immediately populating the interactive with data from an API that maybe the script is fetching. Asynchronous request. We have no way of knowing that. But it's automatic. Those are running independently of the main React tree. The problem is if you have a hydration mismatch, when the whole tree is rendered, that includes anything that was inside of dangerously set inner HTML, which is what React uses to render out arbitrary HTML content. And if you just - not even thinking about like dangerously set inner HTML, if you just have a blob of HTML and you're appending that to the dom, if there's script tags there, they're not going to run. They're not going to run automatically. You have to manually execute those script tags. And you manually execute those script tags by - I mean, I was not really aware of this. But, actually, you take the script tag and you just - the script tag alone, if you append that to a child object in the DOM via JavaScript, then the browser knows, "Oh, okay. You're telling me explicitly to run this script. I'm okay running it." But otherwise, it's just going to treat it as like regular HTML. [00:24:12] GV: And this is a browser-constraint. Effectively, this is browsers basically from a security standpoint. [00:24:18] IG: 100%. Yeah. That would allow so many like XSS attacks. It would just be terrible like practice for anybody to just inject script in a form and then have the browser execute that script. But if you tell the browser explicitly to append it as a child, it will run it. Now we're kind of like in a bit of a pickle because we have millions of article types. As far as I know, we have tens and tens of thousands of embedded interactives. And many of these embedded interactives are built in completely different ways. There might be a few templates that are reused. But you kind of have to assume they're all one-offs. And the dilemma that we were in really is that we know that React 18 is much more sensitive to hydration mismatches. And it's not just more sensitive. It doesn't even leave the page in an invalid state as it did before. In React 16 - and this was an issue I brought up with the actual core React team, and they explained it to me really well, is, in React 16, if there was a hydration mismatch, they didn't do a full re-render of the page. They just sort of left the page in a semi-invalid state. It didn't affect our embedded interactives. We might have even had a problem and not even known. But because the embedded interactives were not re-rendered from scratch, we were like, "Okay, everything's great. Everything's fine." But now that we know that React 18 is more sensitive, it does the full re-render, we have so many different asset types. But we know that React 18 is like the way we want to go. Now the question is how do we kind of move forward? We know what the problem is. How do we fix it? The thing is because we have so many different asset types, we can't test those all individually locally. It would be impossible. We can't actually fix every single one of our hydration mismatches because we're not actually sure when they might appear. But we also want to release React 18. We were just really committed to that. We had already invested all this time and effort. We didn't want to just give up. This kind of became a sort of cat and mouse game of like, "Okay, how do I make embedded interactives work if I just rerun them manually?" And that's what the core of the article is about. It's trying to just work around this hydration mismatch error that is happening. [00:26:38] GV: I think that's great. I mean, the way you've explained that is very good. I was going to bring up the GitHub thread. I think you referenced it in the article. And like I would just recommend anyone to go and read that. Whether you're interested in this issue or not, I think just reading that. And that's a great example of, well, good core team communication. But also, just great, I would say, communication from your side as well. Just having a very good dialogue about a pretty gnarly issue. But a lot of detail and like how to actually resolve that. I mean, for example, do you think you would have got past this issue without being able to have that interaction with the core team? [00:27:14] IG: I think we might have. But to be honest, what was actually happening is React 18 is actually not great at telling you why hydration mismatches occur. And this actually solved now in React 19, which is still in beta, which we hope to upgrade to soon. React 19 will actually give you really clear divs on what specifically has changed in the DOM. And that's amazing. But we didn't have that at the time. And so, for the longest time, I really thought like is the embedded interactive itself causing the mismatch because a script is manipulating the DOM of the embedded interactive itself before the page is hydrated? And it actually turns out that's not the case. What the core team told me is that they actually ignore dom-related changes that happen inside of an embedded interactive. You can have an embedded interactive change its content as soon as like the browser has loaded and that actually will not cause the mismatch. The mismatch is caused by our code by some React component that's within our huge monolithic code base that is using some bad practices that were not visible in React 16 but are now visible in 18. I think that really just gave us more clarity. And I ended up closing the issue because the issue was not dangerously set inner HTML is causing a mismatch. It was just our code is causing the mismatch. And now that we just have to work around that. [00:28:49] GV: Maybe just moving on a little bit from - I mean, again, listeners should - if any of the last five to 10 minutes has really piqued interest, go and read Ilya's article. You'll get even more detail there. And you can also check out that thread that we're talking about. Talk mostly about all the challenges. Of course, there was a lot of upside to this in the end. Performance. You mentioned in the article INP score and sort of how that's so important for New York Times. Could you maybe just speak a little bit to like what even is an INP score? And then like how did React 18 kind of contribute to what were the results, I guess, on that uplift? Yeah. [00:29:28] IG: INP is a pretty new metric I think that people are still sort of wrapping their heads around. And INP is known as interaction to next paint. And it's not replacing all core web vital metrics like things like CLS, or largest contentful paint, or time to total blocking time. These are still things that are still relevant. But Google is going to start it - well, started in March of this year to use INP as a new metric for ranking a website. And for us, having high SEO scores is probably one of our top priorities. Because we want to be the most visible news site for everybody in the world really. And people type in so and so and so happened on Google. We want New York Times to be that top result. Similar to a Wikipedia, for example. We just knew from the outset, "Okay, this new IP score, it's important to us. How do we sort of manage it?" And the reality is our INP score was not great. Even before React 18, our INP was like in the thousands. Thousand milliseconds. And what that means is essentially how responsive your website is. For example, anytime you touch a button, for example, or you close a modal, or you hit a drop down, or you hit a menu screen, or even scrolling by tapping on the page, these are all events that are tracked now by Google. And their core desire really is for can you tell the user when they've initiated an action that something has changed on the page. And how fast have you told them and given them the feedback that something has changed on the page? And it's not always click on this login button. How quick did that asynchronous request occur? That's not necessarily going to happen because that asynchronous request might take a second or two. It's really more about when you clicked on that button, did you get feedback that a loading icon is now on the page? Did you give them feedback that the dropdown has now populated? It's not just about initial load time. It's also about the experience of the user on the page. And I think React 18 kind of just, out of the box, improve those scores kind of tremendously at least on the P75 range, which is for people who don't have a good experience. It improved it by 30%. And that chart actually on the blog post is a little bit outdated. Because as we've sort of iterated on a few on our website overall, the different teams around the company have prioritized different parts of the page based on like their social team or the story team and so on and so forth. Our INP scores even in the P75 range are now close or pretty much on the mark of our - what is the desired metric? I think the desired metric is - I think it's like 200 milliseconds. I can't actually remember the exact number. It's actually close to what is the desired number now so. Before, in the thousands. It's now basically where it should be, which is really great news for us. And I don't think we would have been able to get there without React 18. [00:32:49] GV: I'm trying to think of the - we've had an episode previously with Million.js, Aiden Bai. That's kind of a layer that he designed to like stick on on top of React to kind of move it closer to the model of having all the interactions like compiled basically. Rather than be - basically, avoiding DOM re-render. And as some listeners maybe know or don't, I'm more into Svelte. I'm deliberately coming at this from a slightly different angle. Svelte being a framework that really champions the compiling approach as opposed to the DOM re-render approach. Maybe you can fill in the blank for me. React 18, is that version that kind of brought more of this into the - not the compilation as such. But it was conscious that these frameworks were kind of coming from a performance perspective, especially Vue was also talking a lot about this whilst not actually implementing it. We've had another episode. Unfortunately, I can't quite remember the name of it. But there was another episode we had with a sort of Svelte competitor as well. Yeah, where does React 18 fit in that kind of, if you know, sort of sequence of performance events? [00:33:59] IG: I think there's really two angles to this. The first is React 18 has - I don't know the exact specifics of how the code has changed as a result of their implementation. But what I do know is they basically implemented this new feature, which you can see in real time, is this feature of automatic batching. Before when React would initiate a state update, and let's say you're updating state multiple times in a row across multiple different components and you think of it more as like a pancake of state here, make a change, re-render, state here, make a change, re-render, state here, make a change, re-render, and so on and so forth, React 18 is now I guess smarter about how often it will actually make that render occur. Instead of - let's say you have 8 different state changes in a row and 8 different re-renders, React might say, "Okay, I know what the state is going to be from 1 to 8. I'm just going to skip all those re-renders and go straight to eight." And I think that's really is what's driving the core performance benefits. Because there's less compute happening on the page. There's less virtual DOM manipulation. There's less actual DOM manipulation happening. I think when you just skip directly from A to - I guess, A, B, C, D, E, F, G, H, I. Skip from A to I instead of A to B, you're obviously going to have a little bit more improvments. I think that's, as far as I understand it, where the core functionality has changed. I think the other element that like Million.js, which I'm familiar with and also React 19's new sort of React compiler, and that's actually something I'm really excited about digging into once React 19 is out of beta, is how does the React compiler actually intuitively understand how it can optimize your code? What the compiler is doing is essentially - I guess it's identifying which parts of the page or which part of your code can clearly use memoized data. And, therefore, not initiate a change on data that's clearly not going to be different. I think it's supposed to intuitively understand, without you even needing to intervene yourself, how it can change the code on compilation. And I think that's super cool. I think that that's really great. But I'm also speaking that from the perspective of these are sort of features, particularly new features like React server components and so on so forth that we're only just now starting to kind of have conversations about and get into after our upgrade. [00:36:34] GV: Yeah. That's where I was just going to touch on briefly next. What else, I guess, from React 18 are you kind of exploring? And dare I ask, when would you consider going to React 19 as well? [00:36:47] IG: Well, I do actually have a experimental branch open already about React 19 just to sort of playing around with it. And I already love the new hydration diving issues. We're actually experiencing a minor issue with an embedded interactive type that is causing a hydration mismatch, which is rare, where the embedded interactive itself is causing an issue. And we weren't really quite clear what was happening. That's like a new - sort of a new angle of which to approach this problem is how to deal with those scenarios. But our future is really about, one, we're on a pretty old and deprecated build pattern. We have an open source project called Kyt that we still use actively. But it's clear that it's quite old and we need to reinvigorate at that build process. And we essentially kind of built our own version, like an in-house version of Next.js. And it's clear that that has has served us well. But we need to now upgrade. And upgrading involves kind of digging a little bit into React server components. And React server components sort of introduce this new paradigm that is radically different because it involves streaming updates into the browser rather than having some static HTML blob loaded on the CDN, loaded in the browser and then hydrates it via some client-side React and give it some functionality on the page. Now you're sort of injecting little islands of interactivity that maybe you don't necessarily need on the initial server-side load. You could store those little HTML blobs on the edge. Now you're getting into ideas of like edge computing and questions that like Vercel has tried to answer or is answering. And so, these are all like things that we're only really just now starting to explore. And we're not really quite sure if that takes the form or nature of using Next.js, or Remix, or even maybe our own framework implementation that we want to tackle on ourselves because our tools are relatively bespoken many ways. That's sort of the trend line I see ourselves going to. [00:38:59] GV: Yeah, that's exciting. Yeah. I mean, just anything else you can share from sort of - I mean, you talked there about like build process potentially being upgraded. Yeah, anything else that you sort of can share about like just where I guess New York Times from a technical perspective is going? [00:39:15] IG: Yeah. I mean, we have kind of I think a goal to - I mean, maybe a personal goal, part of the web platforms team, about trying to align our systems in more shared way. Because I think the New York Times, we have our core news site, we have games, we have the athletic, we have wire cutter, we have cooking. And on top of that, we have web view implementations that are in many of the apps. As I described earlier, we have a separate web server sort of rendering out content on the New York Times app. And I think one of the core challenges really is how do we leverage platforms not just to leverage them, but how do we leverage them meaningfully across systems that help actually drive really revenue and help drive value? The idea of like, "Okay, we want games and cooking and wire cutter to all be on React server components and Next.js." And maybe that makes sense. But how does that actually help our bottom line? How does that help us work faster? How does that help share understanding of the different ecosystems without locking ourselves into one implementation versus another and then needing to migrate every other system to like a new system all over again? You want to have the freedom to explore those different tools. But you also kind of want to have a shared identity as a company. And I think that's something that we'll probably really try to focus on over the next few years is developing a more shared identity so that teams are not necessarily working so independently of each other. But part, in fact, sort of like more of an ecosystem of the New York Times bundle of all the different products that we offer. And I think that that's something that we're going to really focus on over the next few years. [00:41:03] GV: That's exciting. Yeah, I'm an athletic subscriber. I like the app. I'm not sure how much of it was brought in from the pre-acquisition. But at the same time, I love that app. I also love the New York Times app. The more things that could be shared across both sounds good to me as a paying subscriber, I guess, is one way to put it. [00:41:23] IG: Yeah, that's great to hear. [00:41:24] GV: Yeah. Just to wrap up, this is just a slightly new segment I'm just adding in, which is a couple of questions. First one is just what's a day in the life for you as a senior software engineer at New York Times? What is a typical day for you? [00:41:39] IG: I think New York Times is actually kind of in a position where I don't really think of myself as like we are both a tech company and not a tech company. Because first and foremost, our product is our news. And our journalists are forever indebted to the work that they provide. Not just for me personally, but for the world. But we also have elements of a tech company. Everybody's on Slack. We have GitHub. We have stand-up meetings. We use Jira. All those things are not probably surprising to most software engineers. But I think where the layers or where the experiences are different is because - and this could just be my experience, because our team is just so close to the news. There's actually a different kind of pressure that exists. Because kind of like what I was talking about before where we really made some critical errors with embedded interactives, there's a different kind of pressure that exists not just on a daily level where you want to ensure the stability of the website. But also, on a periodic level, really just based on huge news events such as the elections. We have an election coming up. For us at the New York Times, that's kind of like our Super Bowl. We really spend an enormous amount of time even right now actively preparing for the scenario of a super high traffic event, which is actually the New York Times does have super high visibility. But imagine all at once, your systems were hit 20X, 30X, 40X. Being able to actually have your system scale that quickly. And because the New York Times itself is a service-side React application. We're not just like delivering some client-side bundle, some static asset. We're Kubernetes application deployed on AWS with assets on the edge. We have systems on systems that are interdependent on each other and linked. And when you bombard them with a huge amount of traffic all at once, that's a problem that you have to solve actively. And I think that's something that we've also been really focused on recently. I think, yeah, we are a tech company in the sense of you're a software engineer. You do your job as a software engineer. You do pull requests and merges domain and so on and so forth. But because you're next to the news, it's really like a fundamentally different experience that I've always valued personally, that I've always felt a sense of pride in to be working at the Times. And it's something that I think a lot of engineers at the Times also feel as well. [00:44:17] GV: That's super interesting. I never thought I guess of an election, for example, in that way. I guess it's sort of like the Amazon prime day of New York Times. Yet, it happens roughly once every four years. Not once a year. It's a different - [00:44:32] IG: That's true. But then you also have - you have the debates. Then you have midterms. Like all these other kind of mini-events also are high traffic. You look at the trend line for traffic patterns. It's like stable, stable, stable. Then a huge spike. And then stable, stable, stable. Then a huge spike. And I think that's just something that we're always dealing with, I would say. [00:44:51] GV: Yeah. Final question. Just what's a piece of advice you'd give to yourself when you starting out in tech based on what you know now? [00:45:00] IG: When I started working at a startup straight out of college, I was given an enormous amount of responsibility, an enormous amount of ownership. And I thought I knew everything. And I think that that was probably - what I mean by I think I thought I knew everything was that I thought to myself, "Oh, well, I worked on the startup. I did all these things. I made all these pages. And I was just like a junior engineer. And I had a little bit of an ego with that. And I think it probably took me some time. And I think everybody really struggles with this to an extent. It took me some time to sort of realize that there is such a huge world of things that I do not know, of things that I may never know, of things that I might know very briefly. And think to myself I know everything about it. But I also don't know everything about it. I just think having like an attitude of humbleness is super important. Because software engineers, we can be like a prickly bunch. It's easy to go into like a conversation with like a foregone conclusion or be really opinionated. And for example, a sort of a brief aside, I posted this blog post on Reddit. And there was a comment that was about like, "Oh, why did you do React for New York Times? Why didn't you just do Vanilla JS? [00:46:28] GV: Of course. There has to be - [00:46:31] IG: And I kind of thought to myself like, "What would I do that? React is the way to go." It's like kind of an impulse to be really attached to the technology that you chose. Instead of really maybe interrogating as like, "Well, do they have a point? Maybe they're on to something." And I think kind of just having an attitude of like just maybe being open and having a curiosity for - I'm not saying we're going to rewrite New York Times to Vanilla JavaScript, because that would be probably not happening. But I think just having enough curiosity to interogate ideas and discuss them with an open mind, that's something I wish I would have taught myself earlier. And hope that others can do that as well. [00:47:15] GV: Yeah. I can completely resonate with that when I started out just running a software engineering company. Unfortunately, for the first 10 years of my life, I was the boss, I guess. As a co-founder. Unfortunately, you come out of that thinking you maybe do know everything. And, of course, I then learned very fast. I didn't in any shape or form. I really like that. I think, exactly, it's about being curious. People will challenge. Especially, as you say, developers, we're a prickly bunch. We're going to be very ready to challenge something. It's just the way in which you want to challenge it can be so different and can be super collaborative even and it's challenging. I think that's really good place to leave this. Because I think that can just helped so many engineers, especially out there, if they're just getting started or even well through their career. But I think we've all met them, engineers, all the way through wherever they are in their career. But they haven't maybe adopted this way of thinking about how to sort of still be open. That's awesome. Where can people find the article and anywhere else that you know you want to plug for people to find you? Anything like that? [00:48:23] IG: Yeah. You go to NYT open and you just - NYT open medium on Google. You should be able to find the NYT open team, which is where we sort of publish all of our content. You'll be able to find the article. It's called Enhancing the New York Times Web Performance with React 18. Not sure what else I have to plug, because that's the big thing I think for me personally. That was a lot of work for us. And I think I'm really proud of where we're at with that. [00:48:49] GV: Well done. And thanks so much for making the time. And, yeah, I hope we get to catch up again in the future. [00:48:54] IG: Yeah. No problem. Thank you so much. [END]