From Concept to Deployment: Real-World Case Study of a Blazor PWA ๐Ÿš€

 


Building a Progressive Web App (PWA) with Blazor is an exciting journey that combines modern web development practices with the power of .NET. In this blog post, weโ€™ll explore a real-world case study: creating a fitness tracker PWA using Blazor. This project illustrates the entire development lifecycle, from concept to deployment, while showcasing best practices and lessons learned along the way.


The Concept: A Fitness Tracker PWA

Our goal was to build a fitness tracker that allows users to:

  1. Log daily workouts and track progress.
  2. Monitor key metrics like calories burned and heart rate.
  3. Access their data offline and sync it when back online.
  4. Enjoy a seamless, native-like experience across devices.

Blazor was the perfect choice due to its ability to combine server-side and client-side functionality, robust .NET ecosystem, and built-in PWA capabilities.


Step 1: Requirements and Planning

Core Features

  1. Workout Logging: Users can add exercises, set durations, and log repetitions.
  2. Real-Time Metrics: Display live updates of metrics like calories burned during a session.
  3. Progress Dashboard: Show graphs and charts of weekly and monthly progress.
  4. Offline Access: Users can log workouts offline and sync data later.

Tech Stack

  • Frontend: Blazor WebAssembly for offline capabilities and client-side interactivity.
  • Backend: ASP.NET Core for APIs and database interactions.
  • Database: Azure Cosmos DB for scalability and global reach.
  • Real-Time Features: SignalR for live updates of fitness metrics.

Design Considerations

  • Mobile-first responsive design.
  • Use of Blazorโ€™s component-based architecture for reusability.
  • Focus on performance with lazy loading and optimized service workers.

Step 2: Development

1. Building Core Components

We began by designing reusable Blazor components for the key features:

  • Workout Form: A form to log exercises, integrated with validation using EditForm and DataAnnotations.
  • Progress Charts: Built using a Blazor-friendly chart library like Chart.js or Syncfusion.
  • Metrics Dashboard: A real-time dashboard powered by SignalR.

Example: Workout Form


<EditForm Model="workout" OnValidSubmit="LogWorkout"> <InputText id="exercise" @bind-Value="workout.Exercise" placeholder="Exercise Name" /> <InputNumber id="duration" @bind-Value="workout.Duration" placeholder="Duration (mins)" /> <button type="submit">Log Workout</button> </EditForm> @code { private Workout workout = new Workout(); private async Task LogWorkout() { await Http.PostAsJsonAsync("api/workouts", workout); } }

2. Adding Real-Time Features

Using SignalR, we updated the metrics dashboard in real-time. For example, calories burned were calculated on the server and sent to connected clients.

SignalR Integration Example

  • Hub (Backend):


    public class MetricsHub : Hub { public async Task BroadcastMetrics(Metrics metrics) { await Clients.All.SendAsync("ReceiveMetrics", metrics); } }
  • Blazor Component (Frontend):


    @inject HubConnection HubConnection <h3>Calories Burned: @calories</h3> @code { private int calories; protected override async Task OnInitializedAsync() { HubConnection.On<int>("ReceiveMetrics", (data) => { calories = data; StateHasChanged(); }); await HubConnection.StartAsync(); } }

3. Enabling Offline Access

Blazorโ€™s PWA capabilities made adding offline functionality straightforward:

  • Service Workers: Caching static assets and API responses.
  • IndexedDB: Storing offline workout data for synchronization.

Service Worker Configuration:


self.addEventListener('install', (event) => { event.waitUntil( caches.open('fitness-tracker-cache').then((cache) => { return cache.addAll([ '/', '/index.html', '/css/app.css', '/_framework/blazor.webassembly.js', ]); }) ); });

Step 3: Testing

To ensure reliability, we:

  • Wrote unit tests for Blazor components using bUnit.
  • Simulated real-world scenarios for offline and online transitions.
  • Conducted load testing on the backend API to handle high traffic.

Example: Unit Test for Workout Form


[Fact] public void WorkoutForm_ShouldLogWorkoutOnSubmit() { var component = RenderComponent<WorkoutForm>(); component.Find("input#exercise").Change("Running"); component.Find("input#duration").Change("30"); component.Find("button").Click(); Assert.Contains("Workout logged successfully", component.Markup); }

Step 4: Deployment

Hosting

We deployed the Blazor PWA on Azure Static Web Apps, leveraging its global distribution and integrated APIs.

Deployment Steps

  1. Publish the Blazor app:

    dotnet publish --configuration Release
  2. Deploy to Azure:

    az staticwebapp create --name FitnessTrackerPWA --source ./wwwroot --branch main

Testing in Production

We tested:

  • PWA installation on iOS, Android, and desktop devices.
  • Offline functionality by simulating network disconnections.
  • Real-time updates under varying loads.

Step 5: Lessons Learned

  1. Optimize Asset Loading
    Using lazy loading for components and static assets significantly improved performance, especially on mobile devices.

  2. Test Offline Scenarios Early
    Testing offline capabilities from the beginning helped us identify caching issues and optimize service worker configurations.

  3. Focus on User Experience
    Creating a polished manifest.json file and professional-grade icons enhanced the appโ€™s look and feel when installed as a PWA.

  4. Leverage Real-Time Features Wisely
    SignalR proved invaluable for live metrics but required careful optimization to reduce bandwidth usage.


Conclusion

From concept to deployment, building the fitness tracker PWA with Blazor was a rewarding journey. By leveraging Blazorโ€™s powerful features and following best practices, we delivered a fast, reliable, and engaging application that works seamlessly across devices.

If youโ€™re looking to build your own Blazor PWA, this case study offers a blueprint to guide you. For more detailed insights and advanced techniques, check out my book, Building Progressive Web Apps with Blazor.

Letโ€™s build something amazing with Blazor! ๐Ÿš€

Comments

Popular posts from this blog

Yes, Blazor Server can scale!

Blazor - Displaying an Image

Blazor new and improved Search Box