Lazy loading javascript files with Rails

The Rails asset pipeline is wonderful for organizing your javascript files. Once you figure it out, it’s really quite nice.

One problem I had was that certain pages of my site needed some heavier javascript, and I wanted to delay loading those scripts until after the page is loaded. I hoped this would provide some perceptible page speed improvement to the user, who wouldn’t have to wait until all the js is downloaded to see the page.

However the Rails asset pipeline doesn’t really support this ability — not that I could see, anyway.  I did come across a couple resources that helped me figure this out, and here’s how I got it to work:

First, set up your application layout.  I do something like this, to allow for the main site-wide js to be loaded, but also defer to the specific page if anything needs to be added there:

<head>
...
<%= stylesheet_link_tag "application" %>
 <%= yield :stylesheets %>
 <%= javascript_include_tag "application" %>
 <%= yield :javascripts %>
...
</head>

now instead of loading the ‘application’ js file, change your layout to load a new file called ‘application_bootstrap.js.erb’  in your app/assets/javascripts directory:

<%= javascript_include_tag "application_bootstrap" %>

in that application_bootstrap file, use this code to append the real application.js file to your page after it’s loaded (using code from developers.google.com) :

// Add a script element as a child of the body
 function downloadJSAtOnload() {
 var element = document.createElement("script");
 element.src = '<%= asset_path "application.js" %>';
 document.body.appendChild(element);
 }
// Check for browser support of event handling capability
 if (window.addEventListener)
 window.addEventListener("load", downloadJSAtOnload, false);
 else if (window.attachEvent)
 window.attachEvent("onload", downloadJSAtOnload);
 else window.onload = downloadJSAtOnload;

Notice in this case I have loaded application.js, which is in my /app/assets/javascripts folder. Since it’s part of the asset pipeline, that file will get loaded and its contents executed.  On our production site, all these assets will have fingerprints so the filenames will look like this:

application-bfcb538d79e6dc74d17dff16a569fc72.js

Note that we use the asset_path erb helper to generate the correct path to that file.  When we look in the application.js file itself, we see the usual Rails asset pipeline notation for including multiple js files, like this:

//= require jquery-1.7.2.min
//= require jquery_ujs
//= require bootstrap.min
//= require bootstrap-datepicker.js
//= require jquery.placeholder.js
//= require site

when the asset pipeline runs, it will concatenate all those files together ,and deliver it to the browser. As long as we don’t need those files before rendering the page, the site should still work.  If some are still needed, you can separate those out and load them as usual, and lazy-load the rest.

Also I mentioned having additional js to render on specific pages — those can be lazy loaded too. Just repeat the same process you did for application_bootstrap.js. Create whatever_bootstrap.js.erb, put the above code in it, and change the

<%= asset_path "application.js" %>

To whatever.js you want to load for that page (assuming whatever.js is in your app/assets/javascripts directory).  Be sure to test this on a variety of different browsers, I did see some different behavior on older browsers that left the page unusable.

Don’t forget to add these new assets to the precompile list in environments/production.rb (or whatever env you want):

config.assets.precompile += %w(application_bootstrap.js whatever_bootstrap.js)

And you should be good to go. try running RAILS_ENV=production rake assets:precompile, and see if you get an application_bootstrap.js file with the expected contents.

lazy-loading-firebug-screenshot

Here is a screenshot of firebug after implementing this change. You can see that the home_bootstrap js gets loaded before the page is finished loaded (vertical red line), but the home-5c702… js file is loaded after.  So the user isn’t waiting on that file to load before seeing the page.

Some caveats:

This won’t work if you use require_tree in your asset pipeline; in that case, you may need to put your application_bootstrap.js.erb file in its own subdirectory so it doesn’t get loaded by the asset pipeline automatically.

There are other, probably better ways of lazy loading javascript; I’m still experimenting with this, so will probably revise it as I make tweaks.  One possibility is replacing the code in application_bootstrap with the a call to the LazyLoad library, and ensuring LazyLoad itself is loaded in the layout.

 

 

