Frontend development is a critical aspect of web development. The front end is the user interface that users see and interact with on their devices. A well-designed and intuitive user interface can make a huge difference in the success of a web application. Writing a good and high-quality front end is as important as having a strong backend architecture. In the rapidly evolving world of Web3, it becomes even more critical to ensure that front-end development is done using the right tools and libraries. With the increasing complexity of blockchain-based applications, it is essential to have a well-designed and intuitive user interface that not only provides a seamless user experience but also enhances overall security and reliability. In this article, we will discuss the key factors that contribute to high-quality frontend development in Web3 and explore the best practices for leveraging the right tools and libraries.
What are the available frontend frameworks and what we should use?
There are mainly 3 frontend libs that are widely used i.e. React, Vue, and angular, out of which React and Vue are mainly used nowadays. Let's dive deeper a bit into React and Vue and understand how they are different from each other.
- React is more flexible and customizable, while Vue is designed to be a more opinionated framework, i.e it provides more structure and guidance to developers on how to build applications.
- Vuejs is known for its high performance and fast rendering speed.
- Vuejs has a lower learning curve than React, as React has more complex syntax and greater flexibility.
Talking about which one we should use then I'd say React because it is used in most websites and has great developer support and a wide variety of third-party libs. Also, with React, you can use tools like Nextjs and Vitejs.
- Nextjs is a React-based framework that provides Server Side Rendering to our React applications. It also provides many other features like Static site generation and serverless functions which enhance the performance of our application.
- Vitejs, on the other hand, is a build tool and development server designed for building fast and efficient web applications. It provides fast and efficient hot module reloading.
Now, coming to what to use? Vitejs is particularly useful for single-page web applications and web apps that require fast development cycles. But if we wanna build a large and scalable web application, then definitely Nextjs is the best option. Thus, in conclusion, I'd say Nextjs is the most optimal option to build a full-stack web application. You can watch this video for the reference.
To manage states,
xstateis the best lib to use which can help us to create, interpret, and execute finite state machines and statecharts.
Which are the libs to be used?
We are going to discuss mainly two types of libs i.e CSS libs and web3 libs.
There are mainly 2 CSS libs that I use in my workflow, namely TailwindCSS and Chakra UI. If you wanna spin up your application quickly without spending much time developing your components, then Chakra UI is the best option to go with. On the contrary, if you wanna develop an application that has the most flexibility and complete control of the CSS, then Tailwindcss is the solution for you. Also, if you wanna develop a highly efficient CSS or a design system then React Stitches is the best lib for that.
Coming to the web3 libs, there are many libs like
viem that you can use to interact with the blockchain. Out of these three,
viem was just released a few weeks ago and thus, has not been used much yet. Among the
ethers.js is used in almost all projects.
Also, there is an amazing react hooks lib built on top of
wagmi. It is a collection of React hooks containing everything that you need to get started working with Ethereum. It provides hooks that make it easy to implement wallet connections, sign messages, read and write data to the contract, and much more and that too with a caching layer and request deduplication. There is also a UI lib on top of
wagmi called RainbowKit that provides you with a cool UI to connect wallets to your Dapp. Thus, in a way, rainbowkit and wagmi are a great combo.
These are the existing good libs to use, but recently the author of
wagmi have released a new lib called
*Viem*. It's a ts interface for Ethereum that provides low-level stateless primitives to interact with Ethereum. It comes with enhanced DX, stability, bundle size (27kB), and performance resulting in fast load times despite executing heavy tasks. This is still in Beta and won't recommend using it in production as it's very new so you might run into an error/bug. Though, it's always good to try out new tech and libs and play around with it.
Thus, as of now, according to me
rainbowkit are the best stack of libs to use to build a qualitative frontend.
How should we test our frontend components?
Testing is very crucial for ensuring the functionality of the application, preventing regressions, improving code quality, and thereby building bug-free applications. Thus it is really good practice to write tests for our components. There are two main forms of testing: snapshot testing and component testing.
Snapshot testing can be carried out using a testing library called
jest. It is a tool that helps us ensure that our UI does not change unexpectedly.
Next comes component testing (also known as testing in isolation). This can be done using Storybook. It lets us test our components visually and one component at a time in isolation.
You can refer to my article on testing react components here.
What are the coding practices or the structure we should follow?
If your application is not a single-page application, and you have a design or layout which gets repeated across multiple pages, then you should move that component to a
Layoutwrapper component. This provides a consistent layout across multiple routes that can improve UX and also improves code reusability. As we are using the same component, it will reduce the number of render cycles and will help improve the performance. Also, if you wanna manage state, pass some context or any other props to the child components, you can pass it from this wrapper.
Try to minimize the number of lines in your file as it will make your file look clean and will help you to easily read and understand the code. Your code should be as clean and understandable as any person can understand what's happening in that file by looking at it at the first glance itself. For that, write well-organized code, reduce redundancy, use functions, and break it down into smaller modules if possible. A standard reference that I keep in mind is to write an effective component somewhere around 150 lines of code.
Do proper state management, having more states increases the size of the application and costs performance. If you wanna use any state value at more than one component, then use
useContextto store and access data (
reduxcan also be used). This will help you manage the state in an organized manner. Also, you won't have to pass props across multiple components. Thus, using
useContextwill allow you to create a state at a central location, making it easier to update.
If you're using Nextjs, use SSG (static site rendering) or SSR (server-side rendering) which can improve performance by pre-rendering pages and fetching data on the server, thereby reducing the amount of work to be done on the client side. Also, use ISR (Incremental Static Generation) that allows us to revalidate the fetched data and update pages after the definite intervals. Large images can slow down page load times, thus optimize images and use lazy loading to improve the page loading times. You can also use CDN (Content Delivery Network) that caches static assets at multiple locations across the world.
One of the most important factors that affect a page's performance, is the improper use of
useEffecthook. We fetch data and cause side effects in this hook, thus we've to be very careful about when to execute this hook. Thus, we've to be very careful while adding dependencies to the hook as too many dependencies can cause unnecessary re-renders and cost us performance. Instead of using one hook with too many dependencies, consider using multiple
useEffecthooks with the required dependencies. Use the cleanup function, to clean up any resources or subscriptions if created. If you want to access the DOM immediately after it's created, consider using
Some Bonus points
- Make as many OSS contributions as possible, as it'll give you the experience to work on big projects and give you an opportunity to learn so many things.
- While opening an issue or creating a PR, always make sure to describe that particular thing in as much detail as possible. Let's consider you are creating a PR, then write what issue it solves, what fix and change you've introduced, and if any other information is there worth mentioning. Similarly, while creating an issue, always mention how you ran into it, the steps to reproduce the issue, and any possible fix you could think of. It's always better to overcommunicate yourself than to under-communicate and create misunderstandings.