Organizing composable Play apps with Flexbox

Yevgeniy Brikman made a awesome presentation about how Linkedin solved its problems to build complex web pages. The basic problem is that, for instance, your profile’s page is too complex and keep one single file like a jsp, to build all this html, is not maintainable. Obviously, we are thinking in a long running app.
There are a lot of objects that have to be loaded to create that page. For example:

  • Basic information like: name, current company, etc.
  • Background information
  • Skills and Endorsements
  • Education
  • People also viewed

This is a major problem for all big web sites and each one has its own version of solution. A lot of them, load the snippets of page from iframes and with this, they can load these pieces from everywhere they want… Another approach is when the server sends a almost blank page and every snippet is loaded from ajax calls. Both approaches solve the problem but it delegates a lot of responsibility to the browser.

The third possibility, which is more difficult, would be load all snippets in your server side and glue them to build the requested page. Using this approach, even in a synchronous way, you would have just small pages that are more testable, easier to maintain and would send to browser just a simple html. Facebook engineers wrote about that in this amazing post.

Linkedin guys used this same approach to change the way them build web pages. They used Play’s API to fetch small pieces of html and aggregate these snippets to compose the page. But if you remember, Play is all about async and streaming data. So Linkedin went ahead and used this power to fetch all pagelets in async way, using the Promise’s API provided by Play. Now, and if the last Promise completes its job before the first one, what your controller would have to do? Wait for the first? The answer is no! If you have a partial of your html, just send to the browser :). To accomplish this task, they used the Iteratee and Enumerator API to stream each html partial as soon as it is available. This project is hosted on github(link aqui) and I advise you to take a serious look!.

Everything is really cool until now, but how they organize all pagelets to build the page? I mean, there is a order between Background information’s block and Education’s block . They solved this using a simple Javascript snippet inside pagelet’s template. Take a look:

    @(contents: Html, id: String)

    <script type="text/html-stream" id="@id-contents">
      @contents
    </script>

    <script type="text/javascript">
      document.getElementById("@id").innerHTML = document.getElementById("@id-contents").innerHTML;
    </script>

Each pagelet knows what is its id in the main template. So, it is used javascript to put the returned html in the correct place, smart :). Talking with @sergio_caelum and @srsaude, masters in frontend topic, they warned me about the high cost that is to use innerHtml in your browser. Especially if you have to use it a lot of times! So they proposed to me that would be interesting if the Linkedin had used the Flexbox property in CSS3. This property, allows you rearrange every element in your page with CSS, no Javascript is needed. I liked the idea so I forked the code and I made this little change.

Now, each snippet has its own div and I just have to define the appearance order in the CSS file :).

    @(wvypCount: Int, searchCount: Int)

    <div class="wvyp">
      <h2>Who's Viewed Your Profile</h2>

      @views.html.wvyp.wvypCount(wvypCount)
      @views.html.wvyp.searchCount(searchCount)
    </div>

And now the css code:

    .wvyp {
    	display: -webkit-flex;
    	display: flex;
    	-webkit-flex-flow: column;
    	 flex-flow: column;
    }

    .wvyp .wvyp-count {
    	color: #0077b5;
    	-webkit-order: 1;
    	 order: 1;
    }

    .wvyp .search-count {
    	color: #333;
    	-webkit-order: 2;
    	order: 2;
    }

Now, I can even delete the pagelet template file :). This changed version is in my repository, go there and take a look!.

I really like this idea and I wish to have a chance to apply this solution in one of the systems that I am helping to build. What did you think? I had to write this post because this presentation is one of the best that I ever saw :). I don’t remember when I spent 50 minutes watching a video!

 

 

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s