When I worked at IMPRES, I got to know Statamic. Statamic is cool and rad (in a good way). The docs are rad and cool too, but not always very comprehensive and sometimes a bit too jolly. With the latest redesign, that has improved, but it can still be a puzzle to figure out what is a good setup for your own Statamic website. So I thought it would be a good idea to share my own settings here.
My hosting/application environment
It's good to know what hosting environment my site is running on, so you can understand why I made certain choices. My website runs on a fairly standard Linux hosting environment with PHP 8 (where php-extensions are supported), this runs behind the well-known Apache2.4 web server. Almost every shared hosting provider in the Netherlands (and also mostly worldwide) offers such a setup. Sometimes the web server nginx is used, but not often as the primary web server.
I am using Statamic 5.x with mostly default settings except for I’m sharing below. So my website does not have its own (relational) database like MySQL.
My Statamic settings
Okay, here they are; my Statamic settings. I'm assuming that you've already configured things like APP_ENV=production. Also, I am using the file -stores for sessions and cache.
.env values
# Make sure the full static caching strategy will kick in
STATAMIC_STATIC_CACHING_STRATEGY='full'
# Disable this for speed ('auto' is also valid)
STATAMIC_STACHE_WATCHER=false
# Antler cache, mostly this is enable, but please make sure
STATAMIC_CACHE_TAGS_ENABLED=true
# Let Glide (image reziser) save to the 'public' folder
SAVE_CACHED_IMAGES=trueThe last setting ensures that image sizes are stored in the right formats in the public folder, and therefore no longer need to be generated or served by PHP. These dimensions come from your templates or from config('statamic.assets.presets') .
.htaccess modifications for Statamic
My webhosting offers Apache2, which allows for a few possibilities to tweak settings. Therefore, I made the following addition in my .htaccess file. If you forget to set this up, full-static caching has no effect because the pre-generated HTML files are skipped when calling your website. In that case, PHP still has to do 'all the work', and the site appears slower for visitors anyway.
I have the following before the lines leading to the index.php (see this Statamic-default htaccess):
# Zorg dat HTML bestanden worden gebruikt
RewriteCond %{DOCUMENT_ROOT}/static/%{REQUEST_URI}_%{QUERY_STRING}\.html -s
RewriteCond %{REQUEST_METHOD} GET
RewriteRule .* static/%{REQUEST_URI}_%{QUERY_STRING}\.html [L,T=text/html]Click here for the final result.
In a few cases, a shared hosting party uses nginx, the other (fast) web server. Usually when this is used, it’s already a more advanced environment. For instructions on this, I would (still) refer you to the Statamic documentation.
.htaccess modifications for file caching
Besides setting up Statamic properly, you can apply even more rules to tell browsers that they really only need to download some files once and then not to fetch them again for a long time. This is useful for images, stylesheets, fonts and your JavaScript.
This is also in my .htaccess file, which tells the browser to keep (and display) the files for a year without first checking our server.
# Define content types for some 'new' filetypes
AddType application/vnd.ms-fontobject .eot
AddType application/x-font-ttf .ttf
AddType application/x-font-opentype .otf
AddType application/x-font-woff .woff
AddType application/x-font-woff .woff2
AddType image/svg+xml .svg
# Define the expire headers
<ifModule mod_expires.c>
ExpiresActive On
# For reloaders
ExpiresDefault "access plus 5 seconds"
ExpiresByType image/x-icon "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType image/avif "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
ExpiresByType text/css "access plus 1 year"
ExpiresByType text/javascript "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType application/x-javascript "access plus 1 year"
ExpiresByType text/html "access plus 1800 seconds"
ExpiresByType application/xhtml+xml "access plus 1800 seconds"
ExpiresByType application/vnd.ms-fontobject "access plus 1 year"
ExpiresByType application/x-font-ttf "access plus 1 year"
ExpiresByType application/x-font-opentype "access plus 1 year"
ExpiresByType application/x-font-woff "access plus 1 year"
</ifModule>
<ifModule mod_headers.c>
# Instructions for browser cache control
<filesMatch "\.(jpe?g|png|gif|svg|css|js)$">
Header set Cache-Control "public"
</filesMatch>
</ifModule>Rolling out (a new version of) the website
Static caching does require you to perform some different actions when you roll out a website. These actions, which you call via php artisan xxx, ensure that, for example, the images are prepared and the (new) static files. After updating the site (e.g. with git pull or rsync), I run the following commands for a correct deploy.
php artisan optimize:clear
php artisan statamic:static:clear
php artisan statamic:stache:warm
php artisan statamic:assets:generate-presets
php artisan statamic:search:update --all # If you offer searchAs you can see, I don't use php please but work with php artisan statamic:xxx:xxx . That does the same thing, and I find easier to use, so a personal choice.
Hopefully this overview will give you some information on how to properly 'tune' your Statamic site to be fast. If you have any further questions or comments, you may of course always contact me or leave a comment.