How to Optimize Card Assets in a Ghost Theme

After thoroughly reviewing Ghost, I was able to remove 5.4 kB for the cards I used. That's a reduction of 77.14% of the original files. Want to know how I did this? 😉

3 min read
How to Optimize Card Assets in a Ghost Theme
Photo by Tima Miroshnichenko on Pexels.

If you're a creator using Ghost CMS (or a Ghost theme developer), you might want your website to be fast to provide a great experience for your users. There are many ways to optimize the performance of a Ghost website. Today, I want to talk about one way that seems to be under looked according to this search: by optimizing card assets.

One thing I absolutely love about Ghost is that they offer so many tools to enhance your post content: buttons, bookmarks, galleries, headers, products, audio, video, and more.

But, if you don't use these features, chances are your website is unnecessarily loading JavaScript and/or CSS related to them. How can you quickly check if this is your case?

Open your theme's package.json file and check if you have the card_assets property in it.

{ 
  "config": {
    "card_assets": true
  }
}
Excerpt of a default theme's package.json file. 

If you can't find this setting inside your theme's package.json file, the default value for this property has been true since Ghost 5.0.

So, what does this imply? These settings tell Ghost to automatically provide and merge many default CSS and JavaScript assets into a cards.min.css and a cards.min.js files.

Take a look at these files here (5.0 kB) and here (2.0 kB) for the demo.ghost.io website. There's a lot of code, isn't it? 😲

But, did you know that you can exclude the features you don't use? I did, and my cards.min.css file is down to 1.6 kB, a reduction of 3.4 kB (68%)! And my cards.min.js file has been completely deleted!

It turns out there's an exclude option you can use to remove the default card implementations in Ghost.

{ 
  "config": {
    "card_assets": {
      "exclude": [
        "audio",
        "blockquote",
        "bookmark",
        "button",
        "gallery",
        "nft",
        "product",
        "toggle",
        "video"
      ]
    }
  }
}
My current exclude option, where it removes the default implementation of many features.
🧐
If you add a card name to the exclude list, it doesn't mean you can't use this feature anymore! It only means that your local theme is now 100% responsible for implementing the necessary code.

For example, I still have quotes, galleries and buttons in some of my posts, don't worry! 😅

You can also disable all cards assets by setting card_assets to false.

{ 
  "config": {
    "card_assets": false
  }
}
If your theme has already implemented all cards, you can use these settings instead.

A simple configuration could immediately reduce your website's response time. Isn't that awesome? 🤗

FAQ

What files are automatically included in the cards.min.css and cards.min.js files?

If you look at this CSS directory and this JavaScript directory, you'll find all the files that are merged and minified by Ghost. A theme developer will probably want to exclude some of these features if they have already implemented them.

As of July 31st, 2022, the included files were:

Name CSS file JavaScript file
audio audio.css audio.js
blockquote blockquote.css
bookmark bookmark.css
button button.css
callout callout.css
file file.css
gallery gallery.css gallery.js
header header.css
nft nft.css
product product.css
toggle toggle.css toggle.js
video video.css video.js

What would a configuration that disables all default implementations look like?

If you listed all the previous card names, it would look something like below:

{ 
  "config": {
    "card_assets": {
      "exclude": [
        "audio",
        "blockquote",
        "bookmark",
        "button",
        "callout",
        "file",
        "gallery",
        "header",
        "nft",
        "product",
        "toggle",
        "video"
      ]
    }
  }
}
An exclude option that removes the default implementation of many features.

Can I use an allowlist (include) instead of a disallow list (exclude)?

According to the current CardAssetService implementation, you can, but I haven't been able to get it to work yet. Let me know if you succeed! 😋

// CASE: the theme has declared an include directive, we should include exactly these assets
// Include rules take precedence over exclude rules.
if (_.has(this.config, 'include')) {
  return {
    'cards.min.css': `css/(${this.config.include.join('|')}).css`,
    'cards.min.js': `js/(${this.config.include.join('|')}).js`
  };
}
Excerpt of the CardAssetService file.