Tips for performance in your web sites

HTTP

HTTP is a networking protocol for distributed, collaborative, hypermedia information systems and it is also the foundation of data communication for the World Wide Web.

How it works?

You send (using a browser, for example) a request for the server: -Hey Internet, give me the Ruby overview web site.

 

GET /2011/07/11/ruby-overview.html
HTTP/1.1
Host: leandromoreira.com.br
User-Agent: Mozilla/5.0 (s.o.) Gecko/20100101 Firefox/5.0

And server can answer you: – Okay!

HTTP/1.1 200 OK
Content-Type: plaintext/html
Last-Modified: Fri, 15 Jul 2011 00:23:15 GMT
Content-Lenght: 896
blah blah content blah blah ruby blah blah

As you can see HTTP is a protocol where you can request resources for the sever, using some fields. This conversation between you and the server can results in further requests. Using some of HTTP fields, you can request compressed data from server (then use less network load), server can inform you how long you can keep components at cache.

The 14 golden rules

Steve Souders wrote the amazing book (based on his researches on Yahoo!) High Performance Web Sites to help us made more scalable and fast web sites. This book shows fourteen rules at practice to follow and achieve the fast web site, it also presents real web sites examples. I certainly recommended you this book. (Thank Guilherme Motta for this recommendation.)

Rule #01 – Make fewer HTTP requests

Yeah, this rule might be obvious but not so obvious is the possible solutions for that:

  • Use image map and css sprites instead of use multiply images.
  • Hard core -> Sometimes you can use inline images. (it doesn’t work with IE)
  • Combine & Minify your files: three js scripts to only one (with removed spaces and etc.) and nine stylesheets to one. In fact this thing of combine everything into one, broke our so beloved coupling OO rule. I think this combine and minify process should be made on deployment and delivery, this let’s free to create cohese and uncoupled scripts and stylesheets.

Rule #02 – Use Content Delivery Networks

I’ve worked in a company where we have some stylesheets and js shared between the projects. Our approach for that was, each project injects the files in its workspace. This take us to the hell of outdate files.

Thinking in terms of caching, if we had this files into a single known server, all the requests for our several web sites would take advantage of cache.

Taking this for a big picture, I mean dream that we are handling a huge web site, we could also take the advantage of customer’s proximity. If our components are next to our clients so the download time would be decreased.

Rule #03 – Add an Expires Header

In HTTP conversation, the server can tell to a client that certain component could be used at his local cache for a certain time using the HTTP field: Expires. You request a component for server and it answers with that component and give you a valid time for that component. The setup for this is made on server-side. (See also: Max-age and Cache-Control – overcome the limitation of Expires, when you need to specify the exact date, causing clock synchronizing issues. Using Cache-Control you can set time in seconds!)

People, usually, don’t put this because they fear the change. For example: I create a component (company’s logo) and put the expires date to ten days, but if I would change it before that time?! Well, you could starting writing your components with rev. number on its name. The company_logo_1.0.png is cached but your newer version company_logo.1.1.png isn’t.

Rule #04 – Gzip ’em all

Once again, you can inform to server that you understand and accept compressed files (Accept-Encoding: gzip) and maybe server answer you with compressed data. (Content-Enconding: gzip) Using compressing, saves the average of 66% in your network flow, it’s huge and worth to do.

Rule #05 – Stylesheets at top

The history is long (progressive rendering, browser way to render, blank screen when css at bottom) so just follow (and read the book to understand the beginning of this long history) the rule! BTW, by testing, it was proved that use LINK way of include css instead @import is better.

Rule #06 – Scripts at bottom

Again, long history (browser way to understand it, EVEN BLOCK parallel downloads because of scripts and middle of your html) just follow the rule!

Rule #07 – Don’t use CSS expression (okay, avoid)

This rule brings a new concept to me. I didn’t know that we could write css and javascritp into css rules (in this way). For example:

width: expression( document.body.clientWith < 600 ? "600px" : "auto" );

Rule #08 – Make JS & CSS external

Inline vs External -> In raw terms inline is faster. But don’t forget about others rules : compressing, CDN and caching. In general, for real world projects external files always win for performance. (Mainly for users with primed cache, components cached because they’re visited site before)

Rule #09 – Reduce DNS lookups

The roundtrip that one request does to find the it can be a huge time-consuming, so DNS caching would improve a lot your user first visit.

Rule #10 – Minify Javascript

I already cite this but it’s a valid rule, imagine the space you can save and bytes you can save by minifying your js.


myFunction(parameter0, paramenter1){

window.title = parameter0 + parameter1;

}

Works equality as:


myFunction(_0,_1){window.title=_0+_1;}

There is a bunch of minifyers on Internet. And even obsfucators but I don’t think it’s necessary and most of them can introduce bugs. There is also CSS minifyers too: write 10 instead of 10px, #606 instead of #660066.

