By Dhruvita Shah,
Last Modified: December 31, 2024
Propshaft in Rails 8: A lightweight asset pipeline with digest based caching

With Rails 8, Propshaft is the default asset pipeline for new applications. To start a new Rails 7 application with propshaft use this command – rails new myapp -a propshaft

There are other libraries for Asset Pipeline in applications with Rails 7.x versions,

  • Sprockets
  • Webpacker
  • Importmap-Rails

Let’s understand the basics of Asset Pipeline before we move to Why Propshaft

Introduction to Asset Pipeline:

The asset pipeline is a framework to manage, process, and serve static assets like JavaScript, CSS, and images. It organize, optimize, and deliver these assets efficiently in both development and production environments.

Click here to learn more about Asset Pipeline.

Following are the benefits of Asset Pipelining

  1. Transpilingbuttons.scss => buttons.css
    • Ability to code assets via a higher-level language (quicker to process by machine).
    • Allows using languages like Sass for CSS, CoffeeScript for JS, and ERB for both by default.
  2. Bundling – (buttons.css, alerts.css) => application.css
    • Concatenation of assets
    • Combines all CSS in a single file and JS in a single file to load the page faster.
  3. Fingerprinting (application.css => application-SHA.css)
    • Cache Busting: If you update the file (e.g., modify application.css), its contents change, resulting in a new hash. Browsers see the new filename and download the updated asset.
    • Efficient Caching: Assets with the same content maintain the same hash, allowing long-term caching for unchanged assets.
  4. Compression (application-SHA.css => application-SHA.css.gz)
    • It makes our asset files smaller. For CSS, whitespace and comments are removed.
    • Then, it applies gzipping to compress the file before sending it to the client.
    • With the above two steps it could make 100 KB file => 14 KB

Why Propshaft ?

  1. ES6 is standard on all browsers. So, we don’t need a Transpiling step to turn ES6 into something that’ll run in the browser. It will just work fine 🚀
  2. HTTP2 removes the limitation of HTTP1. That allows a single connection to make up to 100 requests at a time so instead of a single request, bundling are no longer necessary.
  3. Compression is now provided by CDNs as default service, so compression is no longer needed as additional process.

How Propshaft works ? 

When your application boots, Propshaft will configure itself and assign to this variable, an instance of its most important class – Propshaft::Assembly

1. load_path – contains the paths to all assets. Propshaft automatically knows where all your files are and add it to the assets.

				
					def load_path
  @load_path ||= Propshaft::LoadPath.new(config.paths, compilers: compilers, version: config.version)
end
				
			

2. resolver – It will find the file, you want.

				
					def resolver
  @resolver ||= if config.manifest_path.exist?
    Propshaft::Resolver::Static.new manifest_path: config.manifest_path, prefix: config.prefix
  else
    Propshaft::Resolver:: Dynamic.new load_path: Road_path, prefix: config.prefix
  end
end
				
			

3. server – It will serve those files. (for development environment)

				
					def server
  Propshaft::Server.new(self)
end
				
			

4. processor – handles cleaning and pre-compiling tasks

				
					def processor
  Propshaft::Processor.new \
    load_path: load_path, output_path: config.output_path, compilers: compilers, manifest_path: config.manifest_path
end
				
			

5. compilers – read CSS and JavaScript files and update references to assets with their digested names

				
					def compilers
  @compilers ||=
    Propshaft::Compilers.new(self).tap do |compilers|
      Array(config.compilers).each do |(mime_type, klass)|
        compilers.register mime_type, klass
      end    
    end
end
				
			

Lifecycle of An Asset in Propshaft

  1. The “view” asks ‘stylesheet_link_tag’ for the application asset, which in turn asks ‘compute_assest_path’ for it which reaches for the ‘Assembly’.
  2. Assembly asks it for the resolver which is dynamic since we’re in development environment. In production environment, we will have static resolver.
  3. For development, resolver will go to Loadpath and ask it for the asset name in the application and with that asset in hand, we have the digested path.
  4. For Production, resolver uses the manifest file generated by Propshaft and from there it will get the digested path.
 
File Naming Convention in Digest Based Caching on Rails 8 with Propshaft
Output: Digested Filename

Main Components of Propshaft

  1. Simplified Architecture
    • Propshaft focuses on simplicity, avoiding the complex dependency trees and features of Sprockets.
    • It relies on plain directories to organize assets without requiring manifest files or directives.
  2. Digested Assets (Fingerprinting)
    • Propshaft appends a content-based fingerprint (digest) to asset filenames, ensuring cache busting when assets change like this  – application.css becomes application-123abc.css.
    • This ensures browsers always fetch the latest version of updated assets.
  3. Logical Path Referencing
    • Assets are referenced using their logical paths (e.g., logo.png), and Propshaft automatically resolves them to the correct digested file like /assets/logo-<digest>.png
  4. Compatibility with CDN Hosting
    • Propshaft is designed to work seamlessly with Content Delivery Networks (CDNs).
    • It serves digested assets, making them ideal for long-term caching on CDNs.
  5. CSS and JavaScript Path Rewriting
    • Automatically rewrites paths to referenced assets (e.g., images, fonts) within CSS files to their digested equivalents.
    • This ensures references in stylesheets always point to the correct, cache-busted versions of assets.
  6. No Asset Preprocessing
    • Propshaft doesn’t handle preprocessing of assets like Sprockets. Instead, it assumes assets are already compiled and ready to serve.
    • Use external tools like esbuild, Webpack, or Tailwind CLI to preprocess assets (e.g., minification or transpilation).
  7. Multiple Asset Paths
    • Supports multiple asset load paths, allowing assets to be organized in various directories.
    • Example: You can separate vendor assets and custom application assets.
  8. Efficient Precompilation
    • Precompiles assets into a simple directory structure with hashed filenames, making deployment faster and more predictable.

Key Differences from Sprockets

  1. No Preprocessing: Propshaft does not handle preprocessing (e.g., SCSS to CSS); you must use external tools like esbuild or dart-sass.
  2. Focused on Delivery: Propshaft’s sole job is to efficiently serve assets, keeping the pipeline simple and fast.
  3. Modular Design: Unlike Sprockets, Propshaft is minimal and leaves flexibility for integrating modern asset management tools.

Discover the power of Ruby on Rails

for your projects!

Share On: