Skip to main content

Mobomo webinars-now on demand! | learn more.

Velocity Conf knocked my socks off. This was my first O’Reilly conference and I can really see what the hub-bub is all about. Velocity was host to many top industry pioneers like the dudes from Etsy who created StatsD, Mitchell Hashimoto who works on Vagrant, and reps from Opera, Mozilla, and Google, among other big names.

The conference was split into a venn-diagram of operations, development, and devops, so it was easy to experience talks that were on the fringes of most attendees’ skillsets. Being mostly into development and UX, the web performance track was my home turf. However, I did learn some operations stuff that helps me level up beyond just being able to scale up my meager home NAS server. Many of the pure operations talks had to do with visualization of systems; it was nice to hear the discussion involve many HCI principles that we use on the Intridea UX team on a day to day basis.

There was so much material on the web performance side of things that I could go on for days about it, but I’ll just share a few of my favorite tips from Velocity for this debriefing. I often see front-end developers and engineers struggle with exactly how to measure and address web performance issues, and many of the Velocity presenters covered ways to effectively optimize page load; and yes, image compression was one of those things mentioned.

DOMinate the Document Object Model

Ok, so let’s think about DOM render, it happens serially right? That means that we have to make sure we don’t structure our markup in a way that would severely block the “thread” when loading. Modern browsers have implemented work-arounds like "speculative loading” to download resources while still parsing the rest of the DOM. This is all well and good, but speculative loading will still fail if we have any inline script tags that use document.write() to append markup to the document. This would be a sure-fire way to block the DOM. Not all document.write() is entirely evil, but one should definitely be wary of it.

Something cool that Chrome for Android is doing is spinning up multiple processes when loading a document so it’s likely that true concurrent DOM render is probably coming in the near future. The faster a user sees browser paint (elements on the screen), the faster they will believe the page is loading. You never want to give them the “white screen of death”.

Optimization for Mobile

With responsive design all the rage (and with good reason), there are special considerations to make to optimize for multiple devices. Jason Grigsby drilled down into this at Velocity in his talk “Performance Implications of Responsive Design”. We obviously want to limit the size of any asset on a mobile device if necessary, but the W3C spec still needs to catch up with an image tag that allows multiple sources for multiple breakpoints. Until then, we have this:

Picturefill, a JS lib that allows us to specify multiple images with data attributes. In my opinion, the current landscape of responsive design feels very much like back when CSS and semantic markup had become en vogue. Browsers and W3C spec will need to catch up, and until then we will have to put some hacks in place to heighten the UX.

Tools

Now for the tools…

The W3C now has a couple of recommendations in the works for Timing APIs to measure a slew of attributes surrounding page speed. They are super easy to use too, all you need to do to leverage is:

window.performance

…and BAMMO, you’ve got yourself an interface in which you can piece together just about any metric for page load, memory allocation, etc. that you want.

If you just want to get a good rundown of these metrics, but don’t want to build it yourself, then use the PageSpeed Critical Path tool, a project headed by Bryan McQuade at Google. Bryan, Patrick Meenan, Dallas Marlow, and Steven Souders went over the tool in depth at Velocity, and you can see their presentation here.

A Stronger, Faster Web

Velocity’s theme is centered around “Building a Faster and Stronger Web.” What amazes me is that after leaving the conference I already feel more confident in my ability to begin building a faster, strong web.

Velocity was a conference that didn’t disappoint. It wasn’t a dull offering of overdone presentation topics and speakers – it actually offered interesting panels and presentations on a variety of really engaging topics, all centered around that single theme. I’m looking forward to heading back next year and learning what it will be like building the web in 2013!

Categories
Author

Rails views are typically rendered after some controller action is executed. But the code that powers Rails controllers is flexible and extensible enough to create custom rendering objects that can reuse views and helpers, but live outside of web request processing. In this post, I'll cover what a Rails controller is and what it's composed of. I'll also go over how to extend it to create your own custom renderers, and show an example of how you can render views in your background jobs and push the results to your frontend.

What's a Controller?