Rule #14 – Make ajax cacheable

This is, maybe, the most hard rule to explain and apply! Then it’s better read it here.

PS: I skipped the rules 11 (avoid redirects), 12(remove duplicate scripts) and 13 (configure etags) just because they are most known for general people, except ETags but usually the tip is : avoid ETag, so it is.

Oh yes, you can see more rules of high performance at Yahoo! and at Google.com too.

Useful tools to help mensure your site

Today, we fortunately have tools to help us identify and fix performance issues on our web sites. You can simply grab one of that bellow or both and run it on your site. They give you a complete report about the pain points and thing you can do to increase performance. YSlow uses the fourteen rules as basis and Speed Trace is Google tool, it doesn’t need to say anything.

YSlow

YSlow analyzes web pages and suggests ways to improve their performance based on a set of rules for high performance web pages. It can be installed as browser plugin.

Speed Trace

Speed Tracer is a tool to help you identify and fix performance problems in your web applications. It visualizes metrics that are taken from low-level instrumentation points inside of the browser and analyzes them as your application runs. Speed Tracer is available as a Chrome extension and works on all platforms where extensions are currently supported (Windows and Linux).

Ruby overview

Introduction

Take a look at this, there is two classes: a person and a teacher. The person (originally) just know how to speak English and then teacher teach him speak other language, it can show you how powerful and beautiful ruby is.

class Person
 attr_accessor :name
 def speak_english
  puts "Hi people!"
 end
end

class BrPortugueseTeacher
 def teach(person)
  def person.speak_portuguese
   puts "Ola pessoal!"
  end
 end
end

bill_gates = Person.new
bill_gates.nome = "Bill Gates"
pasquale = Teacher.new
pasquale.teach bill_gates
#now bill gates knows portuguese
bill_gates.speak_portuguese

The intent here is just show a quick overview of ruby from a newbie.

Code’s comment

#one line comment
=begin
Multiply lines comment.
Given that ...
=end

String

String in ruby is mutable (but when you use the operator method + it creates another string, so to concatenate strings you should use the operator <<) and just a little tip avoid the concatenation by using + instead prefer use interpolation, a way to handle string very similar to expression language, and it’s faster than normal concatenation.

ran = 34434
who = "Leandro Moreira"
puts "#{who} generates this #{ran} number"

Conventions

Yet on mutability, when you write a method that can affect the internal state, you should use the bang operator (!) on method’s name.

old_source_name = "angeline"
puts old_source_name.capitalize
puts old_source_name.capitalize!

Another cool convention to Boolean methods is end them with ?

if account.cancelled?
 puts "Run Forest, run!"
end

Range object

In ruby you can use a type Range to describe ranges and its use is very easy.

zero_to_ten = (0..10) #inclusive
one_to_seven = (0...8) #exclusive
alphabetic = ('a'..'z') #you also can omit the (

It’s all object and quick tips

– Hey, language prints I win three times.

puts "I win " * 3

You can use anything on if statement and it can ben true or false (and nil which is false too).

A weird thing is one way of handle the regular expressions.

/myexp/ =~ "sentence"
#"sentence" matches myexp?

Another weird operator is or equals.

list ||= flights
#the list will just receive the flights if list is nil.

The classes are really open

One of the main features of ruby is Open Class, this is cool, you just can grab a class and write a new feature for it.

class String
 def do_nothing
  puts "doing nothig"
 end
end

And then you just call it.

"number".do_nothing

Let’s trick the addition operations on number.

class Fixnum
 def +(other)
  self - other
 end
end
puts 2+1
#and it will prints 1. (~:

Variable arguments

Sometimes you need to use this kind of flexibility.

user.buy computer
user.buy computer, mouse, monitor

To achieve this you just use the syntax. The splat operator how it is known.

def buy(*products)
 #buy logic
end

Hash enhancements

There is a lot of people which claims to use hash as parameter.

e_account.transfer :to_account => my, :value => 4800

def transfer (parameters)
 dest_account = parameters[:to_account]
 #...
end

Declarations

class Anything
 @field #object field
 @@field #class field
end

Singleton in Ruby

Singleton pattern is a design pattern used to implement the mathematical concept of a singleton, by restricting the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects (say, five). Some consider it an anti-pattern, judging that it is overused, introduces unnecessary limitations in situations where a sole instance of a class is not actually required, and introduces global state into an application.  (From wikipedia)

class HyperDao
@@instance = HyperDao.new
def self.instance
return @@instance
end
private_class_method :new
end

But we’re talking about ruby, don’t we?

require 'singleton'
class God
include Singleton
end

It’s done! 😀

Equals

If you want or need to rewrite the equals…

def ==(other)
 self.id = other.id
end

Duck typing – good-bye interface

Duck typing is a style of dynamic typing in which an object’s current set of methods and properties determines the valid semantics, rather than its inheritance from a particular class or implementation of a specific interface. The name of the concept refers to the duck test, attributed to James Whitcomb Riley (see History below), which may be phrased as follows:”When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck.” (From Wikipedia)

class PremiumAccount
 def saldo
   #
 end
end

class CommonAccount
 def saldo
  #
 end
end

The bank manager will accept that.

class BankManager
 def total_debt(accounts)
  for account in accounts do
   debt += account.saldo
  end
 end
end

Mixin

Mixin is a class that provides a certain functionality to be inherited or just reused by a subclass, while not meant for instantiation (the generation of objects of that class). Inheriting from a mixin is not a form of specialization but is rather a means of collecting functionality. A class may inherit most or all of its functionality from one or more mixins through multiple inheritance. (Again, from Wikipedia)

module Logging
 def log(message)
  puts message
 end
end

class Anything
 include Logging
  #...
end

any = Anything.new
any.log "It started now!"

Metaprogramming

Metaprogramming is the writing of computer programs that write or manipulate other programs (or themselves) as their data, or that do part of the work at compile time that would otherwise be done at runtime. In many cases, this allows programmers to get more done in the same amount of time as they would take to write all the code manually, or it gives programs greater flexibility to efficiently handle new situations without recompilation.

class Person
 attr_accessor :name
 def speak_english
  puts "Hi people!"
 end
end

class BrPortugueseTeacher
 def teach(person)
  def person.speak_portuguese
   puts "Ola pessoal!"
  end
 end
end

bill_gates = Person.new
bill_gates.nome = "Bill Gates"
pasquale = Teacher.new
pasquale.teach bill_gates
#now bill gates knows portuguese
bill_gates.speak_portuguese

Highly influenced by ruby on rails from Caelum.

Acceptance testing on Fitnesse using slim test system

What is Fitnesse?

  • It’s a software development collaboration tool.
  • It’s a software testing tool.
  • It’s a wiki.
  • It’s a web server.

This tool provides a way for the BA’s and/or customers write their acceptance testing on wikis and better than this, they can run theirs tests and see if it fails or pass right on the page. Install Fitnesse it’s very simple, you just download and execute. The fitnesse architecture provides two types of test system: slim and the well-known fit. For this tutorial I’ll use the slim.

The hands-on

Scenario: Given that I have the input1 and input2 Then the output Should Be input1 plus space input2. So let’s express the acceptance testing of this feature (or behavior if you want). In Fitnesse we can express this using the decision table, others examples of places to write tests are query table, script table, library table and etc.

|it should print guaqmire|
|input1|input2|output?|
|you|are|you are|
|family|guy|family guy|
|tests|enough|tests enough|

Explaining the table, the first line is the name of the fixture, the second line contains the inputs and outputs names and from the third line on it’s filled with testing data. The output table should look like this:
Let’s setup the wiki-page to it became runnable, edit the page and put these parameters on the page.

!define TEST_SYSTEM {slim}
!define TEST_RUNNER {C:\fit\slim\rubyslim\lib\run_ruby_slim.rb}
!define PATH_SEPARATOR { -I }
!define COMMAND_PATTERN {ruby -I %p %m}
!path C:\fit\slim\rubyslim\lib\
!path C:\fit\ruby\prj\

The first line is setting TEST_SYSTEM to configure fitnesse to use the slim protocol instead of default fit. As we will use slim and ruby, we’ll use the rubyslim library. The second line is setting the TEST_RUNNER to use the ruby slim. Third line defines the PATH_SEPARATOR, used by the COMMAND_PATTERN to separate paths. The fourth line is configuring the COMMAND_PATTERN that will execute the test itself, the two parameters %p (receives all the paths from the page and its ancestors) and %m (the fixture itself) are used to correctly perform the test. The lines with path just informs to fitnesse where it can found the libraries and the runtime files.

And now you can run, is it fails? Good, now let’s programming it in ruby, if you are a newbie ruby as me, your code might be something like this.

module Fixtures
  class ItShouldPrintGuaqmire
   def set_input1 input1
    @input1 = input1
   end
   def set_input2 input2
    @input2 = input2
   end
   def output
    "#{@input1} #{@input2}"
   end
  end
end

Ohh it continues to fail, shame on me. As you can see at the code, I put the fixture inside a module called Fixture, so we need to inform the fitness what module/package is my fixture and we can do that by a table.

|Import|
|Fixtures|

This special table only  configures where is the fixtures. Now let’s see the entire code for fitnesse wiki.

!define TEST_SYSTEM {slim}
!define TEST_RUNNER {C:\fit\slim\rubyslim\lib\run_ruby_slim.rb}
!define PATH_SEPARATOR { -I }
!define COMMAND_PATTERN {ruby -I %p %m}
!path C:\fit\slim\rubyslim\lib\
!path C:\fit\ruby\prj\

|Import|
|Fixtures|

|it should print guaqmire|
|input1|input2|output?|
|you|are|you are|
|family|guy|family guy|
|tests|enough|tests enough|

Running the tests should show

Bonus round – Fitnesse using slim protocol in Java

In fact to make it runnable in Java it’s easier, you don’t need any TEST_RUNNER or COMMAND_PATTERN in your wiki page, since Java it’s default for fitnesse and your final wiki should look like this:

!define TEST_SYSTEM {slim}
!path C:\fit\java\prj\fit-slim-java.jar

|Import|
|br.com.leandromoreira.fixtures|

|it should print guaqmire|
|input1|input2|output?|
|you|are|you are|
|family|guy|family guy|
|tests|enough|tests enough|

And your Java code can be something like this:

package br.com.leandromoreira.fixtures;

public class ItShouldPrintGuaqmire{
  private String input1;
  private String input2;
  public void setInput1(final String i1){
   input1 = i1;
  }
  public void setInput2(final String i2){
   input2 = i2;
  }
  public String output(){
   return input1 + " " + input2;
  }
}

Real world

Usually the real world projects requires a lots of libraries on path, setup pages and more than just decision table to write tests. For instance, you can see that use fitnesse with slim seems more portable , less coupled with runtime and easier to implement too. In the real world you also create wiki for the project and suite test page for stories and organize all your imports and configs on project level, when you are composing a wiki on fitnesse you can take advantage of the fact that all the pages extend the configs from theirs ancestors, so you can have a better project wiki and managable test suite pages.

Update – Issues with Ruby 1.9.x

If you are trying to use the ruby 1.9.x you will have some issues the first one is: require ‘jcode’ issue, I tried to solve it but then it started to show another error list_deserializer.rb:1:in `<‘: comparison of String with Float failed (ArgumentError)’.  Since I’m not (still) a ruby guy I don’t know how to fix it.

Thoughtworks Brazil – POA

Thoughtworks logo
Now it’s official, I’m working on ThoughtWorks – a global IT consultancy which focuses on agile software development, has contributed to a range of open source products, including CruiseControl, NUnit 2.0, and Selenium. My last work was at Sefaz-GO, a government agency which mainly takes care of state tax system. I left too many friends there but this opportunity cames to me and I need to move on, I mean, literally move, from GYN to POA, that’s the worst part to me. Soon I’ll posting more about this new position in my career. Ohhh and like any new thing on life, I have my hopes: increase my knowledge, to know more cultures, apply agile with some of the creators and learn with amazing twkrs. And all this started around four months ago. I’m happy! 😀

For those are feeling lost please read thoughtworks at Brazil  and remember we’re continue hiring people.

ThoughtWorks Brazilian hiring process

The hiring process

My intend here is to explain my personal view of the hiring process (which I was submitted) of Brazilian ThoughtWorks. In fact the ThoughtWorks hiring process is already explained, see a brief view of it:

“Hiring is our signature process, so as you might expect, we’ve thought hard about how we access your suitability for a career with us. We believe we’ve created a process that is fun, that shows you what being a ThoughtWorker is all about and challenges your abilities. Many hiring processes consist of a couple of interviews and perhaps a chance to meet your new boss. We reject that. We want to find out what work environment suits you, what you value and how you do your job, so we don’t just sit and ask you questions. We get you to show us what you can do.”

The steps (Dev role)

The TW talent scout sent me a message telling me about the open positions at TW (Porto Alegre) and then I answer her asking how to apply, she informed everything I need to do. Then I’ve applied to dev position (03/20/2011) and the First Step: a informal phone interview, that first interview it’s very easy and weightless 🙂 just to know you a little bit. The Informal Phone Interview is designed to help tw get to know each other beyond CVs and web pages.

Second Step was the code submission: they will send you two problems, you must choose only one, to solve. On this part they are trying to access a number of things, these include the design aspect of your solution, but mostly we are looking for good coding practices and your object-oriented programming skills. Good tip here is: use your primary programming language (I do love and want to learn ruby but Java was my main tool that moment).

Then if you have passed on this phase you will be on Third Step: the tech phone interview that consists of one ThoughtWorker interviewing you more technically, in my case Rodrigo Wolschick (A.K.A. Patrola) did the interview and despite his nickname he was fine with me.

So after that you will be on Fourth Step: Office Interview (here the real fun will start), they ask me to schedule two days to be at office. At the office you will pass through several interviews (culture values, programming pairing…) and logical assessments, I can tell you it’s very tiring BUT IT’S SURPRISINGLY FUN. After this long process I started to work at June 21.

PS: I should write this before I’ve posted ThoughtWorks POA.

Ohh, one last note we’re hiring, so if you are interested :

Open positions at ThoughtWorks Brazil