Parik Tiwari
Parik Tiwari

Reputation: 1525

Performance Engineering on Apostrophe CMS

So after three weeks of 12hr shifts I am almost done with building a Knowledge Base system using Apostrophe. Now comes the task of speeding things on the front end. My questions are:

  1. How do I add expires headers: Express has inbuilt milddleware called static, can I just implement it normally under the index.js file?
  2. Minify JavaScript & CSS: http://apostrophecms.org/docs/modules/apostrophe-assets/ I saw that apostrophe has something inbuilt but its not clear how to enable it? And also do I need to put the assets in specific folder for it to work? Right now I have all the JS files under lib/modules/apostrophe-pages/public/js and CSS under public/css.
  3. Enable GZIP on the server: there is nothing mentioned but again express does have gzip modules can I just implement them under lib/modules/apostrophe-express/index.js?

Any help will is greatly appreciated.

Upvotes: 0

Views: 410

Answers (1)

Tom Boutell
Tom Boutell

Reputation: 7572

I'm the lead developer of Apostrophe at P'unk Avenue.

Sounds like you found our deployment HOWTO with the recently added material about minification, and so you have sorted out that part yourself. That's good.

As for expires headers and gzip on the server, while you could do that directly in node, we wouldn't! In general, we never have node talk directly to the end user. Instead, we use nginx as a reverse proxy, which gives us load balancing and allows us to deliver static files directly. nginx, being written in C/C++, is faster at that. Also the implementations of gzip and TLS are very much battle-tested. No need to make javascript do what it's not best at.

We usually configure nginx using mechanic, which we created to manage nginx with a few commands rather than writing configuration files by hand. Our standard recipe for that includes both gzip and expires headers.

However, here's an annotated version of the nginx configuration file it creates. You'll see that it covers load balancing, gzip and longer expiration times for static files.

# load balance across 4 instances of apostrophe listening on different ports
upstream upstream-example {
  server localhost:3000;
  server localhost:3001;
  server localhost:3002;
  server localhost:3003;
}

server {
  # gzip transfer encoding
  gzip on;
  gzip_types text/css text/javascript image/svg+xml
    application/vnd.ms-fontobject application/x-font-ttf
    application/x-javascript application/javascript;

  listen *:80;

  server_name www.example.com example.com;

  client_max_body_size 32M;

  access_log /var/log/nginx/example.access.log;
  error_log /var/log/nginx/example.error.log;

   # reverse proxy: pass requests to nodejs backends        
  location @proxy-example-80 {
    proxy_pass http://upstream-example;

    proxy_next_upstream error timeout invalid_header http_500 http_502
  http_503 http_504;
    proxy_redirect off;
    proxy_buffering off;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }

  # Deliver static files directly if they exist matching the URL,
  # if not proxy to node
  location / {
    root /opt/stagecoach/apps/example/current/public/;
    try_files $uri @proxy-example-80;
    # Expires header: 7-day lifetime for static files
    expires 7d;
  }
}

Upvotes: 2

Related Questions