← All projects

Agency Portal and Admin Hub

The screens travel agents use to find and book hotels, the screens Hala Saudi's finance and hotel teams use to run the business, and the work that made a long hotel list fast.

620 → 51 ms

time to draw each frame while scrolling

400-hotel list test; under 16 ms feels smooth

29,223 → 1,364

elements on the hotel list page

Same test, before and after

~7,900

phrases per language in the Admin Hub

English and Arabic kept in step

The problem

Agents need to search, compare and book hotels quickly, in English or Arabic. Finance and hotel teams need clear screens to check money and decide on hotel matches.

On a long list of hotels, the agency portal had become slow: scrolling stuttered and the page used a lot of memory, especially on slower devices.

What I did

  • Built the hotel booking flow in the Agency Portal: search results, hotel details, rooms and rates, the cancellation policy, a booking review that asks before charging a changed price, and a confirmation page with a confirmation number for each room.
  • Built much of the Admin Hub finance back office: wallet top-ups, the ledger, reconciliation with a resolve panel, currency settings with change history, refunds and foreign-exchange earnings.
  • Built the hotel-match review screens, with candidate photographs side by side.
  • Wrote much of the English and Arabic text for both portals.
  • Led the Agency Portal performance work: profiled the pages, wrote the plan and the measurement scripts, and drove the fixes.
  • Designed serving the portal's static files from a CDN: the build setup, a rollback plan and a handover for the infrastructure team.

How the performance work was done

Each step is in plain words. Open “Technical detail” for the engineering version.

  1. Measure

    Build a repeatable test: a list of 400 hotels, run three times, timed the same way each time.

    Technical detail

    Playwright scripts with the CPU slowed four times to match a modest device; median of three runs.

  2. Find the cause

    Every hotel card was drawn at once, even cards far below the screen, which added up to almost 30,000 page elements.

  3. Fix

    Draw only the cards near the screen, load the next page ahead of time, and send less JavaScript to the browser.

    Technical detail

    List virtualisation with @tanstack/react-virtual, route prefetching and smaller first-load bundles.

  4. Measure again

    Run the same test under the same conditions and compare.

Results

  • Scrolling frame time fell from 620 ms to 51 ms in the 400-hotel list test.
  • Page elements fell from 29,223 to 1,364, and memory use from 142 MB to 39 MB.
  • Loading all 400 hotels by scrolling fell from 126 seconds to 12 seconds.
  • JavaScript for the hotel list fell from 604 KB to 508 KB.

Timeline

  1. Mar 2026Finance screens: reconciliation, top-ups and payment notifications.
  2. May – Jul 2026Hotel booking flow and per-room confirmation numbers.
  3. Aug 2026Hotel-match review screens.
  4. Sep 2026The agent is asked before a changed price is charged.
  5. Oct 2026Performance work and the CDN design.

What I learned

Measure before changing anything. The biggest win came from drawing fewer things, not from faster code.

Words on this page

Frame time
How long the browser takes to draw one screen. Under 16 ms feels smooth.
Virtualisation
Drawing only the items you can see, instead of the whole list.
Bundle
The JavaScript the browser downloads to run a page.
CDN
A network of servers that delivers files from a location close to the user.
RTL
Right-to-left layout, used for Arabic.

Built with

Next.jsReactTypeScriptTanStack QueryTailwind CSSnext-intl