blocknotes / rails_full_page_cache

Sample project to use full page caching on Rails

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Full Page Cache on Rails

A sample project to use full page caching on Rails (using actionpack-page_caching).

Main points:

  • app/controllers/application_controller.rb: /update (js) route to send CSRF token, flash messages and optionally DOM elements to modify
  • app/controllers/posts_controller.rb: caches_page actions, json only responses for create, update and destroy
  • app/models/application_record.rb: update cache methods
  • app/models/post.rb: cache callbacks, cache dependecies
  • app/views/layouts/application.html.erb: on DOM ready an update AJAX call is made, data-remote AJAX callbacks (for forms)
  • app/views/posts/_form.html.erb: form with remote option
  • config/environments/development.rb: caching enabled, js compression, don't serve static files
  • config/initializers/actionpack-page_caching.rb: cache directory, caching compression
  • lib/tasks/cache.rake: cache routes, cache tasks: generate_all, generate

Extra notes:

  • In the branch experiments I'm trying to improve some points, for example: removing the update AJAX call on DOM ready, calling it only before a form submit
  • In the update route the CSRF token is available to anyone, this could be a security risk (in this sample project it's used only for testing); an alternative could be to disable CSRF protection for cached routes using a good reCAPTCHA instead, another option is to disable caching for routes with forms

Project setup

rails g model Author name:string age:integer email:string
rails g model Post title:string description:text author:belongs_to category:string dt:datetime position:float published:boolean
rails g model Detail description:text author:belongs_to
rails g model Tag name:string
rails g model PostTag post:belongs_to tag:belongs_to

Serve static assets

rails assets:clean assets:precompile
rails cache:generate_all
rails server -b 0.0.0.0

nginx sample conf

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    gzip  on;
    gzip_min_length 1024;
    gzip_types application/json application/javascript application/x-javascript application/xml application/xml+rss text/plain text/css text/xml text/javascript;

    server {
        server_name  localhost;

        listen       8080;
        # listen       80;
        # listen       443 ssl http2;

        # ssl_certificate /usr/local/etc/nginx/ssl/server.pem;
        # ssl_certificate_key /usr/local/etc/nginx/ssl/server.key;

        large_client_header_buffers 4 16k;

        rewrite ^/(.*)/$ /$1 permanent;

        location / {
            error_page 418 = @app;
            recursive_error_pages on;

            if ($request_method != GET) {
                return 418;
                # proxy_pass http://0.0.0.0:3000;
            }

            root /projects/rails_full_page_cache/public;
            index index.html index.htm;
            gzip_static on;

            # try_files /out/$uri/index.html /out/$uri.html /out/$uri/ /out/$uri $uri $uri/ @app;
            try_files /cache/$uri.html $uri @app;

            # try_files /out/$uri/index.html /out/$uri /out/$uri/ $uri $uri/ @app;
        }

        location @app {
            proxy_pass http://0.0.0.0:3000;
            proxy_set_header  Host $host;
            proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header  X-Forwarded-Proto $scheme;
            proxy_set_header  X-Forwarded-Ssl on; # Optional
            proxy_set_header  X-Forwarded-Port $server_port;
            proxy_set_header  X-Forwarded-Host $host;
        }

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }

    include servers/*;
}

About

Sample project to use full page caching on Rails


Languages

Language:Ruby 72.4%Language:HTML 21.0%Language:CSS 4.5%Language:JavaScript 2.1%