The ultimate guide to a fast concrete5 website

An overview of practical performance tips to speed up your concrete5 website.

This compilation of performance tips for your concrete5 website / application is meant for production environments.

Server

  • Choose a fast hosting provider.
    • If you serve a lot of regional visitors, a provider that has its servers in your region makes most sense. If my visitors are mostly from Germany, I want my website running on a server in Germany, not on a server in California.
    • In order to choose a fast provider, sign up for different providers and use trial accounts to compare the server response times with a fresh concrete5 installation that has caching disabled.
    • Make sure the server runs on the latest PHP version. If your hosting provider is still using 7.0, it's an indication that they are behind and that you can probably find better alternatives.
  • Make sure OPcache is enabled. If you run a lot of concrete5 websites on one server, and you don't use symlinks, you also may want to consider increasing the max_accelerated_files value. To monitor which files are being cached, and whether it hits certain limits, use the OPcache Status tool.
  • Verify that GZip is enabled. With GZip the server will compress the response before it's sent back to the browser. The browser will automatically decompress the response. This approach is quicker than transferring a larger response body.
  • If you have technical background, use tools like Blackfire to find bottlenecks and to profile your website / application. Blackfire is expensive, but it's very sophisticated and they offer trial accounts.

concrete5 caching

  • Enable Full Page Caching (FPC) if you can. It's the most significant performance boost you can get. However, you should only enable FPC in case your pages don't contain dynamic content that can differ per request. E.g. if you have a website where members can log in, you shouldn't enable FPC (for those pages) because the output differs per logged-in user / request. Also be careful with pages that submit data, e.g. contact forms, booking pages, search result pages. You can enable FPC globally, and disable it on a per page basis, or you can disable it globally, and enable it for individual pages.
  • If FPC is enabled, set the expiration to "Only when manually removed or the cache is cleared" unless you have a good reason of why the page should be flushed after x-amount of time.
  • Cache Warmer automatically regenerates the Full Page Cache for pages. If you flush the concrete5 cache, all HTML output needs to be regenerated. Cache Warmer regenerates that HTML output. It can be set up as a (minute) cron job and it offers a CLI mode. It's a paid add-on and I highly recommend it for websites that use Full Page Cache.
  • Always enable Block Cache and Overrides cache.

concrete5 performance tips

  • Use the latest version of concrete5. Each release comes with changes that are likely to improve overall performance.
  • Disable external content from concrete5.org
    • Disable the welcome page, it renders slowly because external content from the concrete5 servers is retrieved.
    • Disable external marketplace integration. When using the Intelligent Search, concrete5 will automatically search the marketplace for themes and add-ons that match your search query.
    • Disable external help. When using the Intelligent Search, the forum is searched for relevant forum posts that match your query.
    • Disable the login background. By default it will render an image from concrete5.org, which slows things down.
    • Note: the settings above can all be changed via the GDPR add-on.
  • Only enable Advanced Permissions if you have to. If you just have one user account, there is no reason to enable Advanced Permissions.
  • Make sure 'Database queries' are not logged (see Logging Settings).
  • Remove Drafts you don't need. I often see websites with dozens of page drafts that are not going to be published. If the number of pages grows, database queries and page lists tend to become slower.
  • Remove page versions you don't need anymore. With the 'Remove Old Page Versions' automated job you can remove old page versions.
  • Minify HTML minifies the HTML output of every page. Use it in combination with Full Page Caching to get the best results. The smaller the HTML size, the faster it can be sent back to the client. Minify HTML is a paid add-on and I recommend it if you want to maximize performance.

Assets (js, css, fonts, etc.)

  • Content Delivery Networks (CDNs) are often optimized in delivering assets as fast as possible. For example by delivering assets via the nearest server. Their usage is generally recommended.
  • Choose a strategy per site in whether you combine CSS / JavaScript assets or not. Say you have 10 pages and each page has different blocks, the concrete5 functionality to combine files is not going to give you the best results because the individual files will be different across all pages. In that case I'd rather combine all assets via the theme using 'providesAsset'. However if you're building a member system for example, you may want to pack certain files via the theme, and others on a per page basis.
  • Make sure your assets are cached in the browser. The browser will automatically do this, if the web server tells it to do so. For Apache servers you'd define rules in the .htaccess file, for example. Use the Network tab in DevTools to see which assets are being cached.
  • Image Optimizer optimizes images for the web without noticeable differences. It has a huge impact on how quickly pages render in a browser, especially on devices with a slow connection. Image Optimizer is a paid add-on, and I highly recommend it.
  • Prevent 404 responses. If the HTML output refers to non-existing CSS or JavaScript files, concrete5 needs to render an (uncached) 'Page not Found' page per missing asset! And that is very slow! Often it is caused because block view.php files are copied to the application folder without copying the view.css file. Just make sure all assets load correctly. PS. If you encounter this problem in a local environment, for example because images are missing, check out the 'Quick not Found' package. (it's free ^^)
  • Consider setting a max width and max height to new images in the File Manager. Images will automatically be resized, preventing a scenario that a client embeds a 16MB image in a Content block... To change the settings, search for "Image Options" in the dasboard.

Custom PHP code

  • If you load content from external sources, e.g. via an API, or with cURL, make sure the results are cached for a sensible time. If you don't, the result may have to be requested again each time you visit a page. That of course is very slow.
  • Make sure you review the block cache settings for all your custom blocks. Visit the documentation page to learn about the different cache settings.
  • Be careful with the Autonav block. It can become really slow if lots of pages are involved. To fix this you'd investigate if the Manual Nav (free) or the Nestable Manual Nav (free) add-ons are an option. If they're not, make sure the output of the Autonav block is cached. For example, it may no be if you hardcode the block in your templates.
  • Be careful with the Page List block. Try to use Full Page Caching if possible. If you want to make sure the list is always 'up-to-date', you'd use the Auto Page Cache Clearer add-on. Also be careful with pagination as it will prevent the block output from being stored and it makes Full Page Caching impossible (at the moment of writing).
  • Speed Analyzer can help you find bottlenecks in the code. It's a free add-on and I recommend it for general analysis and if you are not using any server profiling tools.
  • If blocks are hard coded in a template, their block output won't be cached. If you do want them to be cached, consider moving them to a Stack, or by wrapping them in a method that uses the Expensive cache to store the block's output for x-amount of time.

Database

  • Use the latest version of MySQL or MariaDB.
  • Flush or clean bigger tables, such as JobLogs or Logs.
  • If you have custom code or add-ons, make sure that table indices have been defined. A single index can have a significant impact on the execution time of a query.
  • Optimize Database Tables optimizes your MySQL database. It's a paid add-on and I recommend it for large websites.

Do you want to help others and do you have a suggestion for this article? Please let me know via the 'Feedback' button. Thanks!