This is a translation of a post from the Facebook Engineering Blog, which is interesting, perhaps, not so much the essence of the solution, which it describes as a story about the "kitchen" of development on Facebook. We are talking about the updated photo viewing functionality, which appeared at the end of September 2010 and was slightly improved a few days ago.
Thinking about updating Photo Viewer, we encountered many difficulties. Obviously, photos are the most requested feature of Facebook. Every day, our users upload more than 100 million photos, and the functionality designed for this was created quite a long time ago and clearly needed to be improved.
Thanks to the work done, users began to look at 5% more photos, which in quantitative terms means about one billion additional views a day.
')
How did we do itWe started by compiling a list of current issues:
- The biggest problems were reliability. Images loaded slowly, and sometimes the process hung indefinitely. Users had to refresh the page in the browser to see the photos and comments to them.
- When viewing photos from the News Feed, you had to either open them in a new tab, or put up with the fact that after viewing you had to re-scroll the tape down to return to the previous position. For computer-savvy people, this was not a particular problem, but many of our users experienced inconveniences.
- The functionality of viewing comments on photos was also not implemented in the most convenient way. The process looked like this - you had to look at the photo, squander the page down to see the signature and comments to it, and then go back up, and so on each time.
- JavaScript, intended for uploading and caching photos, as well as for posting comments, was also not implemented in the best way. It has remained unchanged for many years, against the background of the fact that browser technologies and requirements for them have significantly advanced.
We were faced with the task of solving the problems described above and, ideally, creating a new, more enjoyable functionality that can combine viewing photos, placing tags for people on them, the ability to comment and mark your favorite photos with "likes."
We identified several design concepts and began to experiment. Almost immediately, we realized that using pop-up windows at the same time solves several tasks we face. The pop-up window allows you to save the current position in the news feed and at the same time can be implemented with a minimum amount of downloaded data.
Initial Concept Photo ViewerGiven that we immediately liked the initial design of the window, it was obvious that there was no room left for a description of the photograph, comments and marks of the people depicted on it. We have refined the window design, increasing its size and increasing the interactivity of its work. In this case, we have provided the ability to view photos in large size, as far as the user's screen resolution allows.
The initial prototype of Photo ViewerThen, based on the results of prototype testing, we made a number of important decisions. First, we found that on a dark background, photos look more colorful and perfectly stand out on the screen. Secondly, by removing the column on the right, we got more free space for the photo itself, which could now occupy the entire width of the page. And finally, it became clear to us that, despite all the advantages provided by the dark background when viewing photos, it is quite difficult to read the captions and comments written on it. Therefore, we settled on a two-color version of the window containing large photographs.
Full-screen version of the Photo Viewer windowSo, we decided on the design and started working on the engineering side of the project. Considering the need to handle large-sized photos, we encountered several significant problems. For example, some photos were too large to fit entirely on small screens. Our task was to save the user from having to scroll through the image in order to see it entirely. In addition, even before starting work on the project, we were faced with the task of resolving the issue of viewing comments on large photos. Thus, we needed to provide free space at the bottom of the photo, which will always be visible on the screen.
As a result, we defined the following criteria for design development:
• At the bottom of the photo there should be at least 100 pixels for captions and comments, which should always be visible on the screen. This meant the need to compress photos in cases where the user's screen has a too low resolution.
• The pop-up window should be on top of the main page and scroll if necessary, but the page itself should remain stationary in the background.
• We had to provide the ability to easily add new features without having to rework the API.
• We decided to refuse to support the new functionality of the browser IE6, if the amount of work and loss of productivity will be too large compared to the benefits of working with this version.
• We had to minimize the use of javascript.
Final Solution: More CSS, a lot less JavaScriptThe final solution was based on the use of CSS capabilities for working with a pop-up window without the need for JavaScript. Let's take a look at the HTML and consider the line by line code used.

- First we need to create a lightbox. By using the root tag with a fixed position,
fbPhotoTheater
, we were able to separate the content from the body
. By setting the root tag width
and height 100%
and setting the overflow
parameter to body
to hidden
, we can scroll the content without changing the page itself in the background. - The
container
element sets the boundaries of the lightbox content horizontally at 960px
and the position of the lightbox in the center of the screen. After adjusting the lightbox structure, the remaining elements are used to correctly position its contents. - The
positioner
element has a height 100%
and a max-height 820px
. Of these, 720 pixels are reserved for the photo itself, and the remaining 100 pixels are used for captions and comments at the bottom of the lightbox. This is achieved by positioning the photoInfoWrapper
at a height of 100 pixels from the bottom positioner
. Thus, it will always abut below the stageWrapper
. - The
stageBackdrop
, stageWrapper
and stageActions
must have the same positioning within the CSS. This ensures their mutual overlap. We give them a max-height 720 px
, top 0
and bottom 100px
. Thanks to this bottom
, we are guaranteed to have 100 pixels at the bottom of the screen for captions, and max-height
keeps the contents of the lightbox to within limits, even for photos that are too long in height. Also for stageWrapper
we set the value text-align:center
so that the photo takes a central position horizontally. - The
stage
element is used to centrally position the photo vertically. This is the only use of JavaScript
in positioning. For the stage
we need to set the line-height
value equal to its height
, due to this, the img child element gets the vertical-align: middle
positioning. It is worth noting the merit of this decision, which is that the calculation needs to be done only once, and not every time the user scrolls through several photos. - For the image itself, the
max-height 100%
so that it always fits within the panel borders. - Finally, for the
photoInfoWrapper
element, which should be under the positioner
element, the relative positioning top: – 100px
. Due to this, the empty interval is filled.
Having finished with the markup, we started to revise the contents of JavaScript. The old version of the functional downloaded photos in packs of 20 pieces, along with captions, comments, etc. with AJAX. As a result, requests took three times longer than if we only loaded photos. By separating the images from the related information, we received an additional performance gain. Now, with each AJAX request, we can load more photos and less related data, optimizing the response time to the request. To ensure maximum speed of loading photos, we track which way the user scrolls them, and load the next 5 photos. Thanks to this, the photos in advance get into the browser's cache, and they are displayed immediately.
When loading data, we separated the information about them from the JavaScript class PhotoTheater. In response to each request for receiving data, an object comes with keys containing the identifiers of the Photo Viewer elements and the HTML code to be inserted into these elements. We implemented a cycle in which we set the content of each element. Thanks to this solution, we can change the design and layout of HTML, without making changes to JavaScript. Finally, in order to maximize the download speed, we attached an HTML5 attribute containing the full version URL to each photo icon. Thus, when a user clicks on an icon, we can get the URL from its attributes and display the first photo without using an AJAX request. Thus, the average load time functionality for viewing photos is now less than half a second.
As a result of our work, we got a solution with a small amount of downloaded data and a high viewing speed. Due to this, we managed to improve the viewing experience and interactivity of the functional. Now users are faced with fewer errors and less likely to see an indicator of waiting for data loading.
We hope that you will get the same great pleasure from working with the new version of Facebook functionality for viewing photos, which we received from its development.
The final version of the functionality for viewing photos.