Tagged with: , , ,
Posted in Code

Boston Tech Scene 101

People often reach out to me asking about the Boston web/mobile tech scene. How to find meet ups, looking for co-founders, or recruiting for their company.  Here’s a collection of resources for incubators, meet ups, and other events around Boston.

This list is by no means exhaustive, but I will add to it as I find more resources. If you would like me to add anything, drop me a note on the contact page.

Developer training

Startup Institute – training program across a variety of disciplines to prepare students for startup careers.

Apprentice.io  — web developer training program, run by Thoughtbot (see below).

General Assembly – Offers classes on a variety of tech topics, as well as more in-depth courses.

RailsBridge Boston – Introductory Ruby on Rails workshop for women.

Launch Academy – 10-week course from novice to junior developer

 

 

Incubators / Accelerators / Co-working

TechStars — One of the premiere incubators and startup schools nationwide, TechStars has a Boston location and accepts a few Boston-based startups each year.

Paypal Start Tank — Paypal hosts select startups in their Financial District offices, as well as offers mentoring and events. 

Cambridge Innovation Center – rental space and facilities specially arranged for small and startup companies.

MassChallenge — Startup accelerator and competition.

Idea — venture lab attached to Northeastern University , open to students there.

OpenIncubate — IT-focused incubator, also associated with OpenStack cloud software.

Harvard i-Lab — venture lab associated with Harvard University, open to its students.

 

 

 

Ruby and Rails groups

Boston.rb — the biggest gathering of Ruby enthusiasts in the area. Videos of presentations are also available on their site.

Thoughtbot — A consulting company, not a public forum, but a strong presence in the Ruby scene and worth getting to know.

 

 

Meetups

WebInno — David Bisel (of Venrock) puts on this popular bi-monthly mixer and demo night.

Boston hosts many meet ups in various topics  around tech and startups, search meetup.com to find those in your area of interest.  Check out Lean Startup Circle, or Boston Mobile Apps Developers meetups.

 

Other

Innovation District – Boston marketing term for neighborhoods around the Seaport District. The city of Boston is making an effort to woo startups and tech companies to the area.

 

Posted in Events

Set up a Torrent and Media Server on Raspberry Pi

Photo courtesy of Feremy Fuksa, used under Creative Commons license

Photo courtesy of Jeremy Fuksa, used under Creative Commons license

I recently purchased a Raspberry Pi mini computer, and had to think of something to do with it.  I decided I would offload the torrent downloading and media serving responsibility from my home PC to this tiny wonder. Here’s how I did it:

 

1) setup your raspberry pi.  Here’s an intro tutorial.  Basically you need a PC of some sort, an SD card, and a way to copy files to that card from the computer (eg a USB adapter for the SD card).  I used a mini SD card with a ‘macro’ SD card holder, and plugged that into my pc with a multi-type card reader like this one.  You’ll want to use the default Raspbian Wheezy image for your card, download it here. The Raspberry setup guide presumes you use a Windows PC, if not you’ll need other instructions on how to setup the SD card.

 

2) boot your pi for the first time. This is a bit of pain, because by default the Pi needs a video display connected to its hdmi port, and keyboard to its usb ports. I’d rather be able to just boot it and the ssh to the Pi, but to set that up you have to boot the standard way first. I connected to my TV with a hdmi cable and an old USB keyboard I had lying around.

 

3) setup ssh. You’ll want to do the rest of the setup from the comfort of your laptop or desktop, so the first thing we’ll do is setup ssh on the Pi so we can connect to it instead of using the TV.  Here’s one way to do it.

 

4) install transmission.  This will be our bittorrent client.  Instructions here. You will want to change the rpc-whitelist (I just turned rpc-whitelist-enabled  to false). Watch-dir is the location that transmission will monitor for uploaded torrent files; any files it finds there will automagically begin torrenting. Don’t forget to change the password, as we’ll be exposing this via web. Try it out by going to http://<yourPiIpAddress>:9091/  (that should be the default port configured in /etc/transmission-daemon/settings.json, under ‘rpc-port’). You can change some settings from the web gui if you like.

