Remixing a Symfony

Rate this content
Bookmark

In late 2020, I ran a Lighthouse test on a simple content page on Harvie, our farm management platform and Symfony app, and received a performance score of 31/100. The JavaScript bundle, the API requests, the database lookups, even with minimal UI to render, had a baseline score in the thirties! Along with customer feedback, this helped to catalyze a renewed commitment to performance at Harvie. Through numerous discussions, we walked through each step of page load, from networking to rendering, and identified where we could improve. After a year of rewrites and upgrades, our remaining detriment to overall performance was our frontend. We had been converting our Symfony twig templates into React SPA components and fell into the common problem of creating "request waterfalls", while our user had to stare at a loading screen. We needed a change, and for us, that was Remix. In this talk, I'll walk you through our team's journey with performance and how Remix has become a natural progression of that.

This talk has been presented at Remix Conf Europe 2022, check out the latest edition of this React Conference.

FAQ

Harvey plans to continue moving existing pages to their Remix application and ensure that performance and scalability are integral to all new features and updates.

The speaker of the talk is Emily Kaufman, a software engineer based in Pittsburgh, Pennsylvania.

Emily Kaufman works for Harvey, a grocery delivery service that sources products from local farms and producers.

Harvey started as a community supported agriculture (CSA) program where customers paid a yearly fee and received a box of local farm produce every week or every other week.

The COVID-19 pandemic led to a massive influx of both customers and producers on Harvey's platform, as people turned to online grocery delivery to avoid physical stores, and producers needed a new sales channel due to the closure of farmers markets.

Harvey faced performance issues such as slow page load times, large JavaScript bundles, and inefficient database queries, which led to a poor user experience and customer drop-offs.

The engineering team at Harvey addressed performance issues by optimizing image loading, reducing JavaScript bundle sizes, implementing lazy loading, splitting code more thoughtfully, and minimizing expensive API calls.

Changes to Harvey's frontend included adding lazy loading, using Webpack's Bundle Analyzer to reduce bundle sizes, implementing better code splitting, using text compression, and minimizing third-party scripts.

Harvey redesigned their catalog page to load products by category instead of all at once, reducing the number of elements on the page and improving performance.

Remix is a web framework that improves performance by minimizing request waterfalls and co-locating data requests with components. Harvey used Remix to achieve faster load times and smaller JavaScript loads.

Emily Kauffman
Emily Kauffman
19 min
18 Nov, 2022

Comments

Sign in or register to post your comment.
Video Summary and Transcription
This Talk discusses Harvey's performance journey and how it led to the adoption of Remix. The engineering team addressed scaling and performance issues through backend fixes and frontend improvements. The redesign focused on loading products by category and prioritizing performance. The implementation of Remix resulted in improved performance and a reduction in API requests. The focus on long-term scalability is essential for handling a growing product list and customer base.
Available in Español: Remixando un Symfony

1. Harvey's Performance Journey

Short description:

Hey everyone, welcome! My name is Emily Kaufman. Today I'll talk about Harvey's performance journey and how it led us to Remix. Harvey started as a CSA program, but during the pandemic, it grew into a full grocery store. We faced growing pains and poor performance despite the move to React. The underlying architecture couldn't handle the load.

