High-performance frontend development with Solid.js

Interfaces slow down on heavy tables and charts, and every new screen accelerates code growth and build time. We build Solid.js frontends end to end: profile bottlenecks, migrate critical screens, and configure the build. Response time drops severalfold, code size by tens of percent.

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Frequently Asked Questions

Solid.js development: where performance breaks

Solid.js builds the interface on fine-grained reactivity: signals know which node depends on them and update only that node — there is no virtual tree that must be rebuilt and compared here.

Therefore interface performance on forms and cards remains steady even on weak devices, and it breaks in specific areas of code.

The first area is heavy lists and tables. As long as there are dozens of rows, everything is predictable; when thousands of records with filters, sorting, and expanding details enter the table, the frontend bottleneck shifts to creating nodes and recalculating order.

Virtualization, stable row keys, and avoiding re-creating markup when the filter changes restore steady response.

The second is frequent state updates. Live metrics, a message feed, dragging elements: each signal write synchronously pulls along derived computations and effects, and without batching updates, response speed drops for no good reason.

The third is unnecessary rerenders due to overly coarse state. One shared signal per page forces all subscriptions to recompute: editing a field in the header touches the table below.

It is treated with granularity — component-level state, extracted memoized derivations, and targeted subscriptions.

The fourth is time to first response: on a weak device, it consists of the amount of markup, its hydration on the client, and code work before the first touch.

We'll break down how this is addressed: what to profile, where to virtualize, and how to decompose state so the interface responds immediately.

What changes in numbers: response, code size, and build

The reactive model of Solid.js does not build an intermediate view tree: computations are bound to specific nodes, so when data changes, only the markup areas depending on them update.

This yields three measurable consequences — time to respond to an action, final code size, and project build time.

Time to respond to an action drops because cascading rerendering disappears. A click on a filter used to trigger a full block rebuild; now only the result row is recomputed — the number of markup operations is reduced severalfold.

On long tables and catalogs, this is noticeable where the interface usually "sticks": scrolling, filtering, expanding a card.

Final code size decreases along with the layer that no longer needs to be shipped to the browser.

Part of the logic moves into the data layer and stops being duplicated in components; the build is assembled from fewer modules — hence shorter project build time and a more compact artifact for deployment.

Interface stability is a consequence of the same update order: state changes one node, neighboring nodes are not re-created, and the interface does not "jump" during rapid user actions.

We record every change with before-and-after measurements: we take render profiles on typical scenarios, count the share of updated nodes, build size, and its duration. This way the architecture change is confirmed by numbers, not promises.

Solid.js development: comparing rendering approaches

The choice of rendering mode is not a matter of taste but a consequence of how fast the first render must appear and how much logic actually lives in the browser.

With Solid.js, fine-grained reactivity redraws only the changed node, so the same code works both with server rendering and with progressive hydration of the page — only the method of delivering markup to the client changes.

Below are four working options among which we choose at project start. The boundary between them runs along interactivity: the more blocks hydrate on the client, the more expensive it is to split code into parts and the more carefully rollback must be designed.

Option When it fits Constraints
Server rendering with hydration of the entire tree Personal accounts and dashboards where almost every block is interactive Markup arrives quickly, but clicks do not work until hydration; the client part is large
Progressive page hydration, with islands Promo pages, catalogs, sections with rare interactive widgets Island boundaries are defined in advance; shared state between them is passed manually
Static delivery with targeted hydration Reference, documentation, content, and marketing sections No live server logic: everything that depends on user data goes into a separate request
Fully client-side rendering Internal interfaces behind authorization where search visibility does not matter Empty first screen and mandatory loading of client code before any rendering

The modes are compatible with each other: static sections are delivered as ready-made markup, while search and account are connected as separate parts with their own hydration.

Such a set reduces the amount of client code on the first screen and leaves room for gradually increasing interface complexity.

Work stages: from profiling to build integration

Solid.js reactivity delivers gains only where it is clear in advance which nodes update on each state change. Therefore we start not by rewriting markup but with measurements: without them, edits turn into code rearrangement without a verifiable result.

  1. Interface profiling. We take measurements on real screens: how quickly the first response appears, how long a frame lasts when filtering long lists, and where redrawing touches extra branches of the tree.
  2. Dependency scheme. We build a graph of signals, computed values, and side effects — it becomes visible which data pulls along a cascade of updates and which lives in isolation.
  3. Implementation plan. We split the transition into steps so that each can be shipped and rolled back separately, without stopping work on other parts of the product.
  4. Component rework. We move heavy areas to targeted updates, lift state out of deep nesting, remove unnecessary subscriptions and repeated computations.
  5. Integration with the existing backend. Contracts, authorization, and response schemas remain the same — the new layer is responsible only for state and display.
  6. Testing on real scenarios. We run typical and peak user paths, compare before-and-after measurements, and cover found regressions with automated tests.
  7. Handover. We give the team rules for working with state, the dependency scheme, and a set of checks so the effect persists during further enhancements.

Handover artifacts: schemes, build rules, documentation

After delivery, everything remains in the customer's repository and in documentation tied to the code.

Project handover is not an archive and not a call from memory: any engineer who opens the repository must understand how the application is built, where state lives, and what can be changed without risk.

  • Reactive relationship scheme: which signals produce computations, where state is stored, which nodes update from a single change — as a diagram and a "source → consumers" table.
  • Project configuration and build rules: compilation parameters, separation of server and client parts, environment variables per environment, build and local run commands.
  • Component conventions: where local state is allowed, how properties are structured, how files and modules are named, and what is forbidden inside computed values.
  • Catalog of ready-made components with property descriptions, usage examples, and notes on which changes are safe and which break consumers.
  • Support policy: order and frequency of dependency updates, criteria for rollback to a previous build, and owners for modules.
  • Check policy: which automated checks pass before release — types, behavior tests, build size budget.
  • Training materials: a recording of a code walkthrough with the customer's team and short instructions for typical tasks — add a page, change a form, connect a new request.

