Skip to main content
Engineering

Our home page got 50 times lighter on words

· 3 min read

You open pagetovid.com on your phone. Before today, along with the page came almost every sentence we had ever translated, for screens you might never visit. Now each page brings only the words it actually shows, and the site opens lighter everywhere.

Every word, on every page

PageToVid speaks four languages, and its interface text lives in 56 groups of translations: errors, navigation, pricing, the editor, the animations library and many more. The first version of the site, when there were only a dozen groups, handed all of them to every page. It was a sensible default at that size.

The site kept growing, and each new feature added its own group. The home page ended up carrying 139 KB of translation text, most of it for the editor, the dashboard and other screens a first-time visitor never opens. Nothing looked wrong; pages were simply heavier than they needed to be.

Each part of the site gets its own words

Now each part of the site receives only what it reads. The shared layer carries a short list, such as errors, navigation and the address bar, which comes to 2.6 KB. Each section of the site, from the editor to the animations pages, adds the groups it needs with a small ClientMessages wrapper.

There is one subtlety. In the translation library we use, a section's list replaces the shared one rather than adding to it, so every list must include everything that section reads. Keeping that right by hand would be fragile, so a new test walks the imports of every route and fails in two cases: a component reading words its route does not send, and a route sending words nothing under it reads.

A big catalogue stays on the server

The same review found a larger file travelling further than it needed to. Our animations library has a full catalogue of templates, about 1.5 MB. A small helper used by the editor and the animation pages only needed a few sample lines from it, but importing it brought the whole catalogue to the browser.

The helper now reads a small generated file holding just those sample lines, rebuilt whenever the catalogue changes. An animation's detail page loads its preview player only when needed, and only your language's text reaches the animations pages. A test on the browser bundle keeps the catalogue from creeping back. In the same spirit, the purchase code now loads only on the pages where you buy something.

Less work for every visit

The rest of the work was about doing less on each request:

  • while your film is being made, its page checks a light summary (stage, estimated time, scene count) instead of the whole project, and checks less often after a minute or when the tab is in the background;
  • a film's watch page reads the film once per visit, not once per component;
  • the gallery and the home page showcase are kept ready for ten minutes;
  • gallery thumbnails load straight from storage, with their size known in advance, as you scroll;
  • icons, sounds and showcase images are cached for a day;
  • idle assistant connections close after 20 seconds instead of staying open;
  • the slowest database lookups gained indexes.

AI video clips also stay on the fast tier of their model when they need a second attempt, and a call that times out once is simply tried again.

What you notice

None of this changes a single frame of your film. You notice it elsewhere: the video gallery and the home page open faster on a phone, the film page stays light while you wait, and a visit asks less of the servers behind it.

On a site where every page is rendered fresh for each visitor, that matters more than it sounds. Lighter pages mean fewer cold starts, quicker answers and a smoother first impression.

Defaults grow up too

This was not a hard problem. It was a default chosen when the app was small, which nobody had a reason to revisit while it grew from a dozen groups of words to 56.

The lesson we keep is that a size budget needs a test, not a good memory. The two new test suites fail the build the day someone imports a large file into a small button, or forgets to send a section the words it needs.

See it on your own site

Paste a page and get the narrated film this blog is about. The first one is free.

First film free · no credit card · ready in minutes

← All posts