All posts by

The Responsive Image Challenge – Part 2

ej

In our last post, we talked about why images are getting increasingly complicated on the web. It’s a challenge we’ve put a ton of time into solving here at Bethel so that our system is easy to use for authors, designers, and developers.

To create the right solution, we needed to resolve 3 big issues:

  • Selecting the correct image size using dynamic JavaScript and HTML
  • Creating different sizes of the original image automatically
  • Uploading original images into the CMS

So, what did we do? We first looked into getting some JavaScript and HTML to select a good image size. This task was made easier with a little help from our friends across the pond.

Selecting the Correct Image – Imager.js

The BBC has an awesome library called Imager.js. Without burdening you with too much technical jargon, Imager.js is a JavaScript library to dynamically put an image into a placeholder element when the page loads. There are quite a few different libraries to do this, but what separates Imager from the rest of the pack is that it uses the width of the container element, instead of the width of the entire screen. So if we only need an image 100px wide to fit a container (even if the screen itself is 2560px wide), that’s the size we get.

Another thing we liked about Imager was that it loads images by the exact width, rather than using generic identifiers like “small”, “medium”, “large” to specify size. This helps us follow our third rule from the last post, “don’t serve a bigger image than you need.” Imager will select the exact size to fit the screen area. I won’t go into the coding specifics, but it’s documented well and easy to use.

Once we had Imager working correctly, the next problem was figuring out what to do with tons of different sizes of the same image. Dumping them into our CMS would make the system very cluttered and unfriendly. So it was time to look into solutions for automatically creating different sized images of an original image outside the CMS.

Creating Image Sizes – Thumbor

After some searching, we found a Python application called Thumbor.

Thumbor is pretty easy to install, and very easy to use. You simply call the Thumbor service using a URL and send a few parameters. Most notably, you send a width and height. Then it will download the original image, resize, crop if necessary, and return the new image. This means we can put Thumbor URL’s directly in our <img> HTML tags and it will work just like a normal image.

Remember how Imager used exact pixel width instead of a size? This was perfect for Thumbor. It was extremely simple to configure Imager.js to work with a Thumbor URL using an exact width.

Thumbor also has a few other neat tricks. First, it can set the height of the updated image automatically based on the width. It also stores versions locally. So if you request a 300px-wide image, it will resize, crop, and return that image. But it will also save a local copy, either on the filesystem or in a database. This means that next time you request the same 300px-wide version of the image, it won’t have to resize, crop, and return. It will simply return the smaller version it saved. This means that Thumbor overhead is extremely small. It only has to crop an image once. This made meeting our second rule, “have your resized images ready to go before they’re needed” pretty easy. Thumbor stores the versions for us.

To make it even faster, we have a simple script to request popular sizes of Imager from Thumbor when each image is uploaded. This means all our images will be available when we need them.

So once we had Imager and Thumbor working seamlessly together, the last step was pretty simple.

Uploading Images

Now there’s only one rule left to worry about, “always upload the largest copy possible.” Unfortunately, there isn’t some fancy Python script to make sure our web contributors upload the largest image size possible. This step requires some training. However, there might be a few helpful things you can do depending on your CMS. Maybe you can set a minimum width and height for new image uploads? Or a minimum file size? Who knows…just brainstorming.

But once the image upload process is actually started in the system, we can start having some fun. The first thing we do when an image is uploaded is automatically upload it to the server. Nobody thinks to publish an image after upload anyway. The CMS automatically pushes this image to the CDN, which triggers the script to request the different widths from Thumbor. This means that there are now 5, 10, 15, or even more versions of the image ready to go.

The best part? The web contributor can work with the image within the CMS just like normal. They have no idea that the image they are working with is never actually used. And that’s not a problem at all. They embed their image onto a page, and the template configures Imager to create the Thumbor-friendly URL inside the <image> tag. And then, when the page itself is published and viewed, the resized images are ready to go, just like any other images.

Aside from a few installs and a little template work, it’s completely seamless for authors, designers, and developers. And, to top it all off, no overhead for end-users. Just like that, we’ve created a 2007-style way to interact with images that works seamlessly with 2014-compatible complexity.

The Responsive Image Challenge – Part 1

ej

Images on the web used to be pretty simple. Upload your image to a server, throw the URL into an HTML <img> tag, and then it would appear on your page. No big deal.

However, a lot has changed in the last two years.

In 2007, Apple released the first-generation iPhone. The iPhone was the first smartphone that appealed to the average person. And, as we all know, it was a huge success and now all the major smartphone manufacturers are taking the same approach.

