3

I was wondering if dependency injection can be bad for the performance of the website.

For example:

Let's say that I'm building a helper class for my module and it contains a lot of useful methods that use a lot of injected dependencies (let's say 20+), but, not everything is always needed at the same time (so it's not really a "dependency" for the whole helper class).

Now, I know that it's good practice to use the constructor in order to inject the dependencies (and also that it's better for allowing overrides using di.xml), but wouldn't it be more efficient in terms of performance to load the dependencies on demand using the object manager?

  • That's a nice question – Raul Sanchez Jul 19 '18 at 8:47
3

First of all, the 'helper class' architectural pattern is more of an anti-pattern and its use is discouraged in Magento 2.

If you have dependencies that may be used in some contexts, but not in others, that sounds like the class is trying to do too much. Try decomposing (i.e. Refactoring) the class into two or more new classes which have more specific purposes.

For logic that you want to re-use across multiple classes, investigate using Traits rather than helpers: http://php.net/traits

but wouldn't it be more efficient in terms of performance to load the dependencies on demand using object manager?

I can't argue based on performance. I can tell you that using the Object Manager in your code is discouraged in Magento 2 development and it incurs technical debt. If you do use the Object Manager, then you are bypassing Dependency Injection and all the benefits that go with it. Magento relies on DI in order to make other features of the framework function as well (as you note in your answer).

You may not be using those features in your module now, but if you need to use them for some future change to your module and you're not using DI, you'll have the burden of having to refactor away all those uses of the object manager, i.e. That is when you pay that technical debt you incurred earlier. So you're not really saving time - you're just kicking that technical debt down the road.

If you are worried that your dependencies will have a performance impact, then there are ways to mitigate that:

Proxy classes

You can inject Proxy Classes in order to reduce the burden of loading all the dependencies. Proxy Classes are classes which extend from the 'real' class, but don't contain any actual logic. They work more like placeholders. If a method defined in a Proxy Class is called, then the Proxy Class calls the method on the 'real' class, which are lazy-loaded.

The DevDocs has a more complete explanation and examples: https://devdocs.magento.com/guides/v2.2/extension-dev-guide/proxies.html

Context classes

Context classes were introduced to allow for backwards compatible constructor modifications of classes that were supposed to be extended by extension developers. If you need to provide backwards-compatibility, then this is the way to go. However, as Magento 2 moves from inheritance-based APIs (i.e. Adding new functionality by adding a new class which extends an existing class) all such classes will be deprecated together with the classes they were introduced for.

  • I agree with what you say. I was just wondering if it has any effect on the performance. Any guess? – Pini Jul 19 '18 at 11:03
  • My answer to that question is 'it depends'. It depends on your particular solution. You could always use profiling to get an answer that fits your situation. In general though, my answer is 'Maybe - Magento provides these means to mitigate that if you find that it does). – ProcessEight Jul 19 '18 at 12:13
  • @Pini In summary I'd say the Dependency Injection and Object Manager are not the problem and do not cause a performance issue. The problem is the design: 1. the Helper class that has to many other dependencies, 2. not using Proxy classes. That said, I'm wondering why Proxies aren't used in general. I'd like to know when Proxies should be avoided... – robsch 1 hour ago
0

I am having this problem myself porting an M1 site to M2. All the modules written for M1 use the Mage god class to load models, helpers, etc; but those loads are scoped to the methods where they are called. This led to lots of single classes and helpers with multiple responsibilities, which is poor design. I guess the fix is to break up the classes so that each class or helper has a single responsibility in which case there will be fewer dependencies that need to be loaded.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.