Getting the best performance out of your CS-Cart theme

A ThemeHills guide for CS-Cart store owners.

Your theme is only half of what a visitor experiences. The other half is how the store and the server are set up, and that half is usually left at its defaults. Everything below is something we applied to our own demo server, which runs a large number of CS-Cart installations on modest hardware, and measured before and after.

Part 1 you can do yourself in the admin panel. Part 2 needs access to the server, so it is a task for your hosting provider or system administrator. Part 3 is how to check that any of it worked.


Part 1. In your store admin

1.1 Convert images to WebP

Settings → Thumbnails → Thumbnail format: WEBP.

WebP images weigh considerably less than JPEG or PNG at the same visual quality, and this one setting applies that saving to every thumbnail in the store at once.

The first page load after switching will be slow, because every thumbnail is regenerated on the fly. After that everything is fast again.

Check the thumbnail background colour before you switch. There is a background colour field in the same settings screen. If it is filled in, every transparent image gets that colour baked in when its thumbnail is generated, and banners with transparent backgrounds turn into solid rectangles. For transparency the field must be empty.

This is easy to miss because the damage only appears after you enable conversion: until then those images are served as originals and never pass through the thumbnail generator. We ran into exactly this on our own demo.

1.2 Remember that banners are not thumbnails

The conversion setting applies to thumbnails only. Banners, the logo, and any other image shown at its original size never pass through the thumbnail generator, so the setting does not touch them.

Either upload those images already converted, or ask your administrator to set up server-side conversion (Part 2). On our own demo the banners turned out to save more than the thumbnail setting did, simply because they are the largest images on the page. It is worth doing both.

Never rename image files in the database to change their format. It is a tempting shortcut: convert the files, write the new paths in. But then the image format becomes part of your data, and any later settings change collides with it. With conversion enabled, the store will take your already-converted file as a source and compress it a second time, losing quality and producing names like image.png.webp.webp.

Keep the original paths in the database and decide the format at delivery time, either with the store setting or on the web server. Then nothing breaks and everything is reversible.

1.3 Upload source images at a sensible size

A 4000-pixel-wide photograph behind a 300-pixel product tile is wasted traffic on every card, and a category page is full of cards. Resize before uploading.

1.4 Give the first banner loading priority

If your home page opens with a banner slider, that first slide is almost always the largest element on screen, and page-speed tools measure exactly how fast it appears.

Our themes can tell the browser to fetch that slide before everything else. In the banner block settings, enable “Load the first slide with high priority”.

Switch it on where the slider is the first thing a visitor sees, usually the home page, and leave it off elsewhere: marking several images as top priority is the same as marking none.

1.5 Retina images: a real trade-off

CS-Cart ships an add-on called HiDPI that serves double-resolution images to high-density screens. It makes the store look sharper on modern phones and laptops, and it costs traffic.

For an ordinary screen nothing changes. For a retina visitor every product tile is swapped for one of double the width and height, which is four times the pixel area, and the image weight of the page grows accordingly. On a photo-heavy page that is a substantial difference.

There is no universally right answer here, but there is a fact worth knowing: mobile page-speed tests simulate a high-density screen, so they download the double-size images. If your mobile score drops after enabling this add-on, that is why.

Our advice: switch it on if your products are visual and photography is the selling point; leave it off if you sell on price and speed. Measure both ways before deciding.

1.6 Keep one main heading per page

Every page should have exactly one first-level heading. In CS-Cart that is decided by the block wrapper, which you choose in Design → Layouts in the block’s settings: one wrapper renders the block title as the page’s main heading, the others render ordinary subheadings.

The main-heading wrapper belongs to the one central block of the page. If you assign it to a second block as well, the page ends up with two competing main headings, which search engines and accessibility audits both flag. If a block on your home page is showing its title too prominently, change its wrapper rather than editing the theme.

1.7 Do not paste rendered HTML into HTML blocks

Copying the finished markup of a category list or a product grid out of the page and pasting it into an HTML block looks like a quick win, and it freezes your store. The pasted copy carries hard-coded addresses, image paths and image sizes; it will not follow your catalogue when you rename a category or replace a photo, and after a move to another domain its links point nowhere. Use the block that generates the list instead.

1.8 After moving to HTTPS, check your content, not your code

If any element on an HTTPS page is still loaded over HTTP, the browser marks the page as not fully secure and audits deduct points.

The important part: those addresses are almost never in the theme’s code. They sit in content that you or a previous developer entered: banner and menu content, HTML blocks, footer links, add-on settings.

The quickest way to find them is the browser itself. Open the page, press F12, and look at the Console tab: the browser lists every insecure resource by its full address, which tells you exactly which block to edit.

One caution: replace http:// with https:// only for addresses you have checked. Your own domain is safe. Third-party sites are not always: some still do not support HTTPS, and a blanket replacement turns working links into broken ones.

1.9 Install only the languages you actually need

Each language multiplies the translated records in your database and the work of keeping content consistent. Adding a language takes a minute; keeping every banner, menu item and category coherent in all of them does not.

1.10 Turn off add-ons you do not use

Every enabled add-on adds queries, template hooks, styles and scripts to every page. This is the cheapest optimisation there is, and the most often skipped.


Part 2. On the server

This part needs hosting access. Send it to your administrator or your hosting provider.

2.1 Keep the cache in memory instead of files

By default CS-Cart writes its cache to files. Over time that directory grows enormously, and the first page load after a quiet period starts taking a very long time. Stores with filters suffer fastest: every combination of parameters in a URL creates its own entry.

Move the cache to Redis. It lives in memory and evicts old entries by itself, so it cannot grow without limit. In config.local.php:

