Asset Pipeline

Summarized using AI

Rails 3.1 Whirlwind Tour

Ben Scheirman • August 11, 2011 • Earth

In this video titled "Rails 3.1 Whirlwind Tour," speaker Ben Scheirman delivers an insightful presentation on the significant updates and features introduced in Rails 3.1 during the LoneStarRuby Conference 2011. This session is aimed at helping developers take full advantage of the new functionalities offered in the framework, emphasizing hands-on coding examples throughout the talk.

Ben outlines the prominent changes, which include:
- jQuery as the default: Rails 3.1 adopts jQuery as its default JavaScript library, requiring a simple addition to the gem file.
- Reversible Migrations: Introduces a simpler way to manage migrations with a single 'change' method, automating the rollback process.
- Mountable Engines: Enables embedding Rails applications within other Rails applications, facilitating modular development and asset management.
- Identity Map: Improves ActiveRecord by caching objects in memory, reducing memory usage in long-running processes, although it requires careful use.
- Prepared Statements: Optimizes performance especially for SQL Server by caching queries which can result in faster execution times.
- hassecurepassword: Simplifies user authentication in Rails applications by integrating bcrypt for password storage and management.
- HTTP Streaming: Offers a more efficient way to render responses, allowing clients to start loading assets while the server processes the full response, reducing overall wait times.
- Asset Pipeline: Integrates Sprockets to manage assets, reducing HTTP requests and enhancing performance through minification and logical ordering.
- CoffeeScript: Available by default, this streamlined scripting language compiles into JavaScript, simplifying syntax for developers.
- SASS: Now included to manage CSS, providing variables and mixins for cleaner and more maintainable styles.

Ben provides practical coding demonstrations for several features, such as setting up HTTP streaming and utilizing the asset pipeline effectively. He also addresses common challenges developers might face, particularly emphasizing the importance of understanding asset loading order across multiple files.

In conclusion, Ben highlights that Rails 3.1 greatly enhances the developer experience by offering new tools and improved functionality, urging developers to explore these changes in their projects. This session serves as a comprehensive guide for anyone looking to leverage the capabilities of Rails 3.1 for their web applications.

Rails 3.1 Whirlwind Tour
Ben Scheirman • August 11, 2011 • Earth

Rails 3.1 introduces a lot of new changes. In this session we'll cover most of the changes, including how to take advantage of them. From Reversible Migrations, the new Asset Pipeline, Coffee Script, SASS, and even HTTP Streaming. This will be a code-heavy talk demonstrating many of the new features in Rails 3.1.

Help us caption & translate this video!

http://amara.org/v/FGdu/

LoneStarRuby Conf 2011