[♪ Music playing ♪ Hey everyone, welcome! My name is Emily Kaufman. I'm a software engineer based out of Pittsburgh, Pennsylvania. I actually gave this talk at the- I was a backup speaker at the first Remix conference, so if you ended up watching that already this might sound pretty familiar. But my talk today is going to be about the performance journey that Harvey, the company where I work, has undergone over the past few years and how that ultimately led us to Remix.

Alright, so Harvey is a grocery delivery service, where all of our products come from local farms and producers. So it started out, I think about ten years ago, as a community supported agriculture program, if you're familiar with that. It's a CSA. Basically, you pay the farm some amount of money per year and then every week or every other week, you get a box of whatever they happen to have produced in that time. So it's a really great way to support local, support your local farms and producers. So what Harvey did is it provided a platform so you could actually customize what you were getting in your box. So up until about three years ago, two and a half years ago, that's all Harvey really did. We had a number of farms on the platform from all over and we had provided the way for the customers to come in and login, view the contents of their box, make additions if they wanted to swap out stuff and then they would wait for their delivery.

And then the pandemic hit. So, you might remember at the beginning the world was starting to close down. A lot of people in the Pittsburgh area, turned to Harvey as their main source of groceries, to avoid having to go into a grocery store. And on the other side of that, all these producers that were used to going to farmers markets, setting up booths somewhere, so that you could come and actually make purchases, they didn't really have a place to go anymore. And so they were coming on to Harvey as a producer in order to stay in business. So, as I'm sure you can imagine, we had this massive influx of both customers and producers and Harvey began to grow and evolve from this CSA program into a full grocery store.

So, of course, during any kind of large scale growth in a short amount of time like this you're going to experience some growing pains and we absolutely did. This is a Lighthouse test that I ran in late 2020, and it was just a simple content page in Harvey, which is a Symfony application, and we got this performance score. This was the JavaScript bundle, the API requests, database lookups, even with the minimal UI to render on this basic content page, we had a baseline score in the 30s. So this wasn't correct. Something wasn't adding up. This, along with some upset customers, some customer feedback helped to catalyze this renewed interest and commitment to performance at Harvey. The catalog page, which is where you go to view all the products, had recently, I think a year prior to that, been converted from the Symfony, jQuery, Twig combination into part of a new React single page application. And this was hit the hardest. So the dump to React had addressed many UX concerns that we had. It modernized our tech stack, but it was still falling short in terms of performance. So the underlying architecture just couldn't handle the weight of all the new products. It was taking upwards of tens of seconds just to add something to your cart or remove something or do a swap.

2. Fixes for Scaling and Performance

Short description:

Many members were dropping off the site due to poor scaling caused by the significant increase in products offered. The engineering team triaged the issues into quick wins, involved fixes, and future redesign plans. DevOps and networking were mostly handled by services and tooling. Back-end fixes included image optimization, caching, and updating endpoints and database lookups. Front-end improvements focused on reducing bundle size and removing unnecessary localization packages.

And so many members were just dropping off the site entirely. But we have to remember that we had gone from offering maybe 30 to 40 products a couple of years ago to probably over 600 at this point. And so the page just wasn't scaling correctly. So when we think about fixes for this, our first iteration was kind of this crisis mode. Our engineering team got together and we said what can we do in the short term to fix a few of these issues.

So we spent a few hours sitting around the network panel in the performance tab and just walking through every step of page load and organizing what we saw into a few groups based on who would actually be working on them. So we had DevOps and networking. We had the back end, which would include API and the database, and then we had the front end. And from there, we took what we found and we triaged this into quick and easy wins, involved fixes, and this could be part of a future redesign.

For DevOps and networking, we didn't have to do too much here because it was mostly handled by services and tooling. But it was worth it to at least sit down and walk through it and make sure there weren't any bottlenecks. For the back end API, we had quite a few issues around image loading on the site. This is a hero banner that we have on almost all of our pages, and for some reason it was taking like seven seconds to load and seemed to be blocking first paint. So we did a bunch of work around image optimization and caching, and that took actual seconds off of our page load time. So I can't speak to everything that my back end coworkers did, but more involved fixes included updating the endpoints and database lookups to make sure that we're only querying the minimum needed, trying to avoid unnecessary and computationally expensive operations. An example of this is like anything that would have to go through a third party provider. Like if we were checking a user's credit card information for one, we might only be doing this on like one or two pages. So it shouldn't be in a top level like layout component because then it's going to be happening way more than it needs to. Overall, all of these updates came around just because we sat down as a team and we stared at the dev panel for a few hours and just identified issues.

For the front end, aka my problem, because I'm the only front end developer at Harvey, this is how long it takes to actually download the content, how big the script is, testing slower connections and all that kind of thing. We identified several low hanging fruit that we knew would be a relatively small development effort but would drastically increase the user's experience. So we started there. For one, the bundle was just so big, it was too big. There was so much code that a user had to download before even getting to interact with the page. And we used Webpacks. We used Webpacks Bundle Analyzer plugin, if you're familiar with it, and this helped us identify many problem areas that we were able to tackle. One of these being our use of Moment.js localization packages. So we're mostly in the Pittsburgh area. We have farms all over, but mostly at least in the United States. So there were many localization packages that weren't really relevant to us at this time, so we removed those, setting the goal that we would eventually switch to using something else other than Moment.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

A Guide to React Rendering Behavior
React Advanced 2022React Advanced 2022
25 min
A Guide to React Rendering Behavior
Top Content
This transcription provides a brief guide to React rendering behavior. It explains the process of rendering, comparing new and old elements, and the importance of pure rendering without side effects. It also covers topics such as batching and double rendering, optimizing rendering and using context and Redux in React. Overall, it offers valuable insights for developers looking to understand and optimize React rendering.
Building Better Websites with Remix
React Summit Remote Edition 2021React Summit Remote Edition 2021
33 min
Building Better Websites with Remix
Top Content
Remix is a web framework built on React Router that focuses on web fundamentals, accessibility, performance, and flexibility. It delivers real HTML and SEO benefits, and allows for automatic updating of meta tags and styles. It provides features like login functionality, session management, and error handling. Remix is a server-rendered framework that can enhance sites with JavaScript but doesn't require it for basic functionality. It aims to create quality HTML-driven documents and is flexible for use with different web technologies and stacks.
Don't Solve Problems, Eliminate Them
React Advanced 2021React Advanced 2021
39 min
Don't Solve Problems, Eliminate Them
Top Content
Kent C. Dodds discusses the concept of problem elimination rather than just problem-solving. He introduces the idea of a problem tree and the importance of avoiding creating solutions prematurely. Kent uses examples like Tesla's electric engine and Remix framework to illustrate the benefits of problem elimination. He emphasizes the value of trade-offs and taking the easier path, as well as the need to constantly re-evaluate and change approaches to eliminate problems.
Scaling Up with Remix and Micro Frontends
Remix Conf Europe 2022Remix Conf Europe 2022
23 min
Scaling Up with Remix and Micro Frontends
Top Content
This talk discusses the usage of Microfrontends in Remix and introduces the Tiny Frontend library. Kazoo, a used car buying platform, follows a domain-driven design approach and encountered issues with granular slicing. Tiny Frontend aims to solve the slicing problem and promotes type safety and compatibility of shared dependencies. The speaker demonstrates how Tiny Frontend works with server-side rendering and how Remix can consume and update components without redeploying the app. The talk also explores the usage of micro frontends and the future support for Webpack Module Federation in Remix.
Speeding Up Your React App With Less JavaScript
React Summit 2023React Summit 2023
32 min
Speeding Up Your React App With Less JavaScript
Top Content
Watch video: Speeding Up Your React App With Less JavaScript
Mishko, the creator of Angular and AngularJS, discusses the challenges of website performance and JavaScript hydration. He explains the differences between client-side and server-side rendering and introduces Quik as a solution for efficient component hydration. Mishko demonstrates examples of state management and intercommunication using Quik. He highlights the performance benefits of using Quik with React and emphasizes the importance of reducing JavaScript size for better performance. Finally, he mentions the use of QUIC in both MPA and SPA applications for improved startup performance.
React Concurrency, Explained
React Summit 2023React Summit 2023
23 min
React Concurrency, Explained
Top Content
Watch video: React Concurrency, Explained
React 18's concurrent rendering, specifically the useTransition hook, optimizes app performance by allowing non-urgent updates to be processed without freezing the UI. However, there are drawbacks such as longer processing time for non-urgent updates and increased CPU usage. The useTransition hook works similarly to throttling or bouncing, making it useful for addressing performance issues caused by multiple small components. Libraries like React Query may require the use of alternative APIs to handle urgent and non-urgent updates effectively.

Workshops on related topic

React Performance Debugging Masterclass
React Summit 2023React Summit 2023
170 min
React Performance Debugging Masterclass
Top Content
Featured Workshop
Ivan Akulov
Ivan Akulov
Ivan’s first attempts at performance debugging were chaotic. He would see a slow interaction, try a random optimization, see that it didn't help, and keep trying other optimizations until he found the right one (or gave up).
Back then, Ivan didn’t know how to use performance devtools well. He would do a recording in Chrome DevTools or React Profiler, poke around it, try clicking random things, and then close it in frustration a few minutes later. Now, Ivan knows exactly where and what to look for. And in this workshop, Ivan will teach you that too.
Here’s how this is going to work. We’ll take a slow app → debug it (using tools like Chrome DevTools, React Profiler, and why-did-you-render) → pinpoint the bottleneck → and then repeat, several times more. We won’t talk about the solutions (in 90% of the cases, it’s just the ol’ regular useMemo() or memo()). But we’ll talk about everything that comes before – and learn how to analyze any React performance problem, step by step.
(Note: This workshop is best suited for engineers who are already familiar with how useMemo() and memo() work – but want to get better at using the performance tools around React. Also, we’ll be covering interaction performance, not load speed, so you won’t hear a word about Lighthouse 🤐)
Master JavaScript Patterns
JSNation 2024JSNation 2024
145 min
Master JavaScript Patterns
Top Content
Featured Workshop
Adrian Hajdin
Adrian Hajdin
During this workshop, participants will review the essential JavaScript patterns that every developer should know. Through hands-on exercises, real-world examples, and interactive discussions, attendees will deepen their understanding of best practices for organizing code, solving common challenges, and designing scalable architectures. By the end of the workshop, participants will gain newfound confidence in their ability to write high-quality JavaScript code that stands the test of time.
Points Covered:
1. Introduction to JavaScript Patterns2. Foundational Patterns3. Object Creation Patterns4. Behavioral Patterns5. Architectural Patterns6. Hands-On Exercises and Case Studies
How It Will Help Developers:
- Gain a deep understanding of JavaScript patterns and their applications in real-world scenarios- Learn best practices for organizing code, solving common challenges, and designing scalable architectures- Enhance problem-solving skills and code readability- Improve collaboration and communication within development teams- Accelerate career growth and opportunities for advancement in the software industry
Using CodeMirror to Build a JavaScript Editor with Linting and AutoComplete
React Day Berlin 2022React Day Berlin 2022
86 min
Using CodeMirror to Build a JavaScript Editor with Linting and AutoComplete
Top Content
WorkshopFree
Hussien Khayoon
Kahvi Patel
2 authors
Using a library might seem easy at first glance, but how do you choose the right library? How do you upgrade an existing one? And how do you wade through the documentation to find what you want?
In this workshop, we’ll discuss all these finer points while going through a general example of building a code editor using CodeMirror in React. All while sharing some of the nuances our team learned about using this library and some problems we encountered.
Next.js 13: Data Fetching Strategies
React Day Berlin 2022React Day Berlin 2022
53 min
Next.js 13: Data Fetching Strategies
Top Content
WorkshopFree
Alice De Mauro
Alice De Mauro
- Introduction- Prerequisites for the workshop- Fetching strategies: fundamentals- Fetching strategies – hands-on: fetch API, cache (static VS dynamic), revalidate, suspense (parallel data fetching)- Test your build and serve it on Vercel- Future: Server components VS Client components- Workshop easter egg (unrelated to the topic, calling out accessibility)- Wrapping up
Remix Fundamentals
React Summit 2022React Summit 2022
136 min
Remix Fundamentals
Top Content
WorkshopFree
Kent C. Dodds
Kent C. Dodds
Building modern web applications is riddled with complexity And that's only if you bother to deal with the problems
Tired of wiring up onSubmit to backend APIs and making sure your client-side cache stays up-to-date? Wouldn't it be cool to be able to use the global nature of CSS to your benefit, rather than find tools or conventions to avoid or work around it? And how would you like nested layouts with intelligent and performance optimized data management that just works™?
Remix solves some of these problems, and completely eliminates the rest. You don't even have to think about server cache management or global CSS namespace clashes. It's not that Remix has APIs to avoid these problems, they simply don't exist when you're using Remix. Oh, and you don't need that huge complex graphql client when you're using Remix. They've got you covered. Ready to build faster apps faster?
At the end of this workshop, you'll know how to:- Create Remix Routes- Style Remix applications- Load data in Remix loaders- Mutate data with forms and actions
Testing Web Applications Using Cypress
TestJS Summit - January, 2021TestJS Summit - January, 2021
173 min
Testing Web Applications Using Cypress
Top Content
WorkshopFree
Gleb Bahmutov
Gleb Bahmutov
This workshop will teach you the basics of writing useful end-to-end tests using Cypress Test Runner.
We will cover writing tests, covering every application feature, structuring tests, intercepting network requests, and setting up the backend data.
Anyone who knows JavaScript programming language and has NPM installed would be able to follow along.