$config['cache_backend'] = 'redis';
$config['store_prefix']  = 'your_store';

If several CS-Cart installations share one server, store_prefix is mandatory and must be unique for each. Without it they share the same cache keys and start returning errors. We learned this the hard way: most of our installations went down at once.

Sessions and locks can stay in the database.

Cap Redis memory and enable eviction, otherwise it can consume all the RAM:

maxmemory 512mb
maxmemory-policy allkeys-lru

Our result: the long cold start disappeared completely.

2.2 Enable response compression

Check whether gzip is on. Its absence is the most common and most frustrating thing we find: the page travels to the visitor uncompressed.

For nginx:

gzip on;
gzip_comp_level 5;
gzip_vary on;
gzip_proxied any;
gzip_types text/plain text/css application/json application/javascript
           text/xml application/xml image/svg+xml;

Do not add images and fonts to the list, they are compressed already.

Our result: the home page became dramatically lighter. On a mobile connection that is the difference between “it opened” and “it is still spinning”.

2.3 Enable HTTP/2

If the store runs over HTTPS, enable HTTP/2 so the browser can fetch dozens of theme files in parallel over one connection. For nginx that is http2 on; in the site block.

To verify: curl -sI --http2 https://your-store/ | head -1 should answer HTTP/2 200.

2.4 Serve WebP for images that bypass the thumbnail generator

The store setting in Part 1 covers thumbnails. Banners and other full-size images can be handled on the web server: place a .webp copy next to each original and serve it when the browser says it accepts WebP, falling back to the original otherwise.

Originals stay untouched, nothing in the database changes, and the whole thing is undone by deleting the copies. On one of our demo stores, where no store settings had been changed at all, this alone cut the image weight of the home page by more than half.

Remember Vary: Accept in the response, so that caches do not serve a WebP file to a browser that cannot display it.

2.5 Give static files a cache lifetime

Static files need a Cache-Control header, otherwise the browser revalidates every file on every visit. Reasonable lifetimes: images and fonts 30 days; CSS and JS with a hash in the filename a year or more; HTML not cached.

2.6 Tune PHP

OPcache keeps compiled PHP in memory instead of re-reading it from disk. Sensible starting values for a store:

opcache.memory_consumption=256
opcache.max_accelerated_files=50000
opcache.interned_strings_buffer=16

max_accelerated_files matters more than it looks: CS-Cart with add-ons easily runs to many thousands of files, and when slots run short the cache starts evicting itself in circles.

After configuring, check that the cache is not full and the hit rate is close to 100 percent.

Restarting PHP empties this cache, and the site will be noticeably slower for the first few minutes. Do it at a quiet hour and warm the store immediately afterwards by opening the home page and a couple of categories.

Worker processes. More is not better. Scale them with the number of processor cores, not with optimism: about four processes per core is a sound starting point. On a two-core machine that means around 8, and 30 will be slower, not faster, because under load template and stylesheet compilation compete for CPU and everyone slows down at once. Also set an execution time limit of about 45 seconds so a stuck request cannot hold a process forever.

Scheduled tasks. If background jobs are triggered by visitors, one unlucky customer waits for somebody else’s heavy task. Move them to the system scheduler and disable the web trigger. The load spikes during busy periods disappear as a side effect.

2.7 Check two database settings

CS-Cart rarely hits a database limit, but two settings are worth a look:

  • The InnoDB buffer pool should hold the whole database if memory allows, so reads come from memory rather than disk.
  • Temporary table size. At the default value, sorting and grouping start spilling to disk. On our server a large share of temporary tables was going to disk before we raised this.

How to tell the database is not the problem: look at the buffer pool hit rate. If it is around 99.9 percent, the bottleneck is elsewhere and you should be tuning PHP and the cache instead.

2.8 Micro-caching for high-traffic stores

If you get a lot of anonymous visitors, caching the finished HTML for 30 to 60 seconds on the web server helps a great deal: during a rush PHP builds the page once and everyone else gets the ready-made copy.

The conditions that make this safe, all of them:

  • Cache only requests with no cookies. The moment any cookie appears (session, cart, currency, language) serve a live page.
  • Never cache the cart, checkout, account pages, login or the admin panel.
  • Only GET requests, only successful responses.
  • If the store is multilingual, include the language in the cache key. CS-Cart can serve different languages at the same address based on the browser’s language header. Without this, a visitor can be served somebody else’s language out of the cache. We caught exactly this in testing.

Part 3. Measuring the result

Measure before and after, otherwise you will not know what helped.

  • Page weight and request count are the most honest numbers.
  • PageSpeed Insights, in mobile mode. It simulates a slow connection and a weak phone, and that is where real problems show. The desktop score is almost always flattering.
  • Server response time for the home page and a product page.

Three traps when checking

  1. Page cache. If micro-caching is on, an ordinary check may show you a stale copy. Send any cookie with the request; such requests bypass the cache.
  2. Template cache. After editing templates, changes are not always picked up. Clear the store cache. On a server with several installations, do it one at a time and warm each one before moving on: clearing them all at once causes a load spike and visitors see errors.
  3. Retina. Ordinary command-line checks report the weight for a standard screen. If the retina add-on is on, real visitors on modern devices download considerably more. Measure with a high-density screen in mind, or trust the mobile page-speed score, which already does.

What we do not recommend

  • Chasing the SEO score on a test store. If the store is closed to search engines, the score will be low no matter how good the theme is.
  • Installing every “accelerator” add-on you can find. Two caching layers that do not know about each other interfere more often than they help.
  • Buying a bigger server before you understand the problem. More than once we have seen slowness that turned out to be configuration, not hardware: an overgrown cache in one case, missing compression in another. A more powerful machine would have cost more and fixed neither.