5) setup an external drive.  You’ll want to add a usb drive to store your torrents and media on, so connect that up. It should be accessible on /media/usb0. Make sure your transmission settings say to save to that drive or some folder under it.

6) install serviio for media serving.  I run Serviio on my Pi, which provides a DNLA server that other devices, including many modern TVs, can connect to and stream content from.  To install Serviio you first need Java, so get the java distribution for ARM from Oracle Java. I didn’t find this version for ARM in their main lists, so you have to hunt for it.  Download that, copy it to you pi, unpack it and install it in /opt/jdk1.8.0.  Update your PATH env variable to include /opt/jdk1.8.0 in ~/.bashrc.

Once Java is installed, confirm it by running ‘java -verison’.  Then proceed to install serviio.  Download Serviio from http://www.serviio.org/download , get the linux version.  You’ll also want to install some of the prerequisites, such as ffmpeg, by running:

- apt-get update

- apt-get install ffmpeg

- download serviio, unpack it, and install wherever you like. Run the server by running ‘bin/serviio.sh’ from the serviio directory. Hopefully, it will start up. It may take some time to start, due to the Raspberry Pi’s relatively slow cpu.

- Once you confirmed serviio is running ok, you need to configure it. This difficult because we’re not running our Pi with a display, so we want to run the serviio console on our laptop (or desktop), and have it connect to the serviio server on the Pi.  This can be done with some java vm arguments.  Simply start the serviio console from the command line with:

on the Pi:
in the bin/serviio.sh file, add -Dserviio.remoteHost=<server_IP_address> to the end of the JAVA_OPTS line

on the client machine:
in the bin/serviio-console.sh file, add -Dserviio.remoteHost=<server_IP_address> to the end of the JAVA_OPTS line

Then start the server on the pi with serviio.sh, and the client on your machine with serviio-console.sh. You should see the GUI console pop up, and hopefully connect to your Serviio running on the Pi. From here, you can set the media directory (choose your Transmission download directory from step 4), and whatever else you want. Be sure to refresh the library to get Serviio to pick up all your files.

Disconnect your console, and Serviio should still be running. At this point, you should be able to turn on your TV or DLNA device and see the Serviio registered there. You can browse to your content and play it back on your TV!

At this point, you will probably want to ensure that Serviio and transmission are started every time Pi boots, and if the process dies for some reason (fairly common with Java) to restart it.  You can do this with some scripts in /etc/init.d:

/etc/cron.hourly/serviio-launcher.sh:

https://gist.github.com/toddp/4746771 

/etc/init.d/transmission-daemon.sh:

 https://gist.github.com/toddp/4746764

 

I have to admit this isn’t entirely stable, and I need to reboot my Pi occasionally. I think it’s pushing the little Pi to its memory and cpu limits, especially running Serviio which requires Java and a considerable amount of memory. Still, it’s a fun project in a small package.

Feel free to contact me if you have trouble or any questions.

 

Posted in Uncategorized

General Assembly offers tech education

