Showing posts with label web. Show all posts
Showing posts with label web. Show all posts

Saturday, 2 March 2013

The only bad thing about Mason

At the moment, I'm writing a presentation about Mason2. The goal is to somehow convince my colleagues to consider using Mason. Instead of Template Toolkit.
As part of it, I thought I'd do a bit of performance benchmarking against Template Toolkit. So I put together a reasonably complex mini set of templates using both systems. Well, as complex as TT can take in reality. Which is not very much.

But anyway, let's jump straight to the bad news.

        Rate Mason    TT
Mason  901/s    --  -51%
TT    1852/s  106%    --


As you can see, with similar settings (code caching enabled) and over 10000 runs of two pages, Mason2 is twice as slow as Template Toolkit. Mason2 is still below the millisecond per page in my benchmark, but still that's quite a big difference.

As the common wisdom goes, CPU time is cheaper than programmer time, so it shouldn't be a big deal, given the huge gains of productivity you should get by using Mason2's very cool and powerful features.

Stay tuned for the full presentation to come!

PS: To follow up on the comments, feel free to have a look at the benchmark source https://bitbucket.org/jeteve/mason-pres/

J. 

Friday, 23 November 2012

Friday Time Waster: Watch the world go by in ASCII with Reuters' API

I've recently released WebService::ReutersConnect. It's a Perl modules that interfaces with the ReutersConnect's API in OO style. To demonstrate it and hopefully entertain you on this Friday, here's how to use it to watch the world go by in glorious ASCII and from the comfort of your command line. To put it shorter: The perfect Friday Time Waster.

The ingredients

To cook this recipe, you will need:



While you can install all of this with the CPAN command, I suggest you install most of their dependencies through your OS packaging system first.
If you're debian based, here are the debs to install: libmoose-perl libdatetime-perl libdatetime-format-iso8601-perl libtest-fatal-perl libxml-libxml-perl libwww-perl liblog-log4perl-perl liburi-perl liblibaa1-dev

Then just install WebService::ReutersConnect and  Text::AAlib via your favourite channel.

The Recipe

The Recipe is pretty straight forward, it goes like this:

Preamble. We just load the required packages and also make sure that Log4perl is not going to complain about lack of initialisation:

#! /usr/bin/perl -w                                                                                                                                                                             
use strict;
use warnings;
use WebService::ReutersConnect qw/:demo/;
use Log::Log4perl qw/:easy/;
use Text::AAlib;
use Imager;
Log::Log4perl->easy_init($WARN);

Building the $reuters object and querying the freshest image. Here we use the demo credentials and search for the latest picture:

my $reuters = WebService::ReutersConnect
 ->new({ username => REUTERS_DEMOUSER,
         password => REUTERS_DEMOPASSWORD
      });
my ( $item )  = $reuters
            ->fetch_search({ limit => 1,
                             media_types => [ 'P' ],
                             sort => 'date' });

Building the ASCII of the picture. We just download the preview URL and render it in ASCII using Text::AAlib:

## Load preview image                                                                                                                                                                              
my $res = $reuters->user_agent->get($item->preview_url());
unless( $res->is_success() ){
  die $res->status_line();
}

## Build and scale image                                                                                                                                                                           
my $bin_image = $res->content();
my $img = Imager->new( data => $bin_image , type => 'jpeg' ) || die Imager->errstr();
$img = $img->convert( preset => 'grey' );
$img = $img->scaleX(scalefactor => 2); ## Tweak to your taste
$img = $img->scale(scalefactor => 0.5); ## Tweak to your taste


## Build ASCII Version                                                                                                                                                                             
my ($width, $height) = ($img->getwidth, $img->getheight);
my $aa = Text::AAlib->new( width  => $width, height => $height );

Rendering the whole thing on the console. The rendering parameters are OK for me, but you might have to play with them depending on your taste/colour scheme:

## Print ASCII Image                                                                                                                                                                               
print $aa->render( dither => 0 ,
                   gamma => 1.83,
                   bright => 50,
                   contrast => 60,
                   color => 0
                 );

## And some info                                                                                                                                                                                   
print "\n    ".$item->date_created().' : '.$item->headline()." \n";
print "\n    ".$item->preview_url()."\n";

And that's it! Now you can put all of that together, or if you're lazy, you can just copy/paste the whole thing from this pastebin. 

Feel free to experiment with the options and the code and tell us about your improvement in the comments!

Happy coding!

Jerome.

Saturday, 15 September 2012

JS/HTML/CSS: A braindump from a backend guy

It's a wonderful sunny Saturday outside yet I'm here bloging about web development. I should see a doctor, but in the meantime please suffer my brain dump about things browser related.

I'm not really a front end developer, in the sense that I have very poor graphic design skills, that my knowledge of Javascript and CSS is limited. However over the time I had my fair bit of front end development, more recently here, not counting the things I do for fun, so yeah, I don't have expert level knowledge about all of this, but I feel I have enough experience to broadly think about some general guidelines about what should be fed to the browsers. So the goal of this post is not to dictate what I think is right, but rather to put some ideas on the table and calling for critics and alternative and/or improvement suggestion. So if you're a JS Ninja, or a CSS old-master, please be indulgent, and share your art in the comment.

Ok let's get started with the general page structure. I like a page source to be clean and organised (not like my bedroom), but also the goal here is to allow the browser to render the page as soon as possible. In other words, to reduce the time to first pixel:

<html>
  <head>
      <title>My Wonderful Page</title>
      <meta name="description" content="Some meaningful and reasonably long description">
      <script type="text/javascript" src="/js/head.js"></script>
      <link type="text/css" rel="stylesheet" href="/one/css/file.css" />
      
  </head>
  <body>
     <div>
         All sorts of HTML stuff.
     </div>

     <script type="text/javascript">
        
     head.js('https://ajax.googleapis.com/.../jquery.min.js',
                 'https://ajax.googleapis.com/../jquery-ui.min.js',
                 'http://mysite.com/js/site.js'
                );
    head.ready(function(){
      installFancyJS($(document));
    });
     </script>
   </body>
</html>

Let's go though this step by step.

Use a JS Loader. So the idea here is to do as little as possible in the header, and deport the heavy lifting to the end of the body. In your header, you should have only one and only one minimal script, and this script should allow you to load things later at your page bottom. Here I use head.js. It's got other fancy base features but load.js is also a good alternative if you like to make it even smaller. Let your page be pear shaped.

One CSS File. Not two, not three. One, and preferably on the same domain as your main site (so relative URLs are welcome here). Why is that? Here we reduce the number of extra requests the browser has to do to a minimum of erm ... one, and by having the CSS hosted on the same hostname, you avoid doing extra DNS queries, saving you precious milliseconds. Some people even argue that you should have your CSS in the page itself. I'm not sure about this one. It's true that it saves you the extra query entirely, but at the same time, your page is now heavier and therefore longer to download. There's probably a reasonable limit under which this actually saves time, but I'm not sure about its value. Of course in the development environment, you probably want to have your css neatly organized, so you don't have a giant ball of spaghetti monster to deal with. I've tried different techniques to achieve that, but didn't come with something I really like yet. Suggestions?

All sorts of HTML Stuff. Warning. Controversial bit. What? HTML stuff, controversial? Well yes, as it seems to me that with the advent of the uber-ubiquitous Ajax coolness, a large amount of people chose to ignore a fundamental fact of life (at least of life as a developer): Browsers were born to render HTML and dynamic web servers can generate HTML. For instance, I know a site where every time they need to display a table of something (let's say historical stock prices), they first display an empty table, and then, when all the page JavaScript is loaded, they make a second query to get the data to populate the table. It drives me mad. Not only I don't see the point* , but more importantly, you can imagine how it kills the 'time to useful pixel' of their pages. It's not that I'm against Ajax. not at all. I love it, I was doing it wayyyy before jQuery became popular. In fact you'll find here some posts I wrote about how to easily 'ajax' anything. But I kind of believe that if you want to do JS object models and get JSON from the server instead of HTML, you'll be much better off developing your backend as an API and generate your GUI using something like flex, or GWTK (please add yours to the list :)). I certainly reckon the incredible value and power of OO JS/Json for complex and specific information manipulation and display (down with flash and applets!!), but for general pages development, I prefer to stick with good old HTML, specially if the application is 'browsing' oriented.

One JS Function that does it all. I call it (observe my creative naming skills) 'installFancyJS', and it takes one argument: the jQuery** context it's going to used in. So what does this function do? Well, it installs callbacks and all sort of responsive code in the page just after it's loaded. More precisely in the given context. To give you a very minimal example:

function installFancyJS(context){
    installTopClick(context);
    ....
}
function installTopClick(context){
    $('div#topbar' , context).on('click', function(ev){
        $('html,body').animate({scrollTop: 0 },
                               { duration: 'slow', easing: 'swing'}
                              );
    });
}

The reason why I propagate the context everywhere is that when I get a new bit of HTML using Ajax, I want to be able to install the full set of Javascript features on the newly created slice of document. In here's an minimal example of Ajax callback that uses the function:

function(data){
                  var newbit = $(data);
                  container.replaceWith(newbit);
                  // install fancy js on the container's new content.                                                        
                  installFancyJS(container);
              }


That's is for now. I hope you enjoyed reading this and found some interesting/ridiculous/horrible things to talk about.

Jerome.




* But I see the reason: they got tied to the horrible datatables.net.
**yes I use jQuery, please rant and suggest in the comments if you know a better one.

Saturday, 2 April 2011

Implement Ajax actions using page slices [Part 2]

Last time I discussed how to implement Ajax browsing using page slices] generated
at server side. If you haven't read that yet, I strongly encourage you to do so, cause there's little chance the rest of this post will make sense to you.

Read Part 1- Implement Ajax browsing using page slices.

This time we're going to apply the same technique, but we'll implement some actions. By actions I mean simple interactions for instance 'vote a comment up', or 'follow a member', 'delete an item' etc.. Any kind of interaction that does not require more than a click from the user in an Ajax interface.

For instance, on libsquare.net, if you are logged in, you can vote up or down any review that appear on the jQuery page:

So how do we implement that?

The pure HTML flow

First let's remember that page slicing is designed to allow us to implement things without JavaScript, so let's just do that. Here's the work flow of the vote up feature without any JavaScript:

The user clicks on vote up, he arrives on a page where the vote up is pre-selected, clicks submit and is redirected to the page review with the vote count updated.

Let's Ajax this!

First let's give a class 'do_vote_up' to our vote up link:

<a href=".../review/111/vote_up" class="do_vote_up">Vote up</a>

Then we need to give an ID and slice the container that contains the voting unit:

<div class="slice_container" id="review_vote_111">
<& /slice.mas , id => 'review_vote_111' &>
 ... Your vote display html code ...
<a href=".../review/111/vote_up" class="do_vote_up">Vote up</a>
 ...
</&>
</div>

Let's assume /review/111 is a page that always display the review with it's voting part.

Now we're only a small bit of Javascript away from the full Ajaxed feature:

$('a.do_vote_up').live('click', function(event){
  event.preventDefault();
  var a = $(event.target);
  var container = a.closest('.slice_container');
  var target_url = a.attr('href');
  var result_url = target_url; result_url.replace('\/vote_up','');
  // Post a vote up query to the voting URL.
  $.ajax({
    type: 'POST',
    url: target_url,
    data: { vote: 1 , vote_submit : 1 },
    success: function(){
       // On success, reload the voting slice that now contains the updated vote.
       container.load(result_url,{ page_slice: container.attr('id') });
    }
  });
});

Et voila, the vote up action is now Ajaxed. Implementing the same thing for the vote down is left as an exercise for the reader :P

Next time I'll be speaking about submitting forms and dealing with redirections in Ajax. Stay tuned and thanks for reading!

Monday, 21 February 2011

Slice your HTML to Ajax anything. [Part 1]

There's roughly two ways of addressing Ajax on your website:
  • Designing your pages with Ajax in mind. This usually means you'll have a  growing number of features that require JavaScript to work. The W3C recommendation specifies that you should provide JavaScript-less versions of your features. So it means you will have to develop your features twice to maintain accessibility. Sounds a painful thing to do.
  • Designing your pages without Ajax in mind. This means you design only good old pure html/params & forms techniques to animate your features. This is good for accessibility, this is good for testability, this is good for search engines because all your features are accessible via plain links. The only problem is... well there's no Ajax coolness.
But we're going to fix that, and it's not going to be painful at all providing you:
  • have got zero business logic in your rendering layer. Meaning each part of it is idempotent. This is hopefully the case when you use a MVC model for your application.
  • use a rendering layer that's capable of manipulating its buffer, and renders the whole page in this buffer before sending it.
For this post, I'll be using Catalyst as the MVC and HTML::Mason as the View layer. We'll focus on implementing Ajax results paging. (Other ajax aspects will be dealt with in later posts).


Principle of ajax page slices.

The idea of page slices came to me when I was looking at jQuery's load function. It's got a very convenient trick called 'load page fragments' that allows you to do stuff like:

$('#container').load('page_url?offset=2 #result_id');

It will look for an element having the id 'result_id' in the returned document and replace the content of #container with it. Here's a full example of html/javascript that implements this:

<div class="container">
 <div class="result" id="result_id">
   <p>This is page 1</p>
   <p>item 1</p>
   <p>item 2</p>
   <a class="page" href="page_url?page=2">Go to page 2</a>
 </div>
</div>
<script>
 $(document).ready(function(){
    $('a.page').live('click',function(e){
        var a = $(e.target);
        var result = a.closest('.result');
        var container = result.closest('.container');
        container.load(a.attr('href') + ' #' + result.attr('id'));
    });
 });
</script>

This does the trick on the client size but it doesn't save much time on the server side.
Plus it requires DOM parsing of the whole document to find the result_id element. Altogether, chances are that your ajax paging will be slower that a simple whole page reload. To fix that, we're going make the server output only the required slice for us.

Let the server do the work.

First let's have a look first at the intended client side code:

<div class="container" id="result_id">
<!-- This is the slice 'result_id' -->
  <p>This is page 1</p>
  <p>item 1</p>
  <p>item 2</p>
  <a class="page" href="page_url?page=2">Go to page 2</a>
<!-- End of slice -->
</div>
<script>
 $(document).ready(function(){
    $('a.page').live('click',function(e){
        var a = $(e.target);
        var container = result.closest('.container');
        container.load(a.attr('href'), { page_slice: container.attr('id') });
    });
 });
</script>

On the server side, we need a technique to output only the required slice, discarding any previously generated HTML, and aborting the rendering so no more subsequent HMTL is rendered. In Mason, this is easily done by implementing a content wrapping component.
Here's how it looks in under Catalyst (the $c bit):

Component page_slice.mas:
<%args>
 $slice_id 