A Rails controller is a subclass of ActionController::Base. The documentation says:

Action Controllers are the core of a web request in Rails. They are made up of one or more actions that are executed on request and then either render a template or redirect to another action. An action is defined as a public method on the controller, which will automatically be made accessible to the web-server through Rails Routes.

While Base suggests that this is a root class, it actually inherits from ActionController::Metal and AbstractController::Base. Also, some of the core features such as rendering and redirection are actually mixins. Visually, this class hierarchy looks something like:

ActionController::Metal is a stripped down version of what we know as controllers. It's a rackable object that understands HTTP. By default though, it doesn't have know anything about rendering, redirection, or route paths.

AbstractController::Base is one layer above Metal. This class dispatches calls to known actions and knows about a generic response body. An AbstractController::Base doesn't assume it's being used in an HTTP request context. In fact, if we peek at the source code for actionmailer, we'll see that it's a subclass of AbstractController::Base, but used in the context of generating emails rather than processing HTTP requests.

module ActionMailer   class Base < AbstractController::Base     include AbstractController::Logger     include AbstractController::Rendering  # <- ActionController::Base also uses     include AbstractController::Layouts    # <- these mixins, but for generating     include AbstractController::Helpers    # <- HTTP response bodies, instead of email response bodies     include AbstractController::Translation     include AbstractController::AssetPaths   end end 

Custom Controller for Background Job Rendering

For a recent project, I needed to execute flight searches in background jobs against an external API. Initially, I planned to push the search results as a json object and render everything client-side, but I wanted to reuse existing Rails views, helpers, and route path helpers without redefining them in the frontend. Also, because of differing client performance, rendering server-side improves page load times for users in this instance. Architecturally, what I wanted looks like:

The requirements for this custom controller were:

  • access to route helpers
  • renders templates and partials in app/views

Unlike a full blown ActionController, this custom controller doesn't need to understand HTTP. All it needs is the result of the flight search from background workers to be able to render an html response.

The full code for the custom controller is:

class SearchRenderer < AbstractController::Base   include Rails.application.routes.url_helpers  # rails route helpers   include Rails.application.helpers             # rails helpers under app/helpers    # Add rendering mixins   include AbstractController::Rendering   include AbstractController::Logger    # Setup templates and partials search path   append_view_path "#{Rails.root}/app/views"    # Instance variables are available in the views,   # so we save the variables we want to access in the views   def initialize(search_results)     @search_results = search_results   end    # running this action will render 'app/views/search_renderer/foo.html.erb'   # with @search_results, and route helpers available in the views.   def execute     render :action => 'foo'   end end 

A runnable example of this source code is available at this github repository.

Breaking down the above code, the first thing we do is inherit from AbstractController::Base:

class SearchRenderer < AbstractController::Base   def initialize(search_results)     @search_results = search_results   end end 

We also save the search results in an instance variable so that our templates can access them later.

  include Rails.application.routes.url_helpers  # rails route helpers   include Rails.application.helpers             # rails helpers under app/helpers 

These methods return Rails route helpers like resource_path and resource_url, and also any helpers defined in app/helpers.

Next we add the mixins we need to be able to call the #render controller method. Calling #append_view_path sets up the view lookup path to be the same as our Rails controller views lookup path.

  include AbstractController::Rendering   include AbstractController::Logger    append_view_path "#{Rails.root}/app/views" 

Then we define a controller action named execute that'll render out the response as a string. The #render method used here is very similar to the one used by ActionController.

  def execute     render :action => 'foo'   end 

To use this renderer object, you need to initialize it with a search results object, and call #execute:

search_results = [{:foo => "bar"}, {:foo => "baz"}] renderer = SearchRenderer.new(search_results) renderer.execute 

Summary

Rails ActionControllers are specific to HTTP, but its abstract parent class can be used to construct objects for generic controller objects for coordinating actions outside of an HTTP context. Custom controller objects can be composed with the available mixins to add common functionality such as rendering. These custom controllers can also share code with existing Rails applications DRY up templates and helpers.

Categories
Author
1
Subscribe to Optimization