One line in configuration will speed up your Nette application. How is that possible?

5 days ago by David Grudl  

Imagine you have a large application with dozens of services – database, logger, mailer, cache, and many others. During each HTTP request, all these services are created, even if you don't use them at all. This unnecessarily slows down your application. The new version of PHP 8.4 and Nette brings an elegant solution to this problem using so-called lazy objects.

What are lazy objects?

A lazy object is a special type of object that looks and behaves exactly like the actual service from your code's perspective, but in reality, it delays its initialization until it's actually needed. When we request a database service from the DI container, for example, we get an object that externally looks like a regular instance of Database, but it hasn't actually established a database connection yet. This happens only when we first actually use the service.

Example:

// We get an object that looks like Database but hasn't established a connection yet
$database = $container->getByType(Database::class);
// The database connection is created HERE, during first actual use
$database->query('SELECT * FROM users');

How to enable it?

In the new version of Nette DI 3.2.4, all you need is one line in configuration:

di:
    lazy: true

That's all! From now on, all services in the DI container will be created “lazily”.

We can also set lazy creation for individual services:

services:
    newsletter:
        create: Newsletter
        lazy: false   # this service will be created immediately, even if lazy is globally enabled
    database:
        create: Database
        lazy: true    # this service will be lazy, even if lazy is globally disabled

Benefits in practice

  1. Faster application startup – only services you actually need are created
  2. Lower memory consumption – unused services don't take up space
  3. Simple implementation – just one line in configuration

It's important to note that lazy objects logically change how service configuration errors manifest themselves. For example, incorrect database credentials won't show up at application startup, but only during the first actual database connection.

Limitations and recommendations

  • Lazy objects work only for your own classes
  • They cannot be used for internal PHP classes
  • Requires PHP 8.4 or higher

Lazy objects represent a significant step forward in PHP application optimization. Thanks to them, your Nette applications can be faster and more efficient without changing a single line of your code.