Over the past year, we’ve adopted more frameworks and libraries to deliver a better user experience.
Our core web application is driven by a tried-and-true Ruby on Rails server that serves React apps. This serves us well, but we wanted to build richer and more performant experiences for prospective clients interested in our products. Specifically, we wanted to:
- Speed up our marketing pages (like our homepage, wealthfront.com/cash)
- Implement a consistent marketing design system to reflect our updated brand direction
- Allow for experimentation and iterative improvements
Historically, our web presence has been served by Fastly with our Rails server as the origin. We’ve augmented this with Next.js, which we’re using as a static site generator (SSG). During deployment, the built static site is uploaded to S3. Based on the request, Fastly will determine whether to route certain requests to S3 or our Rails server.
This allows us to avoid rewriting our entire infrastructure at once; a gargantuan refactor is not a prerequisite for upgrading our toolset to use Next.js. Engineering, marketing, and product are able to build richer experiences at a much faster pace.
Let’s dive into these updates to our tech stack.
We first began prototyping a Wealthfront website using Next.js in 2020. The developer experience was incredibly tight, and miles ahead of our Rails tech stack. We were impressed by the fast reloads, automatic code splitting, and easy integration with tools like CSS Modules and Sass, which would allow us to reuse a lot of our existing code. Next.js initially had a few issues integrating with our existing TypeScript codebase, but this is no longer a problem. We’re very happy with how Next.js has matured over the past few years.
Next.js treats TypeScript as a first-class citizen, integrates incredibly well with Tailwind, and works flawlessly with Framer Motion.
Adopting Tailwind has arguably been one of the biggest boons for productivity to quickly scaffold out a new webpage. We loved the developer experience from the beginning. Simply begin using new CSS classes in our codebase, and they would be generated within less than a second. Combined with classnames, this has been our styling solution for our marketing website.
Tailwind was already fast enough compared to our old workflow, but Tailwind’s Just-In-Time (JIT) compiler improved our rebuildsfrom 800ms to 80ms. It was a literal order of magnitude improvement.
Despite the complexity of our new visual style, we rarely have to reach for custom CSS beyond customizing our Tailwind configuration. We rarely ever have to worry about media queries, which was a huge source of frustration within our previous BEM-like CSS architecture.
Thanks to Tailwind, it’s been a breeze to build and extend our design system within code. The result is a beautiful, consistent, and jank-free website that allows engineers to spend less time writing code, and more time making sure the experience is great.
Here is our Tailwind config, containing nearly all of our customization to Tailwind:
The end result is a beautiful, responsive website:
Our design system relies heavily on floating and layered imagery to captivate the user, so tasteful animations are a natural fit. We chose Framer Motion, as it met our requirements:
- Declarative APIs for simple, sequenced animations
- Imperative APIs for complex, orchestrated animations
More specifically, our declarative animations look nearly identical to the Framer Motion docs:
While our more complex animations utilize React Hooks and other techniques to deliver a stunning experience:
By using modern frameworks and components and running basic optimizations on our assets, we significantly improved all of our metrics (especially TTI – 25.4 seconds to 3.2 seconds on a slow mobile connection!).
Many of the techniques that we’ve adopted for our marketing pages have been making our way into our logged-in experience, which is currently a client-side rendered (CSR) app. A lot of the techniques and implementations prescribed by libraries like Tailwind and Next.js have heavily influenced how we think about web infrastructure in general.
As time goes on, we want to make even more improvements to our A/B testing framework, dynamic content generation, and performance budgeting that ensure that code quality remains high.
The information contained in this communication is provided for general informational purposes only, and should not be construed as investment or tax advice. Nothing in this communication should be construed as a solicitation or offer, or recommendation, to buy or sell any security. Any links provided to other server sites are offered as a matter of convenience and are not intended to imply that Wealthfront Advisers or its affiliates endorses, sponsors, promotes and/or is affiliated with the owners of or participants in those sites, or endorses any information contained on those sites, unless expressly stated otherwise.
All investing involves risk, including the possible loss of money you invest, and past performance does not guarantee future performance. Please see our Full Disclosure for important details.
Wealthfront offers a free software-based financial advice engine that delivers automated financial planning tools to help users achieve better outcomes. Investment management and advisory services are provided by Wealthfront Advisers LLC, an SEC registered investment adviser, and brokerage related products are provided by Wealthfront Brokerage LLC, a member of FINRA/SIPC.
Wealthfront, Wealthfront Advisers and Wealthfront Brokerage are wholly owned subsidiaries of Wealthfront Corporation.
© 2022 Wealthfront Corporation. All rights reserved.