𝗠𝘆 𝗔𝗣𝗜 𝗥𝗲𝘀𝗽𝗼𝗻𝗱𝗲𝗱 𝗶𝗻 𝟰 𝗺𝘀, 𝗯𝘂𝘁 𝗡𝗮𝘃𝗶𝗴𝗮𝘁𝗶𝗼𝗻 𝗦𝘁𝗶𝗹𝗹 𝗙𝗲𝗹𝘁 𝗦𝗹𝗼𝘄

I was debugging a project management app built with SvelteKit and a Rust API.

On my local machine, everything felt instant. On the VPS, navigation felt heavy. Opening pages like Tickets or Timeline took too long. Clicking a ticket caused a noticeable delay before the preview appeared.

I thought the problem was the server. I suspected slow database queries or a weak VPS.

The measurements proved me wrong.

I checked the feature list endpoint. For only 52 tickets, the API responded in 4 ms. That sounds fast. But the response size was 354 KB.

The SvelteKit route payload showed the same issue. The data size was huge for a simple list.

The problem was not speed. The problem was weight.

The descriptions alone made up 80% of the total response. The list endpoint was returning full Markdown descriptions for every single item.

This is a common trap. The list endpoint had become a detail endpoint. Every time a page needed a list, it paid the price for data it did not use.

The UI usage does not determine the payload. The loader return shape does.

If your loader returns a full object, SvelteKit serializes that entire object into the route data. Even if you never render a field, it still travels across the network.

I fixed this by separating summary data from detail data.

I created two different contracts:

• A list contract for summaries (ID, title, status, dates). • A detail contract for full information (descriptions, commands).

I split the API into two endpoints:

  • GET /features (returns summaries)
  • GET /features/:id (returns one full detail)

I also changed how the frontend works. Now, the app renders the list immediately using summary data. When you click a ticket, the app shows a shell and fetches the heavy detail data in the background.

The results were massive:

• Feature list API: 89.6% reduction • Tickets route data: 91.4% reduction • OpenSpec docs API: 98.9% reduction

The database was always fast. The real bottleneck was the data contract between the API and the page.

Lessons for list-heavy apps:

  • Mide el tamaño de la respuesta, no solo el tiempo de respuesta.
  • Trata los payloads de lista y de detalle como elementos distintos.
  • Nunca devuelvas campos de texto extensos en una vista de lista.
  • Comprueba qué está serializando realmente tu cargador de SSR.
  • Carga de forma diferida los datos de detalle, pero muestra la estructura de la interfaz (UI shell) de inmediato.
  • No utilices un indicador de carga (spinner) para ocultar un payload pesado.

Una consulta rápida no garantiza una página rápida.

Fuente: https://dev.to/ahikmah/my-api-responded-in-4-ms-but-navigation-still-felt-slow-1hk8