Bild von Code

Magento 2 3/23/2017

Why and How to disable unused Magento 2 core modules

The uncached load time of the homepage of a local Magento 2.1.5 shop dropped from 4.5 seconds to 2.6 seconds on average after I disabled all Magento 2 core modules which could be disabled. Disclaimer: Measurements were done with disabled caches and activated developer mode on my local machine.

Even though most pages will be delivered cached, there will always be requests where only parts of the pages can be cached. The general performance increase won't be 40% on a live server, but it will still be noticeable. And during development, when cache is being cleared frequently, it makes a huge difference.

That should be reason enough to disable as many modules as possible, right?

As an additional benefit, the admin users won't get distracted by configuration options and features which aren't used in your project.

What did I do?

Magento 2 brings a mechanism to disable single modules, including core modules. You can do that using the integrated command line tool. The call could look like this:
bin/magento module:disable Magento_Marketplace
Many core modules of Magento 2 cannot be disabled - you will get an error message because other modules depend on that module if you try to disable them. So I created a small tool which helps me find out which modules can be disabled easily.

New command line tool: info:dependencies:show-removable

You can find the module containing the new command on GitHub: https://github.com/avstudnitz/AvS_DisableModules/. You can install the module via composer ("avstudnitz/disable-modules") or by dropping the content of the repository into app/code/AvS/DisableModules/. More detailed installation instructed are provided on the GitHub page.

After installation, you'll have a new command available:

$ bin/magento info:dependencies:show-removable

This will give you an output like this:

Report successfully processed. File "modules-removable.csv" generated.

The file modules-removable.csv contains content like this:

"Modules without dependencies:"
" =========================== "

Magento_Weee
Magento_WebapiSecurity
Magento_Version
Magento_Usps
Magento_Ups
Magento_TaxImportExport
Magento_SwatchesLayeredNavigation
Magento_Swagger
Magento_Sitemap
...

All those files can be safely deleted. Add the following code in front of each line and paste it into the shell:

bin/magento module:disable

After you have disabled the modules, you can do a second run - new modules might show up which can now be disabled as they were only required by modules which you have just disabled.

Which modules should be disabled?

In a default Magento 2.1.5 CE installation, the following modules can be disabled - in some cases only after other modules from the list have been disabled:
Magento_AdvancedPricingImportExport
Magento_AdminNotification
Magento_Authorizenet
Magento_Braintree
Magento_Bundle
Magento_BundleImportExport
Magento_CacheInvalidate
Magento_Captcha
Magento_CatalogRuleConfigurable
Magento_CatalogWidget
Magento_CheckoutAgreements
Magento_ConfigurableImportExport
Magento_ConfigurableProduct
Magento_Cookie
Magento_CurrencySymbol
Magento_CustomerImportExport
Magento_Deploy
Magento_Dhl
Magento_DownloadableImportExport
Magento_EncryptionKey
Magento_Fedex
Magento_GoogleAdwords
Magento_GoogleAnalytics
Magento_GoogleOptimizer
Magento_GroupedImportExport
Magento_LayeredNavigation
Magento_Marketplace
Magento_Multishipping
Magento_NewRelicReporting
Magento_OfflinePayments
Magento_OfflineShipping
Magento_Paypal
Magento_Persistent
Magento_ProductVideo
Magento_SalesInventory
Magento_SendFriend
Magento_Sitemap
Magento_Swagger
Magento_Swatches
Magento_SwatchesLayeredNavigation
Magento_TaxImportExport
Magento_Ups
Magento_Usps
Magento_Vault
Magento_Version
Magento_Webapi
Magento_WebapiSecurity
Magento_Weee

First rule: Don't disable any modules whose functionality you need! (Obviously) Second rule: Don't rely on Magento's modularity. This means: there may be hidden dependencies.

Hidden Dependencies

Dependencies are declared in the composer.json file of each module. This is a manual process - in some cases, not all dependencies have been declared by the Magento core team. A module might still require another module even if it doesn't say so.

In our recent project, we disabled Magento_ConfigurableProduct as we were using Grouped Products and Simple Products only. At first, it looked okay, but then we got an error during indexing which led us to the conclusion that the indexer has a hidden dependency to the Configurable Products module.

So: Try out if everything (still) works in your project and observe the behaviour. If you have automatic tests available: perfect, they help you find hidden dependencies much faster.

Practical Example

In our current project, we disabled about 30 modules, which works out well so far. This is the list of modules, those which are disabled are marked with a "0" (from app/etc/config.php):