We hand over on live code: we walk through the design together with the customer's engineers and answer questions on each item in the list. Access to the repository and documentation belongs to the customer's team, without dependency on us.

Case: heavy dashboard and before-and-after metrics

The dashboard collected data from several sources: summary charts, an event log, and a table with tens of thousands of rows with filters.

Every stream update rerendered the tree entirely — the tab froze for several seconds, and the aggregates in the header briefly diverged from the table contents. Users stopped trusting the numbers and refreshed the page manually, which returned them to the same state.

What was changed

State was moved to fine-grained reactivity of Solid.js: subscriptions were tied to specific data slices rather than to the root store. The table was given to virtualization, heavy derived values to memoization, and stream updates to batched processing in one render frame. A widget updates only when its own source changes, not any of dozens of neighboring ones.

Metric Before After
Response to log filter 4.8 s 0.7 s
Rerenders per stream update ~1200 18
Project build time 96 s 34 s
Desynchronization of aggregates and table constantly not reproducible

Response returned to fractions of a second, and the dashboard maintains a live stream without blocking the interface. Most importantly, a class of failures we call view desynchronization is gone: divergence between summary numbers and detail no longer occurs. This scenario was fixed in regression checks so it does not return with future enhancements.

What to do if the frontend is already written on another stack

You do not need to rewrite everything at once, and most often that is the worst of the options.

A gradual transition is more profitable where the product is live and generating revenue: the old code continues serving traffic, while the new layer is enabled page by page, by routes.

The first step is to split pages by criticality and coupling. First to be migrated are areas with high load and weak ties to the rest of the application: catalog, listings, product cards, individual checkout steps.

The personal account and admin panel are left for later — there are more states and permissions, and an error costs more.

The new layer is introduced at the route boundary, not inside existing screens. Both applications live side by side under one domain, share the session, authorization, and the server request layer, while transitions between them remain invisible to the user.

A shared design system and one contract with the server side are what keep the layers compatible and prevent the interface from drifting apart in appearance and behavior.

The product does not stop: releases proceed as usual, switching a page to the new implementation is done by a route edit, and rollback by restoring the previous one.

Solid.js performs well on such a frontend migration: it connects to individual page nodes without requiring a single root application for the entire site.

Partial rework has a cost. For some time, two builds live side by side, some dependencies are duplicated, and the team keeps both models in mind.

Therefore we calculate in advance the share of pages that will actually migrate and say directly when it is more profitable to rewrite entirely than to maintain compatibility for years.

Technical doubts: indexing, dependencies, support

Objections to a frontend stack usually come down to four: will pages be indexed, what will happen with dependency updates, who will support the code, and how quickly a new team will get into it. Let us address each from an engineering standpoint, without generalities.

Will pages be indexed by search engines?

Yes, if rendering is moved to the server. Reactivity here works on top of regular document nodes, so the page is delivered as ready HTML — the search robot receives content, meta tags, and structured data in the very first response, without waiting for scripts to execute. We build static content at build time: no server part is needed, and response time drops.

Will dependency updates break the project?

The Solid.js core is deliberately small, and most logic lives in application code rather than in the package tree. Updates are released less often and less often affect public interfaces.

Major transitions are planned as a separate task with automated tests run on a copy of the build — the release does not depend on whether third-party libraries have been updated.

Can support of someone else's code proceed without the author?

Components are regular functions with explicit dependencies: there is no hidden lifecycle to keep in mind. Logic is moved out of markup into separate modules and covered by checks, so a new engineer changes behavior rather than untangling side effects. We also hand over the data scheme and component map.

How high is the entry threshold for the team?

The syntax is close to what developers have already seen in other libraries, so the transition takes days, not months. The main difference is signal-based state management; it is learned on the first small module. After that, the team works at a familiar pace: component, test, review.

Let's discuss the task: how we start work

So that the estimate is based on facts rather than guesses, we need a minimum of context: what the product is, which scenarios are critical, and what has already been implemented.

Based on this description, we analyze the task and come back with a work plan by stages, team composition, and duration of each stage.

What to send or describe:

  • product description and three to five main scenarios that people use;
  • mockups, a prototype, or a link to the current version;
  • which screens must respond instantly even on weak devices and slow connections;
  • list of external services for integration: payment, account login, analytics, data exchange;
  • what has already been written and what it runs on — if part of the interface is made with Solid.js, we will look at what can be reused;
  • constraints: hard dates, requirements for placement, access, and data protection;
  • who on your side accepts the stages and verifies the result.

In response, you receive not an "from and to" range, but a breakdown: what stages the work is divided into, how long each lasts, who on the team is responsible for it, and at what point you accept the result.

If risks surface during the analysis — for example, a bottleneck in data exchange or an unstable service provider — we name them immediately, before the start, not in the middle of the work.

Describe the task in two paragraphs or send the listed items — we will come back with an estimate and work plan.

Our competencies:

Latest works

  • B2B ADVANCE company website development
    B2B ADVANCE company website development
    1542
  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1393
  • Website development for BELFINGROUP
    Website development for BELFINGROUP
    1081
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1368
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1139
  • Website development for FIXPER company
    Website development for FIXPER company
    1060