</%args>
<%init>
  my $requested_slice = $c->req->param('page_slice');
  if( ( $requested_slice // '' ) eq $slice_id ){
    # Discard any previously generated content,
    # output the content and finish rendering
    $m->clear_buffer();
    $m->out_method->($m->content);
    $m->abort();
 }else{
    # This component is transparent
    $m->out_method->($m->content);
 }
</%init>

Here's how to use this component in your page.mas:

% deal with param('page') to compute results and next page.
<div class="container" id="result_id">
 <&| /page_slice.mas , slice_id => 'result_id' &>
  <!-- This is the slice 'result_id' -->
% # Output the right results
% ...
  <a class="page" href="page_url?page=<% $next_page %>">Go to page <% $next_page %></a>
  <!-- End of slice -->
 </&>
</div>
<script>
 $(document).ready(function(){
    $('a.page').live('click',function(e){
        var a = $(e.target);
        var container = result.closest('.container');
        // Use the container ID as the slice ID.
        container.load(a.attr('href'), { page_slice: container.attr('id') });
    });
 });
</script>


When clicking a '.page' link, a request will be sent with the param 'page_slice'. Thanks to this, the component page_slice.mas will output only the requested page slice, and this will populate the container.

Your paging will obviously works without JavaScript. There's no Ajax specific code at server side. This is:
  • Good for accessibility. Try using your paging with lynx. It just works.
  • Good for SEO. Our beloved search engines will crawl these links, even if they don't do Ajax.
  • Good for testing. Because Ajax is not needed to use your application, you can easily unit test your features from your web test suite.
  • Good for reliability. If for some reason your JavaScript is broken, the feature will still be available.
Of course this technique can be applied to any kind of browsing features: sorting, faceting etc..
Next time we'll discuss performing an action in Ajax, and managing Ajax redirections.

I hope you enjoyed this post, thanks for reading!

Thursday, 6 January 2011

Perl: Avoiding the HTML::Mason/TemplateToolkit schism

As a Perl web developer, I've been using HTML::Mason intensely for many projects. Over the past year, I've also been working with Template Toolkit as a rendering layer for a web application.

As always, choosing between two similar technologies seems to be mainly a matter of taste and yet another occasion for an holy war. To pacify the situation, let's try to figure out what are these beasts good at.

TT feels more simple.

Consider the following code:

[% IF customer.is_in('GB') %]
We'll ship your order by Royal Mail
[% ELSE %]
Sorry [% customer.firstname %], delivery will take a while.
[% END %]

It's much easier to understand for a non-programmer than the Mason equivalent:

% if ( $customer->is_in('GB') ) {
We'll ship your order by Royal Mail
% } else {
Sorry <% $customer->firstname() %> ...
% }

So here clearly, TT wins, although as a programmer, and specially as a Perl programmer, Mason also feels just fine. However, a designer or a configuration person will feel more at home with TT, as it resembles infamous visual basic excel macros.

Mason simplifies page composition.

Let's implement a set of pages, each with a specific title and content, but with the same structure (here just a navigation box). In fact the common bread of web development

Let's do it in HTML::Mason:

autohandler:
<html>
 <head>
  <title><& SELF:title &></title>
 </head>
 <body>
  <div id="nav_box">...</div>
  <div id="payload">
% $m->call_next();
  </div>
 </body>
</html>
<%method title>A default title</%method>

content1.html:
  <p>content 1</p>
  <%method title>Page Content 1</%method>

content2.html
  <p>content 2</p>
  <%method title>Page Content 2</%method>

etc..

Now let's do it TT:

page:
<html>
 <head>
   <title>[% title || 'A default title' %]</title>
 </head>
 <body>
 <div id="nav_box">...</div>
 <div id="payload">
  [% content %]
 </div>
 </body>
</html>

content1.html:
[%WRAPPER page
          title = 'Page content 1'
%]
 <p>content 1</p>
[%END%]

content2.html:

[%WRAPPER page
          title = 'Page content 2'
%]
 <p>content 2</p>
[%END%]


From a programmer's point of view, HTML::Mason wins, as its inheritance mechanism allows much better simplicity, elegance and flexibility in page composition. In this example, I only considered a simple example that's possible to implement both in Mason and in TT, but for more advance use, the inheritance mechanisms (with call to PARENT (super) methods), and other Mason-isms largely beat the TT WRAPPER directive.

❧

From these two simple examples, it appears that HTML::Mason has got much more to offer to programmers, as it allows them to use Perl natively, use a fairly complete inheritance mechanism, and much more. On the other hand, what TT has to offer is definitely an easier and simpler solution for simple templating jobs.

To sum up:

- Use Mason where you need elegance and simplicity to build complex things.

- Use TT where the 'easier than Perl' feel is important, with a restricted set of directive to build simple things.