Table of Contents

Lazy loading

Starting with version 1.19, EF Core lazy loading is activated by default in Neos. More information about EF Core lazy loading.

Why is lazy loading activated by default?

Lazy loading is considered by some to be an anti-pattern. Its use is the subject of debate. If used incorrectly, it can lead to a very large number of requests being triggered, which can have a detrimental effect on performance.

However, it was decided to activate it by default for several reasons:

  • On a collection navigation property, if it is not enabled, business code could browse an empty collection because it has not been populated. This can lead to erroneous data without errors.
  • On a reference navigation property, if it is not activated, a NullReferenceException could be thrown.
  • On a property that is not read all the time in a business process, this can avoid loading data that will not be used.
  • When several business functions are triggered and they need the same data, the subsequent ones will naturally take advantage of the data loaded by the first function.

Used properly, it can prevent production bugs and contribute to the overall performance of the application.

How do I know if lazy loading is occurring?

When EF Core triggers lazy loading, an information log is output and is visible in the console:

16:29:09 INF Proxy/MyCluster/Back/Microsoft.EntityFrameworkCore.Infrastructure.NavigationLazyLoading - The navigation 'Order.Customer' is being lazy-loaded.
16:29:09 INF Proxy/MyCluster/Back/Microsoft.EntityFrameworkCore.Infrastructure.NavigationLazyLoading - The navigation 'Customer.Prices' is being lazy-loaded.
16:29:09 INF Proxy/MyCluster/Back/Microsoft.EntityFrameworkCore.Infrastructure.NavigationLazyLoading - The navigation 'OrderDetail.Product' is being lazy-loaded.

A tab also appears in the manager showing these same logs (this tab only appears when the first log is sent):

16:29:09 The navigation 'Order.Customer' is being lazy-loaded.
16:29:09 The navigation 'Customer.Prices' is being lazy-loaded.
16:29:09 The navigation 'OrderDetail.Product' is being lazy-loaded.

Finally, the query also appears in the backend monitoring, just like any other SQL query that has been executed.

Can I disable lazy loading?

In theory, yes, this is possible if you don't use any external modules and you're sure that none of your modules rely on lazy loading. If you are using external modules (which will generally be the case), you are strongly advised not to deactivate it, as you have no control over the code written in these modules.

To disable lazy loading, you need to change a setting in the ASP.NET Core application configuration.

Example of appsettings.Development.json:

{
  "PersistenceSettings": {
    "LazyLoadingEnabled": false
  }
}

How can I have warnings instead of information messages?

This can make the logs more visible in the console.

Messages sent by EF Core can be configured in cluster configuration.

Example:

EFCoreWarnings:
  CoreEventId.NavigationLazyLoading: Warning

How can I get an exception when lazy loading is triggered?

In development, it can be useful to have an exception thrown every time lazy loading occurs. This can be useful for :

  • Avoid triggering lazy loading by mistake on a new development.
  • Identify the cause of lazy loading by obtaining a call stack to guide us.

It can also can be configured in cluster configuration.

Example:

EFCoreWarnings:
  CoreEventId.NavigationLazyLoading: Throw

How can I prevent lazy loading?

To prevent lazy loading, you have to do eager loading or to use repositories instead of navigation properties.

How can I disable lazy loading on a given property?

This functionality is not yet available in Neos. However, it has been available since version 8 of EF Core and will potentially be implemented in a future version.