A Google Lighthouse audit showed several render blocking resources slowing down the page. Anything in a GL audit about 'unneeded JS/CSS' or excessive render blocking resources is a red flag.

Turns out each page was pulling in unused JS/CSS because of inheritance from the base.html template. Here's a snippet of the home route's head tag.

<head>
    <!-- ckeditor -->
    <link href="{% static 'ckeditor/ckeditor/plugins/prism/lib/prism/prism_patched.min.css' %}" rel="stylesheet">
    <script src="{% static 'ckeditor/ckeditor/plugins/prism/lib/prism/prism_patched.min.js' %}"></script>

    <!-- MathJax-->
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.4/MathJax.js?config=TeX-AMS_HTML"></script>

  <!-- Bootstrap -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
    integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
    integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"
    crossorigin="anonymous"></script>

  <!-- MailChimp-->
  <link href="//cdn-images.mailchimp.com/embedcode/classic-10_7_dtp.css" rel="stylesheet" type="text/css">

    <!-- My CSS -->
    <link rel="stylesheet" type="text/css" href="{% static 'main.css' %}" />
</head>

Many imports are not leveraged at all!! For example, the ckeditor and MathJax CSS/JS only kick in when viewing individual posts or creating new ones.

One solution is to only use these libraries on pages that need them. In Django, you accomplish this by including a template block within the head tag. By using these blocks on pages inheriting the base template, you add resources to the <head> on a page-by-page basis.

I also made the Mailchimp CSS script async because it is only used by the newsletter component. I am OKAY with taking longer to become interactive.

The <head> in the base.html shrunk and the home route load time dropped by a second!

<head>
  {% block head %}

  {% endblock %}

  <!-- Bootstrap -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
    integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
  <script async src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
    integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"
    crossorigin="anonymous"></script>

  <!-- MailChimp-->
  <link href="//cdn-images.mailchimp.com/embedcode/classic-10_7_dtp.css" rel="stylesheet" type="text/css" media="print"
    onload="this.media='all'">

  <!-- My CSS -->
  <link rel="stylesheet" type="text/css" href="{% static 'main.css' %}" />
</head>

On line 9, I add an async tag to the bootstrap JS. This increases time to be interactive, but I haven't noticed an impact other than FCP dropping (that's a good thing). For CSS, I used this hacky approach on SO which involves adding two attributes to the script tag to remove it from being a render blocking resource. See line 14 and 15.

For the post detail route where the user is seeing a full post, I use the {% block head %} to pull in the needed ckeditor and MathJax libraries.

{% block head %}
    <!-- MathJax-->
    <script type="text/javascript" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.4/MathJax.js?config=TeX-AMS_HTML"></script>

    <!-- ckeditor -->
    <link href="{% static 'ckeditor/ckeditor/plugins/prism/lib/prism/prism_patched.min.css' %}" rel="stylesheet">
    <script src="{% static 'ckeditor/ckeditor/plugins/prism/lib/prism/prism_patched.min.js' %}"></script>
{% endblock %}

This way, the resources for the page becomes all the CSS/JS from the base.html plus whatever is placed inside the block.

Most websites can receive a performance boost by being smart about when and where JS/CSS loads. Check your site, today!