Skip to content

Commit

Permalink
Merge pull request #11 from Aranda-Cyber-Solutions-LLC/master
Browse files Browse the repository at this point in the history
Add methods to allow generation of critical CSS for a specific route …
  • Loading branch information
michael-misshore authored Jan 18, 2017
2 parents 73a18a3 + 7a301e5 commit 1879c02
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 8 deletions.
50 changes: 46 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@ This gem assumes that you'll load the rest of the CSS asyncronously. At the mome

This gem uses [PhantomJS](https://github.com/colszowka/phantomjs-gem) and [Penthouse](https://github.com/pocketjoso/penthouse) to generate the critical CSS.

## Update

Version 0.3.0 is not compatible with previous versions. Please read the Upgrading from Previous Versions section below for more information.

## Installation

Add `critical-path-css-rails` to your Gemfile:

```
gem 'critical-path-css-rails', '~> 0.2.0'
gem 'critical-path-css-rails', '~> 0.3.0'
```

Download and install by running:
Expand Down Expand Up @@ -61,15 +64,15 @@ To load the generated critical CSS into your layout, in the head tag, insert:

```HTML+ERB
<style>
<%= CriticalPathCss.fetch(request.path) %>
<%= CriticalPathCss.fetch(request.path) %>
</style>
```

A simple example using loadcss-rails looks like:
A simple example using [loadcss-rails](https://github.com/michael-misshore/loadcss-rails) looks like:

```HTML+ERB
<style>
<%= CriticalPathCss.fetch(request.path) %>
<%= CriticalPathCss.fetch(request.path) %>
</style>
<script>
loadCSS("<%= stylesheet_path('application') %>");
Expand All @@ -80,6 +83,45 @@ A simple example using loadcss-rails looks like:
</noscript>
```

### Route-level Control of CSS Generation and Removal

CriticalPathCss exposes some methods to give the user more control over the generation of Critical CSS and managment of the CSS cache:

``` ruby
CriticalPathCss.generate route # Generates the critical path CSS for the given route (relative path)

CriticalPathCss.generate_all # Generates critical CSS for all routes in critical_path_css.yml

CriticalPathCss.clear route # Removes the CSS for the given route from the cache

CriticalPathCss.clear_matched routes # Removes the CSS for the matched routes from the cache
```

NOTE: The `clear_matched` method will not work with Memcached due to the latter's incompatibility with Rails' `delete_matched` method. We recommend using an alternative cache such as [Redis](https://github.com/redis-store/redis-rails).

In addition to the `critical_path_css:generate` rake task described above, you also have access to task which clears the CSS cache:

```
rake critical_path_css:clear_all
```
NOTE: The `critical_path_css:clear_all` rake task may need to be customized to suit your particular cache implementation.

Careful use of these methods allows the developer to generate critical path CSS dynamically within the app. The user should strongly consider using a [background job](http://edgeguides.rubyonrails.org/active_job_basics.html) when generating CSS in order to avoid tying up a rails thread. The `generate` method will send a GET request to your server which could cause infinite recursion if the developer is not careful.

A user can use these methods to [dynamically generate critical path CSS](https://gist.github.com/taranda/1597e97ccf24c978b59aef9249666c77) without using the `rake critical_path_css:generate` rake task and without hardcoding the application's routes into `config/critical_path_css.yml`. See [this Gist](https://gist.github.com/taranda/1597e97ccf24c978b59aef9249666c77) for an example of such an implementation.

## Upgrading from Previous Versions

The latest version of Critcal Path CSS Rails changes the functionality of the `generate` method. In past versions,
`generate` would produce CSS for all of the routes listed in `config/critical_path_css.yml`. This functionality has been replaced by the `generate_all` method, and `generate` will only produce CSS for one route.

Developers upgrading from versions prior to 0.3.0 will need to replace `CriticalPathCss:generate` with `CriticalPathCss:generate_all` throughout their codebase. One file that will need updating is `lib/tasks/critical_path_css.rake`. Users can upgrade this file automatically by running:

``` prompt
rails generate critical_path_css:install
```

Answer 'Y' when prompted to overwrite `critical_path_css.rake`. However, overwriting `critical_path_css.yml` is not necessary and not recommended.

## Versions

Expand Down
15 changes: 14 additions & 1 deletion lib/critical-path-css-rails.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,25 @@ module CriticalPathCss

CACHE_NAMESPACE = 'critical-path-css'

def self.generate
def self.generate(route)
Rails.cache.write(route, CssFetcher.new.fetch_route(route),
namespace: CACHE_NAMESPACE, expires_in: nil)
end

def self.generate_all
CssFetcher.new.fetch.each do |route, css|
Rails.cache.write(route, css, namespace: CACHE_NAMESPACE, expires_in: nil)
end
end

def self.clear(route)
Rails.cache.delete(route, namespace: CACHE_NAMESPACE)
end

def self.clear_matched(routes)
Rails.cache.delete_matched(routes,namespace: CACHE_NAMESPACE)
end

def self.fetch(route)
Rails.cache.read(route, namespace: CACHE_NAMESPACE) || ''
end
Expand Down
6 changes: 5 additions & 1 deletion lib/critical_path_css/css_fetcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ def fetch
@config.routes.map { |route| [route, css_for_route(route)] }.to_h
end

private
def fetch_route(route)
css_for_route route
end

protected

def css_for_route(route)
Phantomjs.run(PENTHOUSE_PATH, @config.base_url + route, @config.css_path)
Expand Down
2 changes: 1 addition & 1 deletion lib/critical_path_css/rails/version.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module CriticalPathCSS
module Rails
VERSION = '0.2.4'
VERSION = '0.3.0'
PENTHOUSE_VERSION = '0.3.4'
end
end
9 changes: 8 additions & 1 deletion lib/tasks/critical_path_css.rake
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@ require 'critical-path-css-rails'
namespace :critical_path_css do
desc 'Generate critical CSS for the routes defined'
task generate: :environment do
CriticalPathCss.generate
CriticalPathCss.generate_all
end
desc 'Clear all critical CSS from the cache'
task clear_all: :environment do
# Use the following for Redis cache implmentations
CriticalPathCss.clear_matched('*')
# Some other cache implementations may require the following syntax instead
# CriticalPathCss.clear_matched(/.*/)
end
end

Expand Down

0 comments on commit 1879c02

Please sign in to comment.