RailsConf 2014

Surviving the Big Rewrite

Surviving the Big Rewrite

by Bradly Feeley

In the video "Surviving the Big Rewrite" presented by Bradly Feeley at RailsConf 2014, the speaker discusses the use of Middleman, a static site generator, in the realm of web application development. The talk emphasizes the importance of understanding Middleman's role and functionality, particularly in improving deployment processes and creating efficient web applications. Key points include:

  • Introduction to Middleman: Middleman is depicted as a modern alternative to Jekyll for building static websites, utilizing contemporary Ruby gems, and emphasizing modularity through its foundation of Rack. The speaker notes the good documentation provided for Middleman, which aids developers in its application.

  • Getting Started with Middleman: The process of initiating a Middleman project is compared to that of a Rails application. Developers can easily set up a development environment with a quick server startup, aiding rapid development.

  • Environment Awareness: Middleman supports multiple environments, facilitating the use of various extensions for development and production, such as live reload during development and asset minification in production.

  • Deployment: Deployment is simplified to a two-step process: building and transferring files to a web server or S3 bucket. The speaker highlights the cost-effectiveness and scalability of hosting static sites on Amazon S3.

  • Dynamic Applications: Feeley provides context on the spectrum of web applications, noting dynamic applications require real-time capabilities, leveraging Middleman effectively in scenarios such as polling applications and interactive presentations.

  • Lifecycle of Development: The evolution of their web applications from Rails to Middleman illustrates the adaptability required in web development, showcasing flexibility in choosing libraries and frameworks tailored to specific challenges.

  • Case Studies: Feeley recounts experiences from his company Poll Everywhere, detailing the transition from a Flash application to a Middleman-based application that successfully integrates with various platforms, including PowerPoint, highlighting how they maintained a responsive user experience during high traffic events.

  • Asset Management: Utilizing Sprockets with Middleman allowed for a consistent user interface across multiple applications, enabling developers to efficiently manage shared assets.

  • Call to Action: The speaker encourages attendees to explore Middleman for personal or professional projects, indicating that their company will be releasing a framework designed around Middleman for broader use.

In conclusion, the video underscores Middleman's advantages in building static and dynamic web applications, promoting its ease of use, deployment efficiency, and adaptability in various development scenarios to improve the overall web development experience.