General Assembly (http://generalassemb.ly) is a new face in the Boston tech scene, having opened its Kendal Square location back in October.  GA claims to “transform thinkers into creators through education and opportunities in technology, business, and design.”  GA hosts a variety of classes, from a one-evening session on mobile apps to a 10-week course in product management.

I attended the class titled “Building Web Apps with Backbone.js”, which gave an intro to the popular Backbone.js framework. About 12 people attended, with varying levels of skill and experience. The instructor, Dave Wasmer, took the pulse of the attendees with a quick javascript quiz and then dove into the meat of the material.

Dave has a great command of Javascript and backbone.js.  Unfortunately Dave didn’t get a chance to cover some of the material, as the class had a lot of questions that slowed down his progress. It’s tough to do crowd control, and ensure that everyone has the right background to benefit from the material.

Still, my group did get some valuable tips out of the class, and we’re going back for the Advanced backbone.js course later in February. A big benefit to attending in-person classes and meetups (as opposed to doing tutorials online) is the chance to meet and talk with other people working in the field.  We met a number of great people, and I left thinking that General Assembly is making a big contribution to the Boston tech community.

Slides from the class are here:  http://www.rvl.io/davewasmer/building-with-backbone

Dave is also very interested in building a community of Backbone.js developers in Boston, so if you use backbone or are interested in learning, contact Dave on twitter at @davewasmer .

More General Assembly course listings at https://generalassemb.ly/education

 

 

Tagged with: , ,
Posted in Code, Events

Learning as a Team

Former PMI Mass Bay president Steve Martin (not that Steve Martin) presented at this month’s chapter meeting in Burlington.  His slides, and other materials are available here:  http://www.emergn.com/insights/events/pmi-learning/

Steve’s talk focused on teams and learning, and how teams learn differently from individuals.  After the basic concepts, he then applied that idea to the world of corporate training — for example, Scrum training for a team or whole company.  The way it’s usually done is a 1-day or a few days of intensive training, where the topic is introduced and a lot of material thrown at the student, and after the training they are ‘certified’ and now ready to be a ‘master’ of this subject at their company.

Except we don’t retain that much of what was presented; 25%, maybe. And we don’t learn as well given all the material up front, as opposed to learning a little bit over time.  So Steve proposes work-based learning on real projects, with teams using a scrum-like process to figure out what is most important for them to learn first (the backlog), experiment with that knowledge and do something practical, then reflect on how it went before learning the next important concept.

Steve claims this style has shown to reduce cost of training up to 30%, and since the team is using a real project to learn the new material, benefits are shown immediately. This takes the focus away from passing a test or completing a course to using the new knowledge to actually work better and improve the project, which makes the team more accountable for results.

Steve blogs at https://www.valueflowquality.com/author/stevemartin

More info on PMI Mass Bay (Boston-area chapter) and upcoming events available here: http://www.pmimassbay.org/events/all-events

 

Posted in Agile and Scrum, Events

Agile Boston – Thanksgiving for Scrum

over 100 in attendance at Agile Boston "Give Thanks for Scrum" event.

over 100 in attendance at Agile Boston “Give Thanks for Scrum” event.

Today I attended the Agile Boston group’s November meetup, titled ‘Give Thanks for Scrum‘.  The “giving thanks” part was to recognize everyone working to transform their team/organization to embrace Scrum and agile methodologies. Ken Schwaber and Jeff Sutherland each presented, and both had some interesting highlights about how far scrum has progressed since its creation in 1990s:

  • 400k+ job postings that mention ‘scrum’; Ken claims we’ve reached the tipping point
  • Scrum has moved out of just software, and into manufacturing, even social ‘do-good’ organizations with great results
  • US Dept. of Defense now requires their vendors to produce product in an iterative fashion, with frequent customer touchpoints – one of the key principles of agile

Some other fun stuff I learned today:

  • Jeff told the story of Joe Justice, who led a top-ten finishing team in the 100mpg electric car competition, delivering a road-legal electric vehicle in only 3 months! — using agile practices.
  • Heang Ly led a session demonstrating several ice-breakers, those getting-to-know-you games and funny practices to get strangers talking.  It seems like everybody likes to call these things ‘lame’ and act too good for them, but it’s amazing how earnest everyone was once we got going. People came out of their shells and talked, offered to help each other, and shared their insights.  I soon got over my self consciousness and thoroughly enjoyed myself.
  • Dan Mezick emceed, and brought passion and energy to the room from start to finish. I liked his no-holds-barred style, willingness to say daring things and challenge conventional wisdom.  I’ve started reading his blog.

More info on upcoming meetings at the Agile Boston site.

I met some great people, had some ok food, and generally had a good time. It wasn’t perfect — some people talking during the presentations made it hard to concentrate, and it seemed like a lot of attendees already knew each other, I had a hard time approaching people (which is more my problem than theirs).  But everyone was warm and inviting, and pretty positive people overall — the kind of people you get energy from when they’re around.  So I’ll probably be going back for the next meeting.
Posted in Agile and Scrum, Events