Skip to content
Taimoor Arshad
Back to portfolio

Website Performance Analyzer

2024Web

Angular + ASP.NET Core web app that measures a URL's load time and byte size. Azure SQL for history, polling for slow analyses.

بسم الله الرحمن الرحيم

The Website Performance Analyzer was the third project in the batch I built to sharpen my full-stack chops. Enter a URL, get back load time and resource size, all shown in a small dashboard. Angular frontend, ASP.NET Core backend, Azure SQL for persistence.

What it does

You give it a URL. The backend makes a real HTTP request to that URL through IHttpClientFactory, measures how long the request takes, records the response size, and writes the result to Azure SQL. The frontend fetches the result and renders it. If you analyze the same URL twice, the history is there.

Nothing about that is complicated. The interesting bits were the failures.

The 500 error

First deploy, first request, 500 response. The backend had thrown because IHttpClientFactory wasn't registered in the DI container. I'd added the interface to my controller expecting it to just be there, because in ASP.NET's older HttpClient days it kind of was. In modern ASP.NET Core, you need builder.Services.AddHttpClient() in Program.cs. One line, but it took a minute to trace because the 500 was generic and the deploy logs weren't showing the underlying exception until I turned on developer exception details for the staging slot.

Lesson: turn on structured logging before you deploy, not after.

CORS and CSP

Firebase-hosted frontend, Azure-hosted API. The CORS setup was straightforward once I remembered which side needs the whitelist (the API, always). CSP was more interesting. Firebase's default Content-Security-Policy for hosted apps is fairly locked down, and the fetch calls to Azure were getting blocked at the browser level, not the API level. Adjusting the connect-src directive in the Firebase hosting config fixed it.

Slow analyses

A few of the URLs I threw at it were slow enough that the UI felt like it had hung. No feedback, no progress, just a spinner. That's a bad experience. I added a polling loop with a "Waiting..." message on the frontend that updates every few seconds so the user knows something is still happening. Not the fanciest solution, but it made the difference between "the app is broken" and "the analysis is taking a while."

Next steps

I'd add a proper queue on the backend so multiple analyses can run in parallel without stepping on each other, and I'd make the result page shareable via a stable URL so you can send someone a report. Both would turn this from a demo into something closer to a real tool.

Try it at performance-analyzer--performanceanalyzer-be32e.us-central1.hosted.app.