<?php
return array(
  'modules' =>
  array(
    'Magento_Config' => 1,
    'Magento_Store' => 1,
    'Magento_Directory' => 1,
    'Magento_AdvancedPricingImportExport' => 0,
    'Magento_Backend' => 1,
    'Magento_Theme' => 1,
    'Magento_Eav' => 1,
    'Magento_Backup' => 1,
    'Magento_Customer' => 1,
    'Magento_AdminNotification' => 0,
    'Magento_BundleImportExport' => 0,
    'Magento_CacheInvalidate' => 1,
    'Magento_Indexer' => 1,
    'Magento_Cms' => 1,
    'Magento_CatalogImportExport' => 1,
    'Magento_Catalog' => 1,
    'Magento_Rule' => 1,
    'Magento_Msrp' => 1,
    'Magento_Search' => 1,
    'Magento_CatalogUrlRewrite' => 1,
    'Magento_Widget' => 1,
    'Magento_Quote' => 1,
    'Magento_CheckoutAgreements' => 1,
    'FireGento_MageSetup' => 1,
    'Magento_CmsUrlRewrite' => 1,
    'AvS_ScopeHint' => 1,
    'Magento_ConfigurableImportExport' => 0,
    'Magento_SalesSequence' => 1,
    'Magento_Contact' => 1,
    'Magento_Cookie' => 1,
    'Magento_Cron' => 1,
    'Magento_CurrencySymbol' => 1,
    'Magento_Payment' => 1,
    'Magento_CustomerImportExport' => 1,
    'Magento_Deploy' => 1,
    'Magento_Developer' => 1,
    'Magento_Dhl' => 0,
    'Magento_Authorization' => 1,
    'Magento_Downloadable' => 1,
    'Magento_ImportExport' => 1,
    'Magento_Bundle' => 0,
    'Magento_Email' => 1,
    'Magento_User' => 1,
    'Magento_Fedex' => 0,
    'Magento_Sales' => 1,
    'Magento_CatalogInventory' => 1,
    'Magento_GoogleAnalytics' => 1,
    'Magento_Ui' => 1,
    'Magento_GroupedImportExport' => 1,
    'Magento_GroupedProduct' => 1,
    'Magento_DownloadableImportExport' => 1,
    'Magento_Checkout' => 1,
    'Magento_Security' => 1,
    'Magento_LayeredNavigation' => 1,
    'Magento_Marketplace' => 0,
    'Magento_MediaStorage' => 1,
    'Magento_ConfigurableProduct' => 1,
    'Magento_Multishipping' => 0,
    'Magento_NewRelicReporting' => 1,
    'Magento_Newsletter' => 1,
    'Magento_OfflinePayments' => 1,
    'Magento_SalesRule' => 1,
    'Magento_PageCache' => 1,
    'Magento_Captcha' => 0,
    'Magento_Vault' => 1,
    'Magento_Persistent' => 0,
    'Magento_ProductAlert' => 1,
    'Magento_ProductVideo' => 0,
    'Magento_CatalogRule' => 1,
    'Magento_Reports' => 1,
    'Magento_RequireJs' => 1,
    'Magento_Review' => 1,
    'Magento_Rss' => 1,
    'Magento_CatalogRuleConfigurable' => 0,
    'Magento_Authorizenet' => 0,
    'Magento_SalesInventory' => 1,
    'Magento_OfflineShipping' => 1,
    'Magento_GoogleAdwords' => 0,
    'Magento_SampleData' => 0,
    'Magento_CatalogSearch' => 1,
    'Magento_Integration' => 1,
    'Magento_SendFriend' => 0,
    'Magento_Shipping' => 1,
    'Magento_Sitemap' => 1,
    'Magento_Paypal' => 1,
    'Magento_Swagger' => 0,
    'Magento_Swatches' => 0,
    'Magento_SwatchesLayeredNavigation' => 0,
    'Magento_Tax' => 1,
    'Magento_TaxImportExport' => 0,
    'Magento_GiftMessage' => 1,
    'Magento_Translation' => 1,
    'Magento_GoogleOptimizer' => 0,
    'Magento_Ups' => 0,
    'Magento_UrlRewrite' => 1,
    'Magento_EncryptionKey' => 0,
    'Magento_Usps' => 0,
    'Magento_Variable' => 1,
    'Magento_Braintree' => 0,
    'Magento_Version' => 1,
    'Magento_Webapi' => 1,
    'Magento_WebapiSecurity' => 0,
    'Magento_Weee' => 0,
    'Magento_CatalogWidget' => 0,
    'Magento_Wishlist' => 1,
    'Staempfli_ImageResizer' => 1,
    'Yireo_AutoFlushCache' => 1,
  ),
);

Project specific modules have been stripped from the list. Feel free to take this module list as a starting point for your module.

Conclusion

Magento 2 is a big step forward regarding modularity, compared to Magento 1. On the other hand, some work still has to be done for even better modularity. You can gain a much better performance by disabling the right modules. But be careful: some modules might be needed even if you don't recognize that on first sight. Personally, I will start off new projects by disabling unneeded modules first from now on.