Overall, smartphones are great. You have instant access to the Internet, GPS navigation, calling, and texting all from a little device that you carry with you. For website maintainers, however, smartphones and the many devices they’ve spawned present some serious problems.

Problem #1 – Mobile connections are slow

While mobile speeds are a ton faster than they used to be, they’re still pretty slow compared to a traditional connection, especially outside of a big city.

So why is this a problem?

Well, compared to text and HTML code, images are really big. In fact, the text, html, CSS, and Javascript from www.bethel.edu is about 10% of the total page size. The other 90% is mostly images.

All that to say, text loads really fast, images load really slow. You can have an entire essay that’s smaller than a single image. On a desktop connection, not the biggest deal. However, this can make a huge difference on a slow mobile connection.

The simple solution: Make images as small as possible. Easy, right?

Not so fast.

Problem #2 – Retina

In 2010, Apple coined the term “Retina display.” In reality, this is just a screen with a ton more pixels than normal and an operating system that can still make everything look good. This is amazing for text and icons. Everything is smoother and overall better to view. So what is the downside? Well, images of course.

If anybody happens to be reading this on a Retina laptop, you might have noticed images look really bad on some websites. Why is this? Well, if you double the pixels of your display, but don’t double your image size, the images will have to expand to fill in the extra area. This causes blurry images all over your websites.

On a desktop, you can just serve an image twice as big. Not a huge deal. But what about mobile?

Retina screens are actually more popular on mobile than laptops because you actually hold those devices close enough to notice the difference. The catch-22 is that if we make our images look good, they are twice as big, and therefore take twice as long to load. If you compress them too much, the image quality will deteriorate. So we are dealing with the worst of both worlds—slower load speed with larger images. And even if connection speed wasn’t an issue, there is one more thing to consider…

Problem #3 – “Just make a bigger copy”

Pretty easy to say, but extremely hard to do.

If your source image is 300×300 but needs to be 600×600 for your Retina device, you can’t exactly just expand the 300×300 copy to be twice as big. It will look just as bad as if you served the 300×300 copy to begin with.

This relates to our first rule of images: “Always upload the largest copy possible.” Technically, we could serve this image all the time, and the let the phone or computer shrink it to the correct size. But these images are huge. At 3-5 megabytes a pieces, using this method would make our homepage close to 20 MB’s—a 2000% increase of our current page size.

So we need to resize it. But now the problem is that resizing and compressing images takes time. And time is very valuable when serving to a mobile connection. This creates a second rule:  ”Have your resized images ready to go before they’re needed.” Okay…so we need to have a different image size ready for every single width and height we’ll need to serve.

Great. And since we’re trying to speed things up, we’re going to need to make sure we only serve the exact size needed for the page. This ensures we’re loading as little data as possible. That is, if an image is only going to take up 100 pixels on the page, we don’t want to make someone load a 600-width version of the image. This is in line with our final rule, “don’t serve a bigger image than you need.”

Putting all those rules together shows how big of a problem this can be.

Before, we had one single image in an HTML tag. Now we have 10-20+ versions of the exact same image needed for a single webpage. After all, there are so many different phones, phablets, tablets, laptops, desktops, etc., that all need something different. That’s a lot of overhead.

We’ve spent a long time trying to create a solution that is fast, responsive, and extremely easy to use. And we think we’ve come up with something that, for our web authors, will be as easy as it was pre-2007 when we all we had was one image inside some HTML. Just put your image on the page, and leave the rest to us.

So how do we solve this? Check back next week for The Responsive Image Challenge – Part 2.

High-Stakes LEGOs

ej

Last week we mentioned that there are tons of parts that go into a single page in Cascade. It’s actually a little insane just how many different pieces there are. When we logged into our fresh Cascade install for the first time, it was overwhelming how empty it was. Up until that point, our demos and sandboxes had been somewhat functional. Now we had to start from a completely blank slate. We’ve had many meetings where all we do is draw diagrams trying to wrap our heads around how all the pieces fit together, and which blocks to work on first.

 

It might seem like all the different pieces would make it too complicated to use. But in reality, it’s almost the opposite. You can almost think of Cascade as a CMS to build a CMS. We start with a blank slate and work until we have Bethel-flavored Cascade ready to go.  This is where it’s advantageous to have all the different pieces and possibilities. We can put them together so they fit our needs perfectly in an easy-to-use package.

Right now we’re essentially playing with high-stakes digital LEGOs. Even our most basic page has dozens of parts. But this is actually a good thing. When we’re done, you won’t see individual LEGO blocks. Instead it will be finished LEGO sets, glued together so they won’t fall apart—ready to play with.