00:00:16.320 Alright, while these responses are coming in, it looks like quite a few people have either handcrafted HTML and CSS applications. I'm not sure if they are built as single-page applications or if they are simply deploying straight-up Rails applications with all the logic on the server side.
00:00:23.590 That's good to hear! I hope you'll learn something new today about how my company, Poll Everywhere, works. The product you are seeing is a software as a service application, and we sell this to presenters based on audience size. So, I'm going to fire up the slides here.
00:00:40.630 Alright, my display settings are working, which is good. So, let’s jump into it. This presentation is titled "Middleman: The Missing View in the Rails API Stack." As I mentioned before, I'm Brad Gessler, the CTO and co-founder of Poll Everywhere. We started this company about six years ago, and we have always been mobile-first, initially focusing on SMS.
00:01:11.560 We've gone through all the pains of upgrading to the second vintage of mobile-first, which is basically a mobile website. We had a lot of fun doing that and learned many things the hard way. But first, what is Middleman? How many of you have heard of Jekyll in this room? That seems to be the predominant static website generator.
00:01:31.360 If you go to Ruby Toolbox and ask, "Hey, what should I use to generate a static website?" you are likely to get Jekyll as a recommendation. However, Middleman is not like Jekyll in that it uses many modern Ruby gems commonly found in Rails 4 and Rails 3. For instance, it uses Tilt to manage templating and Sass, and all that good stuff.
00:02:09.399 So, if you're looking for a tool to build a static site, don't be discouraged by the comparisons to Jekyll; you should feel a lot better about Middleman after this talk. Middleman is extraordinarily well documented. Thomas Reynolds is the mastermind behind it, and he built an amazing website with comprehensive documentation.
00:02:31.360 If you go to middlemanapp.com, you'll find everything you need about this static site generator. Another fantastic aspect of Middleman is its modularity; it uses Rack under the hood. So, if you understand Rack, you can write lots of extensions for Middleman, which is quite impressive for a static site generator.
00:03:02.820 There’s also an extension framework, allowing you to roll out features like a Middleman blog. Essentially, Middleman is a drop-in replacement for Jekyll, with a few additional features. If you are used to writing GitHub-flavored Markdown, there are some tweaks you'll need to make to get everything functioning smoothly.
00:03:40.900 Getting started with Middleman is also quite similar to starting a Rails application. You install the gem, initialize the application, and it creates all of this boilerplate code. You get a directory structure that includes your configuration file, a default index HTML ERB file, a layout file, and all your assets, such as stylesheets and JavaScripts. You can spin up the server, and it boots extremely fast; you can have everything working in under a second.
00:04:25.630 One thing I love about Middleman is how easy it is to come into it from Rails. As I mentioned before, it uses Tilt, so you can bring in all the same gems and the same toolset that you hopefully have come to love in Rails without too much trouble. Another interesting aspect of Middleman is that it is multi-environment aware.
00:05:00.820 This is a default configuration from Middleman, simplified a bit. In your development environment, you can include various extensions, like live reload. You can pull these extensions from the directory on the Middleman website. In production, Middleman refers to this as the build environment, where you'd activate certain extensions like minifying CSS or JavaScript, or using asset hashing.
00:05:39.760 Once you have this configuration set up and your web pages ready to go, you need to deploy them. This is another area where Middleman truly shines. Deployments are incredibly easy—it's just two steps. First, there’s the build command, which compiles all these templates and files into a build directory.
00:06:26.270 The best part is that getting that build directory up to your web server is as simple as an rsync command. If you want to throw back to the days of using Dreamweaver, you could still use FTP or SFTP, if you're into security. I developed a gem called Shart to facilitate this process, humorously hoping it would spark awkward IT conversations in corporate environments.
00:06:50.100 With Shart, you can deploy your Middleman website to an S3 bucket and set the headers for certain assets. There are tons of tools available for this, and deploying to S3 is incredibly cost-effective—just a few cents a month for a personal website. It’s also a highly scalable solution for your static websites.
00:07:14.790 So, now that you have a static website, you might wonder why you should care about Middleman. How is it going to help you scale your application? To answer that, it’s crucial to understand Middleman’s place in this spectrum of dynamic and static applications.
00:07:49.640 I refer to this spectrum as "Dyna-scizzum." But it turns out, 'dinah scizzum' is not actually a word, so I had to ignore the spell checker. The graph I mentioned earlier represented a static web application. If you access pollev.com on your smartphone, that was another static web application.
00:08:06.430 However, that was a rather dynamic application because the chart had to move, animate, and pull data from the server in real-time under one second. We needed to ensure that this data could get from all your phones—whether through SMS or smartphones—up to the graph very quickly. So, this is a highly dynamic application.
00:08:54.470 Additionally, we needed to make everything very smooth and fluid for presentations. As we move down the Dyna-scizzum spectrum, we have GUI-oriented applications, such as Google Spreadsheets. Most people are familiar with that; it involves many different actions that need to be swift. You don’t want to build applications where you click a button and wait for a server response.
00:09:41.280 The functions of the GUI should be closely coupled with the server operations. We then move into document-oriented web apps like invoicing applications or Basecamp, which sit in the sweet spot between highly dynamic applications and highly static applications. Moving further down is the blogging platform world, with systems like Subtle or Posthaven that are backed by MySQL.
00:10:31.560 For the most part, they simply store documents in a database server for convenience in administering numerous users and a multi-tenant environment. At the bottom of the spectrum are personal blogs, possibly hosted on GitHub using Jekyll or Middleman, and informational websites like small local businesses.
00:11:04.830 So, where does Middleman fit into all of this? If you're working on a greenfield application, it’s straightforward to get started. You typically build your single-page application and a smaller API using Sinatra or some micro-framework.
00:11:39.030 Since we started as a company in 2008, we initially built our application using Rails 1.2, even before REST was a thing. We set up an application on pollev.com, and we incorporated real-time components. I don't know if anyone remembers RJS, but back then, we used those horrendous helpers to emit JavaScript from the server to your web page.
00:12:42.000 We achieved a lot with that, but eventually realized we needed something more visually appealing than just updating numbers in a table. So, we turned to Flex, which offered a great bar chart library that updated in real-time and just worked out of the box. It also just happened that Flash was installed on an overwhelming majority of networking machines, which made it easy to embed Flex assets in PowerPoint.
00:13:56.620 We executed a quirky hack where we would embed those Flex applications in PowerPoint slides and let people download polls already embedded in their slides. When they opened it, nothing actually needed to load from the Wi-Fi at the conference; the Flex application connects directly to our Rails app to pull that data.
00:14:38.210 Initially, we had this Flex application within the same repository as our Rails application, but as we grew and scaled, things became more complex. Eventually, we could afford a contractor who worked on the Flex app, enhancing it and enabling faster deployments. This led us to separate the applications, allowing our Rails app team to push updates independently.
00:15:41.650 Over time, mobile started evolving beyond just SMS, primarily thanks to the advent of the iPhone. We had good luck in the past with frameworks like Rails and some visual components from Flex, which naturally led us to use jQuery Mobile. At that time, some suggested using the .mobi extension to serve up mobile content, but that turned out to be a poor decision.
00:16:27.170 jQuery Mobile worked for about 80% of our needs, but the last 20% was extraordinarily painful. We found jQuery Mobile to be extremely prescriptive in how it structured DOM elements, and it felt somewhat clunky to work with. This led the team to rethink our approach: instead of choosing one rigid framework, we opted to focus on the specific problems we needed to solve.
00:17:14.670 By selecting specific libraries for each task, we created a much clearer development path and brought in what we needed for our application. Around that time, various JavaScript MVC frameworks emerged, including SproutCore, but we decided to move forward with Backbone.js.
00:18:03.300 At the time, it was still maturing, and we knew we might need to switch libraries as things evolved. This approach enabled us to handpick the exact libraries we needed and to swap them out when we found better options. Our result was a single-page mobile application built entirely within Middleman.
00:19:17.790 Middleman handled all the assets for this application using the standard Sprockets pipeline found in Rails. Whenever we built the application, we ended up with three files that we uploaded to our NGINX server, and we were very happy with how everything functioned in production, especially regarding deployments.
00:20:40.020 If you choose to build single-page web applications, you should be aware of CORS (Cross-Origin Resource Sharing). When you loaded pollev.com on your phone, it made AJAX requests to our API endpoint, and without CORS, you would receive cross-domain errors. CORS allowed our server to whitelist requests.
00:21:52.700 Another interesting feature of how we deployed this mobile app was its ease of deployment to CDNs. You can push your assets out to separate servers, which isn’t as feasible with a Rails app since you can't just move it over to a different server's filesystem without booting everything up.
00:22:56.220 A fun and unexpected feature we discovered was the ability to deploy our application onto floppy disks! I had floppy drives, available for about 15 dollars on Amazon, and surprisingly, MacOS supports floppy drives, which made for an amusing live hardware demo.
00:23:36.080 Imagine having a customer in a remote area, and the only way to get something to them is via Pony Express. You could place this floppy disk in a satchel and send it off. It was quite amusing to see the Network Inspector reveal the latency issue of booting up a web application from a floppy disk.
00:24:26.000 While joking about creating a library called ‘Floppy.js’ due to limitations with large assets not fitting, it would illustrate that our primary focus was still on fixing production bugs instead. More importantly, you can package hollow applications with HTML assets through PhoneGap. We had customers who wanted to bundle our polling application with their mobile apps.
00:25:50.010 We provided our HTML assets to integrate within their applications. So even when 300 people are in a conference room voting, it wouldn’t overload the Wi-Fi. That said, Flex began aging, and the writing was on the wall for its eventual obsolescence.
00:26:54.300 This gave us a natural driving purpose: to create a visualization app. We decided to utilize Middleman, aiming to build something that works on tablets and iPhones, leveraging HTML5 to communicate with our JSON API. It worked remarkably well, and today, you are witnessing that HTML5 application in action.
00:27:54.410 We have all the advantages of caching and CDNs with this application. However, a challenge arose when we started noticing slow performance with our visualizations because we depended on short polling—hitting our server to get new data every few seconds to update our graphs.
00:29:06.190 To improve this, we rolled out a streaming API. At that time, we also wrote our own server as Socket.io didn’t meet our needs. I previously gave a talk in 2012 on streaming resources, and we set up our stream server on a separate host, isolating it. Even during this experimentation, we faced stability issues.
00:30:29.490 However, our client-side applications were able to seamlessly fall back to HTTP short polling whenever there were issues with the stream. Over time, the team became much better at handling these elements, managing client-side service-oriented architecture (SOA). Additionally, CORS enabled us to consume multiple APIs and combine their data in JavaScript.
00:31:27.770 We found so much success with these Middleman single-page applications that we started to develop all our other applications in this manner. Our approach to native integrations evolved into creating specialized web browsers with unique JavaScript hooks, allowing web developers to be more productive and versatile.
00:32:15.950 We've had numerous Backbone.js applications emerge from this work. Now, if you’re dealing with various applications, you may think about reevaluating your strategy to prevent redundancy and achieve better organization in a world filled with Sprockets and Middleman.
00:33:04.960 We extracted common components—session components, models, and Backbone—into one asset gem for all applications to consume from. So, building these gems becomes just like creating any other gem with Bundler, allowing us to manage dependency versions seamlessly.
00:33:25.800 Utilizing Bundler, we prevent breaking changes when updating libraries; we can continue using the versions we specify in our gem bundles. We host our assets in a Git repository and reference them in a gemfile, enabling local updates during development.
00:34:16.870 Whenever a branch is updated in the Pull of Assets repository, changes get picked up the next time you reload Middleman without restarting the whole server. This allows for a smooth feature-building process, as we can branch our Rails app project and the Middleman project simultaneously. Ultimately, we can deploy them in the correct order, with APIs implemented first.
00:35:05.150 Does it work? Yes, it has worked remarkably well for us—especially when infrastructure gets complicated, such as dealing with bandwidth-constrained environments or unreliable conference Wi-Fi. Just two months ago, Microsoft launched their PowerPoint 2013 app store.
00:36:00.290 We managed to pull many assets from our mobile application into our Sprockets asset gem to reuse most of that work. Quick customizations enabled us to integrate smoothly with Office 2013. Whether you're running a single-page application inside an iframe in Office, it feels very native.
00:37:05.350 This practice of reusing functionality proved beneficial. Working on any given project often results in improvements—better handling of logins or status codes or similar features. These improvements can be integrated back into the Sprockets asset gem and pushed out to other projects, leading to system-wide benefits.
00:37:56.090 This reinforcement of functionality turns the Sprockets asset gem into a cohesive framework, extracted in a way that is both practical and successful for our customers. That was an overview of one of the more complex Middleman deployments, illustrating how to manage multiple projects while highlighting the adaptable nature of Middleman.
00:39:02.300 One downside is there is no out-of-the-box JavaScript MVC app solution in Middleman. For example, when using Backbone, you're responsible for organizing a lot of the assets, which may vary in quality across different frameworks. This situation was a boon for us, as it compelled us to create our own, sidestepping issues related to someone else's less-than-ideal framework.
00:39:59.790 Lastly, let's address static websites on the other end of the spectrum where Rails balances everything in the middle. We're developing a lot of content for our website, with an explosion of use cases demanding implementation. One thought on our front is to extract a content directory from our Rails app.
00:40:54.540 Raise your hands if your Rails app started with a home page, then evolved into a content directory with twenty or thirty pages. Before long, that repository becomes a disorganized junk drawer of pages. In Middleman, the directory structure is also the routing structure, simplifying organization.
00:41:34.290 Middleman offers much better support for aspects like image compression, enabling designers to focus on creating while Middleman optimizes images for the web. For static websites like this, you can't simply ignore components like login states; JavaScript can help maintain some dynamism.
00:42:38.930 You can implement client-side checks to verify if a user is logged in by checking cookies, and you can integrate server interactions through forms. Furthermore, you can add other JavaScript applications like Google Analytics, Optimizely, or Stripe, enhancing functionality while keeping your site primarily static.
00:43:33.910 The advantage of static websites is their resilience; they don't get easily taken down, especially if hosted on S3 buckets or CDNs. I attended a Middleman meetup a year ago, where attendees mentioned their CMS or dynamic back end kept slowing down their website due to press mentions.
00:44:44.370 Instead of throwing money at the problem, they opted for building a static website with Middleman and deploying it on simple servers, eliminating those traffic issues. There are many considerations to take into account when building these Middleman applications.
00:45:49.610 I could probably give several more talks solely focused on this, and I'd be happy to answer questions later. I encourage everyone to try building their next website using Middleman! Whether it's a personal website, a blog, or something else—give it a shot.
00:46:45.460 You can migrate your hand-crafted setups into Middleman and start leveraging the asset pipeline. Furthermore, I didn't mention that my company, Poll Everywhere, is also working on extracting the framework and will be releasing these components as ‘Fanny Pack.’ Fanny Pack will handle testing, binding to different environments, and more.
00:47:30.960 If you’d like to work on Middleman projects professionally, consider joining our team at Poll Everywhere. That concludes my talk. I'm Brad Gessler, and I will be sharing slides, links, and code on Twitter when I’m not busy working on these projects. Thank you!
00:48:12.560 Thank you.