Moving .htaccess rules into the vhost stops the per-request read

With AllowOverride set to anything but None, Apache looks for an .htaccess file in every directory from the document root down to the requested file, on every request, and parses any it finds. The same rules placed in the vhost are read once at startup and compiled.

<Directory /var/www/shop/public>
    AllowOverride None
    Options -Indexes +FollowSymLinks

    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php/$1 [L]
</Directory>

For a file four directories deep that is four failed stat calls before anything useful happens, and a page pulling eighty assets pays it eighty times. The saving is small per request and quite visible under load. What you give up is the ability to change a rule without touching the server: the vhost needs a reload, and on shared hosting you have no vhost to edit at all, which is the entire reason .htaccess exists. Set AllowOverride None explicitly rather than trusting the default, because the default has changed between Apache versions and inheriting it from a parent <Directory> block is easy to do by accident.