Saved 500 Kbytes of autoload classmap with autoload-dev at @AtrapaloEng

This week, at Atrápalo, we have reviewed our autoloading Composer configuration to use PSR-4 and split production classmap from development classmap to save some space in our Opcache. The result, 500 Kbytes less. Let’s see some details.

As you may know, when going to production, it’s a best practice to run “php composer.phar dump-autoload –optimize –no-dev” as one of your steps, or just “php composer.phar install […] –optimize-autoloader –no-dev” when installing your dependencies.

With this command, Composer generates a PHP file with a big array where keys are the names of all classes in your project and the values are the path where they can be found. With this approach, autoloading a class is as easy as requiring the result of one access to a PHP array, fast.

<?php

// autoload_classmap.php @generated by Composer

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
    //...
    'Atrapalo\\Catalog\\Domain\\Accommodation\\Rate\\Price' => $baseDir . '/src/Atrapalo/Catalog/Domain/Accommodation/Rate/Price.php',
    'Atrapalo\\Catalog\\Domain\\Accommodation\\Rate\\Rate' => $baseDir . '/src/Atrapalo/Catalog/Domain/Accommodation/Rate/Rate.php',
    'Atrapalo\\Catalog\\Domain\\Accommodation\\Rate\\RateServices' => $baseDir . '/src/Atrapalo/Catalog/Domain/Accommodation/Rate/RateServices.php',
    //...
);

Because the classmap file is a PHP file, it gets loaded into Opcache, fast again. But, if we take a closer look, there are some entries in this array related to your test classes that make the array bigger than needed for production. There are different options for removing those unnecessary entries:

  1. exclude-files-from-classmaps: If you want to exclude some files or folders from the classmap you can use the ‘exclude-from-classmap’ property. This might be useful to exclude test classes in your live environment, for example, as those will be skipped from the classmap even when building an optimized autoloader.The classmap generator will ignore all files in the paths configured here. The paths are absolute from the package root directory (i.e. composer.json location), and support * to match anything but a slash, and ** to match anything. ** is implicitly added to the end of the paths.Example:
    {
        "autoload": {
            "exclude-from-classmap": ["/Tests/", "/test/", "/tests/"]
        }
    }
  2. autoload-dev: This section allows to define autoload rules for development purposes.Classes needed to run the test suite should not be included in the main autoload rules to avoid polluting the autoloader in production and when other people use your package as a dependency.Therefore, it is a good idea to rely on a dedicated path for your unit tests and to add it within the autoload-dev section.Example:
    {
        "autoload": {
            "psr-4": { "MyLibrary\\": "src/" }
        },
        "autoload-dev": {
            "psr-4": { "MyLibrary\\Tests\\": "tests/" }
        }
    }

With all these considerations, we have grouped all our test classes into a /tests folder, we have added PSR-4 splitting dev and no-dev.

# ls -lah vendor/composer/autoload_classmap.php
-rw-r--r-- 1 wwwagent wwwagent 4,8M abr 11 11:01 vendor/composer/autoload_classmap.php
# ls -lah vendor/composer/autoload_classmap.php
-rw-r--r-- 1 wwwagent wwwagent 4,3M abr 12 16:46 vendor/composer/autoload_classmap.php

The result is 500Kb less. For more information, take a look to http://es.slideshare.net/javier.eguiluz/new-symfony-tips-tricks-symfonycon-paris-2015 by Javier Eguiluz.