Implementing Lazy Loading in Full Stack .NET Applications
Lazy Loading is a design pattern that delays the loading of data or resources until they are actually needed.
In full stack .NET applications, lazy loading is commonly used to improve performance, reduce database queries, and optimize page or API response times.
Lazy loading is most often applied in:
Entity Framework Core (load related entities only when accessed)
Frontend (React/Angular) (load heavy components only when needed)
API calls (fetch data in smaller chunks or on demand)
Images or media (load only when visible)
This guide focuses mainly on Entity Framework Core, but also covers front-end lazy loading in a full-stack scenario.
1. Lazy Loading in Entity Framework Core
Entity Framework Core supports lazy loading via:
✔ Proxies
✔ Manual loading
✔ Explicit loading
1.1 Enabling Lazy Loading with Proxies
Install the lazy loading package:
dotnet add package Microsoft.EntityFrameworkCore.Proxies
Configure EF Core to Use Lazy Loading
In your Program.cs or DbContext registration:
services.AddDbContext<AppDbContext>(options =>
options.UseLazyLoadingProxies()
.UseSqlServer(configuration.GetConnectionString("DefaultConnection")));
Modify Your Entities to Use Virtual Navigation Properties
Lazy loading ONLY works when navigation properties are marked as virtual.
public class Order
{
public int Id { get; set; }
public string CustomerName { get; set; }
public virtual ICollection<OrderItem> OrderItems { get; set; }
}
public class OrderItem
{
public int Id { get; set; }
public string Product { get; set; }
public decimal Price { get; set; }
public virtual Order Order { get; set; }
}
Now the related data (OrderItems) will be loaded automatically ONLY when accessed:
var order = await _context.Orders.FirstAsync();
var items = order.OrderItems; // Lazy loading triggers here
Pros and Cons of Lazy Loading in EF Core
✔ Advantages
Fewer initial database queries
Simpler code for retrieving related data
Only loads what the user needs
✘ Disadvantages
Hidden multiple queries (N+1 problem)
Harder to debug
Not ideal for APIs returning full object graphs
1.2 Explicit Loading (Recommended for APIs)
Explicit loading gives full control:
var order = await _context.Orders.FirstAsync();
await _context.Entry(order)
.Collection(o => o.OrderItems)
.LoadAsync();
You decide when to load related data.
1.3 Eager Loading (For comparison)
Not lazy loading, but sometimes better:
var order = await _context.Orders
.Include(o => o.OrderItems)
.FirstAsync();
2. Lazy Loading in Frontend (React / Angular)
Full stack .NET apps often use React or Angular.
2.1 Lazy Loading Components (React)
React supports lazy loading using React.lazy():
const Dashboard = React.lazy(() => import('./components/Dashboard'));
Show a fallback with Suspense:
<Suspense fallback={<div>Loading...</div>}>
<Dashboard />
</Suspense>
This improves:
Initial page load time
Bundle size
Render performance
2.2 Lazy Loading Routes (React Router)
const Reports = React.lazy(() => import("./pages/Reports"));
<Route path="/reports" element={
<Suspense fallback={<p>Loading...</p>}>
<Reports />
</Suspense>
} />
2.3 Lazy Loading in Angular
Angular has built-in lazy loading for modules:
{
path: 'users',
loadChildren: () =>
import('./users/users.module').then(m => m.UsersModule)
}
3. Lazy Loading for Images and Media
Large images should load on demand.
HTML loading="lazy":
<img src="/images/photo.jpg" loading="lazy" />
React example:
<img src={imgUrl} loading="lazy" alt="Product" />
This reduces:
Initial page weight
Bandwidth
Rendering time
4. Lazy Loading in API Design
Lazy loading can apply to API endpoints:
✔ Pagination (load small chunks)
GET /api/products?page=1&pageSize=20
✔ Infinite scroll
Only load the next batch when the user scrolls.
✔ On-demand loading of nested resources
Do not include everything unless needed.
Example:
GET /api/orders/1?includeItems=false
5. Full Stack Example of Lazy Loading
Step 1: Backend (EF Core)
Enable lazy loading proxies → related entities load on demand.
Step 2: API returns only summary data
{
"id": 1,
"customerName": "John"
}
Step 3: When user opens order details
React makes another request:
GET /api/orders/1/items
Step 4: React lazily loads the details component
const OrderDetails = React.lazy(() => import("./OrderDetails"));
Final Result:
✔ Faster initial load
✔ Better performance
✔ No unnecessary data transfer
Conclusion
Lazy loading improves performance in full stack .NET applications by:
Reducing database load (EF Core lazy loading)
Speeding up UI (React/Angular lazy components)
Optimizing network calls (lazy API requests)
Loading media only when needed
Use lazy loading carefully—especially with EF Core—to avoid hidden queries and ensure predictable performance.
Learn Dot Net Course in Hyderabad
Read More
How to Implement Real-Time Features with SignalR and React
Building Mobile Apps with Blazor WebAssembly
How to Use Webpack for Full Stack .NET Front-End Projects
Working with TypeScript and JavaScript in Full Stack .NET
Visit Our Quality Thought Institute in Hyderabad
Subscribe by Email
Follow Updates Articles from This Blog via Email
No Comments