00:00:20.240 I'll be talking today about Rails 3.1.
00:00:26.080 My name is Ben Scheirman. I spoke here at LoneStar last year, and on the Thursday when I came into town, I started to get sick. Last year, I had just the raspiest voice and I couldn't participate in the bar conversations. By the time my talk came up, I could barely speak at all. So when I came down this time, I started to feel that scratchy throat again. Luckily, it's not as bad as last year, but this seems to be a tradition that Ben is going to feel sick around this time. So, I apologize for that.
00:00:38.160 A little bit about me: I'm the Director of Development for Chai One in Houston, Texas. We do iOS and Rails development, and we're looking for some people, so if you work with iOS, Rails, or Android, let me know. I also enjoy drinking beer and playing guitar, so I think I'm in good company here. You can find me on Twitter at 'subdigital' and on my blog at flux88.com.
00:01:21.759 All right, let's talk about Rails 3.1. If we take a look at what Rails 3 did, it brought a lot of componentization and the merging of the Merb project, making everything pluggable. Rails 3.1 is what I like to call the 'return of opinions' release. There are some pretty strong opinions in Rails 3.1, so for a dot release, it's actually quite significant.
00:01:52.399 I'm going to go over what's new, and then we're going to drill into each one of these sections. First, and probably the least controversial change, is that jQuery is now the default. We also have reversible migrations, mountable engines, the Identity Map, prepared statements, has_secure_password, HTTP streaming, the asset pipeline, CoffeeScript, and SASS.
00:02:10.479 The jQuery integration is fairly innocuous. You simply add a new line in your gem file for jQuery Rails. And if you are one of the few holdouts for Prototype, you can still uncomment that gem and add Prototype-Rails to your gem file, and everything will work just fine.
00:02:40.560 Another new feature is reversible migrations. This concept is fairly straightforward. Previously, our migrations had an 'up' method and a 'down' method. If you created a table in the 'up' method, you'd have to drop the table in the 'down' method. Now we just have a 'change' method, which simplifies the code. If you create a table, it will automatically handle the dropping of the table for you when rolling back.
00:03:16.640 Additionally, we have mountable engines. An engine is like a Rails plug-in that contains everything, including controllers, models, views, routes, initializers, and assets. It's like another Rails application that you can embed inside of your Rails application. For example, if you have an engine, you can embed it inside different applications. The important part is that it contains assets, as well as views, so you can include your own JavaScript, CSS, images, and more within those other Rails apps.
00:03:47.359 Creating an engine is quite easy. You can do this by running the command 'rails plugin new your_engine_name --mountable', and it generates an app that looks like any standard Rails application, along with a gemspec that includes an engine class. To embed it in a containing application, you would open up 'routes.rb', and specify 'mount your_engine_name: :engine', which denotes the path in your application used to access that engine. Essentially, it's just a Rack application that Rails passes requests to, allowing it to process its own routes.
00:04:20.239 Next up is the Identity Map, which is common in other ORMs. If you've ever used Hibernate, NHibernate, or similar frameworks, they all have an Identity Map, and ActiveRecord now includes one as well. When you call 'customer.find', it executes a statement against the database, placing an object in memory. If you run the exact same statement again, it caches the result, but we end up with another separate object in memory.
00:04:45.520 What the Identity Map does is return the same object in memory consistently, meaning you're always dealing with the same memory location. This can help reduce memory usage in long-running processes or when using multiple methods in controllers. However, it should be used with caution, as it can break some complex relationships in certain scenarios. Therefore, it is off by default. If you want to activate it, you can do this in 'application.rb' with 'config.enable_identity_map = true'. Alternatively, you can use it within a specific case using 'ActiveRecord::IdentityMap.use' within a block.
00:05:29.840 Next, we have prepared statements. Does anyone here use SQL Server? A couple of people? Great. So let's say we have a query like 'SELECT * FROM customers WHERE id = 128'. If we execute the same query with a different parameter, it can generate different execution plans on SQL Server due to how it is configured. Prepared statements take that query and cache it, sending a token along with the parameters, resulting in less text being sent to the database and enabling reuse of the execution plan.
00:06:01.440 This leads to substantial performance improvements on SQL Server. I heard a statistic on the internet about a 10x performance increase, but I couldn't verify that. However, it's a significant win for SQL Server. We also saw small gains for SQLite and PostgreSQL, but unfortunately, MySQL performance degraded when using prepared statements. It seems that MySQL already implemented a similar optimization, and adding the extra call to prepare the statements led to redundant calls, which is why it's disabled for MySQL adapter.
00:07:57.360 Moving on to 'has_secure_password,' what is your favorite authentication system? If you're starting a new project, which one will you use? I've had issues with many of these authentication systems at some point. There seems to be a lot of magic involved, and just when you understand how it works, an upgrade to Rails 3 breaks everything. Ryan Bates from RailsCasts suggested that it's pretty easy to roll your own authentication system, and I agree, especially now that we have 'has_secure_password' in ActiveModel.
00:08:43.680 To use 'has_secure_password', you would have a users table and add a password digest column. In your user model, you simply say 'has_secure_password', and this gives you virtual accessors for 'password' and 'password_confirmation'. When you call save on the user, it uses bcrypt to encrypt the password and store it in the password digest column. You can then authenticate the user by calling the 'authenticate' method and passing in the password. If the password is incorrect, it returns false; if it's correct, it returns the user itself.
00:09:35.519 Next, let's discuss HTTP streaming. Nearly every major web framework, except Rails, does some form of HTTP streaming, primarily for performance. Without HTTP streaming, the client makes a call to the server, which conducts a render step to render a template and sends it back to the client. At this stage, the client notices it needs to fetch some assets, fetches them, and finally renders the page. This process can lead to delays.
00:10:00.560 In contrast, with HTTP streaming, when the client calls 'get items', the server continues to render. As soon as a particular section finishes, it can send that part immediately. The client notices that some assets need to be grabbed and can start fetching them while the server completes the render process, sending the final HTML as it finishes. This reduces the overall wait time for the client, as assets can be requested and loaded earlier.
00:10:47.360 Now, let's take a look at my Rails version. I will check if everyone can read this. Do I need to make it bigger? All right. So, Rails 3.1 is currently on RC5. I expect it to be released very soon. Next, I'm going to run the command to create a new Rails application called 'streamer' and wait for it to complete the dreaded bundle install on the conference network.
00:11:50.800 As I wait, I might need some elevator music during this step. All right. Now we have a Rails 3 application set up. I plan to open it up and examine the gem file, as you cannot use HTTP streaming with the built-in WEBrick web server. Therefore, we can use Unicorn instead. I'm going to add some configuration for Unicorn in 'config/unicorn.development.rb'.
00:12:13.920 Next, I need to ensure that my bundle is installed. Once installed, I will use the Unicorn command with the configuration file, and then we can start our web server. After this, we'll check to ensure it's operating correctly. Everything seems to be working, so now I'm going to create a basic controller and action.
00:12:41.040 Inside this controller, I will render some text initially. To demonstrate, I will simulate some complex rendering using 'sleep' within the view. When I visit 'demo streaming', I notice there is a significant delay before it comes back. This delay is much more evident when using cURL to check the time taken.
00:13:19.680 To improve this, I can just add 'stream' at the top of the controller. When I execute the cURL command again, I can see that the head tag is returned immediately, allowing me to fetch the CSS, JavaScript, and then eventually receive the body content. Additionally, if I run 'cURL -i' to inspect the headers, I notice that the transfer encoding is chunked, which is a new feature of Rails.
00:14:05.680 This method is generally beneficial as it allows the client to begin fetching assets sooner. You can also perform actions like rendering the streaming using the statement 'render action: ... , stream: true' to apply the streaming behavior selectively to one action.
00:15:00.560 Overall, the objective with HTTP streaming is to flush the head tag to the client as soon as possible, allowing them to start fetching assets. However, there are a few complications, especially when using yields with named blocks for content provision like sidebars. The way Rails templates work means that content for named yields can be accumulated and rendered only after the entire template is finished. Thus, the yield tag must wait for the complete rendering process before flushing content to the client, which can negate the benefits of streaming.
00:15:55.160 An example accomplishes periodic flushing to the client by introducing a new method, 'provide'. So, if we yield a title, templates can set the title for individual pages with the 'provide' method, indicating that once done, that section is ready to be sent to the client.
00:16:41.040 This approach must account for the limitations of Rack middleware, which may break under these streaming conditions. If any middleware inspects response behavior, it might try to log timings that become unreliable, returning responses prematurely without the render being completed. Additionally, middleware that injects content may not function properly due to Rack's current design not accommodating for streaming well. It indicates that while streaming support exists, further refinements are needed.
00:18:00.000 Next, let's discuss the Asset Pipeline. A typical application consists of numerous JavaScript, CSS, and image files. When working on a project I previously developed, I found that all the JavaScript code was consolidated into a single file. The motivation behind this organization is to reduce HTTP requests, as it's recommended to minimize the number of requests made when loading a page. Another advantage of bundling is minification, leading to smaller sizes for assets. This is where Sprockets comes into play and is now included as a dependency in Rails 3.1.
00:19:09.280 Sprockets compiles all these assets, concatenating them together in a logical order and minifying the result. Consequently, the resulting file becomes what you include in your HTML page to provide all the styles and scripts. To illustrate this, we will add an action to our controller to demonstrate how the asset pipeline operates.
00:19:58.160 In this example, I’ll create two different divs styled differently. Once I visit the new pipeline action, I want to ensure that everything is functional. Looking further into the application directory, I can see that a new folder called 'assets' has been created, which houses images, JavaScript, and stylesheets. I’ll explore the existing styles and make some modifications to enhance each div’s design. Even though I am defining custom styles, Sprockets will combine these styles and supply them as a single CSS file.
00:21:16.160 When inspecting the source of this new page, the previously mentioned demo.css file is not being included, as Sprockets has intelligently aggregated it for me. This produces one request for CSS and another for JavaScript, simplifying the process. If I create additional JavaScript files within the assets folder, Sprockets takes it upon itself to bundle everything efficiently, which facilitates smoother management of my asset files.
00:21:56.480 There is another note regarding Sprockets that it depends on a server-side JavaScript environment. For Heroku deployments, this may create issues, necessitating the inclusion of the 'ruby-racer' gem. The gem version 0.8.1.3 is the latest that works with Rails 3.1.
00:22:44.160 Now, let’s shift gears to CoffeeScript. Recently, a simple commit on GitHub regarding CoffeeScript has led to an overwhelmingly long comment thread, showcasing the community's strong opinions on its inclusion in Rails. Some developers have expressed concerns or confusion, asking if they must use CoffeeScript in their projects. To clarify, you do not have to use CoffeeScript if it is not your preference. However, it is included by default now. CoffeeScript serves as a streamlined language that compiles into JavaScript, eliminating much of the superfluous punctuation you typically encounter.
00:23:44.800 The syntax of CoffeeScript lacks certain keywords like 'var' and 'function', resulting in a cleaner codebase while retaining functionality. It’s whitespace-sensitive, forming an elegant structure, meaning less clutter overall. The conversion from traditional JavaScript creates a more natural coding experience for those who are familiar with Ruby, while still respecting JavaScript's underlying mechanics.
00:24:37.760 Next up, we have SASS. You may have noticed that I previously entered CSS into a file saved as SCSS, which is a syntax compatible with CSS. In contrast, SASS introduces variables and mixins, allowing enhanced organization and management of stylesheets. For example, I might need various colors associated with certain components in my website. By creating a variable for each specific color, I can ensure consistency and easily modify values when required.
00:25:19.040 Once I define these variables, I can easily write expressive syntax that nestles components together, efficiently reducing redundancy in my code. Instead of duplicating CSS rules across various selectors, I can encapsulate the declarations within a single mixin, easing future adjustments.
00:26:07.560 In closing, SASS allows for nuanced control over styles via variables and nested rules. Yet, using variable scopes carefully becomes paramount in ensuring clarity when referencing variables across diverse style definitions. Furthermore, I find the SCSS syntax to be less confusing compared to the original SASS syntax. It remains imperative to familiarize yourself with how Sprockets orders and handles these assets and compile them correctly within Rails applications.
00:27:44.160 Are there any questions? Yes, that's a great question. If you're working with multiple files that utilize variables, you need to ensure proper loading order. By adding 'require' statements, you can explicitly register specific files to load before others to maintain variable accessibility.
00:29:27.760 Furthermore, while Rails 3 did support engines, this release enables wider integration with the Asset Pipeline. Moving forward, I hope to see improved developer experiences as we explore the enhancements offered by Rails 3.1. Thank you all for your attention today. I'm excited to see how you leverage these new features in your projects!
00:30:51.199 Thank you very much!
Explore all talks recorded at LoneStarRuby Conf 2011
+19