Gravatar

Geoff Evason

Posts Tagged ‘tech’

Keeping Up With The Jones.com (Some online competitive analysis tools)

Monday, March 17th, 2008

It’s always good to know what your competition is up to, so naturally, if they have blogs, you should subscribe.

A few other useful tools:

Traffic Stats:

I’ve found 3 good tools that track traffic. None of theme seem to be overly accurate for small sites. Even for medium sites the numbers often don’t match the truth. (Comparing visitor stats from google analytics vs these tools shows a very significant underestimation for me). I know these stats sites track mostly US visits, but even taking into account that they seem to underestimate. I use them with the hop that they equally underestimate everyone.

Here are 3 sites that I use to check stats:

Alexa: (often said to be inaccurate by techcrunch)

http://www.alexa.com/search?q=www.momentville.com

Quantcast: (They do a good job of providing more info about the type of visits)

http://www.quantcast.com/momentville.com

Compete: (they have pretty graphs that let you compareup to 5 websites at a time)

http://siteanalytics.compete.com/momentville.com/

Simple Javascript to detect browser details

Monday, March 10th, 2008

Sometimes users of MomentVille will report a problem. It may be a javascript or css problem. Often, the first bit of info I need to find out is what browser they are using, and what their screen resolution is.

I thought it might be too tricky to get them to give me these details reliably, so I made a simple page that gives me the details I want. I just ask them to go to that page and copy and paste the text in an email. (Fortunately I don’t have to use it too often, but when I do it makes things easy).

The file looks as follows:


<html>
 <head>
  <title>Browser Check</title>
 </head>
 <body>
  <h3> Browser Info </h3>
  <br>
<script language="JavaScript" type="text/javascript">
<!--
document.write("navigator.appName " + navigator.appName + "<BR>");
document.write("navigator.userAgent " + navigator.userAgent + "<BR>");
document.write("navigator.appVersion " + navigator.appVersion + "<BR>");
//-->
</script>
  <h3> Resolution Info </h3>
<script language="JavaScript" type="text/javascript">
<!--
document.write("screen.width " + screen.width + "<BR>");
document.write("screen.height " + screen.height + "<BR>");
document.write("document.body.clientWidth" + document.body.clientWidth + "<BR>");
document.write("document.body.clientHeight" + document.body.clientHeight + "<BR>");
//-->
</script>
</body>
</html>

To see it in action check out: http://www.momentville.com/check_browser.html

CSS For Sliding Door Input Buttons In Rails

Tuesday, February 26th, 2008

UPDATE: This article appears to get a reasonable amount of traffic from google so I figured I’d update/correct it. The solution I outline below ended up not working as nicely as I had hoped, so I scrapped it. Instead, I just created a single image and making all my button text fit within the length of that single image. Sliding doors isn’t worth the trouble (i.m.h.o), and what I wrote below isn’t a perfect solution anyway.

——

This is one of those annoying things that took me all day to figure out, and the stuff I was able to find on the internets wasn’t very helpful….

I wanted to create some fancy looking buttons with curved corners. But I wanted them to be real buttons (http:post) , not links (http:get) that just look like buttons.

I looked for a way to do it and found a way to do it using links and a way to do it using the <button> element. Neither of these did what I wanted. Rails uses <input type=”button” /> rather than <button>. After learning more about the difference between buttons and inputs I’m still not sure why, but I figured there must be a good reason. I did try <button> but IE was giving me headaches (I couldn’t click on the button) so I gave up. I tried adapting these methods and they weren’t working for me.

One of the methods linked above worked briefly, but it required floating one of the elements left, which makes layout a REAL pain!

So, I (perhaps by accident) found an easier way. I took the opposite approach from using the outer html element for the left image.

First, I made my own button helpers like so:


module ButtonHelper
  def fancy_button_to(button_text, action_text, button_class = "button")
    return '<form method="post" action="' + action_text + '">' + button_base(button_class, button_text) + '</form>'
  end

def button(button_text, button_class = "button")
    return button_base("button", button_text)
end

protected

  def button_base(button_class, button_text)
    return '<p class="button_wrapper"><span class="' + button_class + '"><input value="' + button_text + '" type="submit" /></span>'
  end

end

Then, the css looks like this:


span.button input {
 border:0;
 cursor:pointer;
 white-space:nowrap;
 color: #fff;
 text-align:center;
 font-weight: bold;
}

span.button {
 background: transparent url(/images/small_button_left.gif) no-repeat top left;
 padding: 6px 0px 6px 5px;
}

span.button input{
 background: transparent url(/images/small_button_right.png) no-repeat top right;
 padding-right: 5px;
 font-size: 15px;
 height: 25px;
}

You will need to create some sliding door images (see links at the beginning of this post). The values measured in pixels in the css will depend on those images.

Of course, there is some conditional css, but it’s pretty short. You just have to use different padding amounts for IE6 and IE7. So, I created a new css file call button_ie.css. I conditionally include it in the html file like so:


<!--[if lte IE 7]>
  <link href="/stylesheets/button_ie.css" media="screen" rel="Stylesheet" type="text/css"></link>
<![endif]-->

The button_ie.css looks like this:


span.button {
  padding: 0px 0px 0px 5px;
}

This isn’t perfect. Occasionally there is an error of 1 pixel in firefox 2, but IE6, IE7, & Safari seem to work fine.

Hopefully this will save someone else the frustration I faced today. Though to be honest, I’m actually thinking of moving to fix width buttons.

The (insane) Importance Of Database Indices

Thursday, December 20th, 2007

One of the great things about Rails (especially for beginners) is that you need to know very little about database.

One of the bad things about Rails (especially for beginners) is that you need to know very little about database.

Through all of the literature I read while learning rails, I only have a vague recollection of databases indexes being mentioned. I started learning more about them recently because the performance of one of my apps was degrading over time, and literally, in about 2 hours, I increased the performance of my backend processing by 5x!!!

Intrigued? First – some background:

Most tables in rails (anything that has a model really) has a field ‘id’. This is the primary key of the database, and an index is created on this. I am a database rookie, but I know that an index is just like an index in a book. It’s extra info that the database stores so that it can find things more quickly.

Indices are not a concern when you get started, nor should they be. When your table gets to 1000s of entries, then they CAN become more important. It largely depends on how your app works.

Lets take a simplified example. Lets say you have an app that has sites and pages:


create_table "sites", :force => true do |t|
  t.column "permalink", :string
end

create_table "pages", :force => true do |t|
  t.column "site_id", :integer
end

Someone can view a site, and each site has pages:


class Site < ActiveRecord::Base
  has_many :pages
end

Because you want pretty urls you want someone to be able to go to www.myapp.com/<site.name>/<page.id>. The first thing you need to do that is


@site = Site.find_by_permalink(params[:id])

Of course, you are also going to need to have navigation for that site, so while rendering you have something like this


<div id="nav">
  <% for page in @site.pages %>
     <%# (do something with the page here) %>
  <% end %>
</div>

So what happens, when your someone tries to view a site?

Step 1: find_by_permalink: The database has to open every single ’site’ and check if the permalink matches.

Step 2: @site.pages: The database has to open every single page and check if the event_id field matches the id of the event that it is looking for.

When you have small numbers of rows, this isn’t a big problem. When you get 1000s of rows, looking through every site and every page gets slow, quickly.

So, the solution is to add an index. You add indices in Rails using migrations. You can create a migration like this:


class AddIndices < ActiveRecord::Migration
  def self.up
    add_index :sites, :permalink
    add_index :pages, :site_id
  end

  def self.down
    remove_index :sites, :permalink
    remove_index :pages, :site_id
  end
end

When you add those 2 indices, the database can now much more quickly find and retrieve the single Site object by permalink, and find and retrieve only the required Page objects rather than having to search the entire database for a match.

Doing this got my a 5x improvement in the speed of some of my more common actions, and literally took 2 hours.

You do need to be careful. Adding indices can slow down your performance because every time you insert, update, or delete rows, the database must also alter the index.

Some useful links:

http://therailsway.com/2006/11/21/tracks-part-4

http://weblog.jamisbuck.org/2006/10/23/indexing-for-db-performance

http://www.websitedatabases.com/database-index.html

There are probably good ways of benchmarking this. After testing locally, I copied my live data to my staging area, added the indices, ran a few actions, and compared the logs from before/after the migration. In my case, some actions got a bitter slower, but those were uncommon ones. My most common actions got 5x faster!! Have a look at the following graph. The red lines show the % of time for an action after adding the indices. Above 100% means the action got slower. Below means it got faster. You an see most actions got a lot faster!

Effect of Database Index

A Quick Trick For Read Only Behaviour

Monday, November 26th, 2007

Sorry for the lack of posts recently. I haven’t really been doing any Rails stuff!

My focus as of late has been on design (css) and search engine optimization. I’ll write more about those too I suppose, but for now just a quick trick I cam up with today that I thougth was kind of neat.

MomentVille growth has been great, so we are upgrading hardware. This will cuase up to an hour of downtime as we migrate. But, that seems unacceptable to me. In reality, it’s only 5 minutes of downtime that is required for one specific thing. One VM is getting moved. It needs to be shut down and copied to new hardware. After it is copied, it can go back up on the original hardware, (5 min) and the rest of the time is getting the new hardware up and altering DNS settings. (55 min).

If we run the original after its’ been copied then any changes made will be lost, but that shouldn’t stop people from being able to READ from the db.

I put together a quick little fix to deal with this. In the main controller that deals with edits I created a protected method:

def check_for_maintenance_mode
respond_to do |format|
format.html {
redirect_to "/index_maintenance.html" and return
}
format.js {
render :update do |page|
page.alert "Nov 26, 2007: MomentVille.com is undergoing scheduled maintenance. " +
"It should last less than 1 hour. " +
"Any changes you try to make during this time will NOT be saved. " +
"We are sorry for any inconvenience."
end
return
}
end
end

I then call it in a before filter for any action that performs an edit:

before_filter :check_for_maintenance_mode, :except => [ :show ]

I save that new controller as: controller.maintenance.rb and wrote a little shell script to update the controller and restart the mongrel cluster. This will put me into ‘maintenance’ mode, and the outcome:

  • All parts of the website are viewable.
  • If someonetries to make a change that requires a database write they get:
    • redirected for an http request
    • an alert for an ajax request

YSlow On Rails

Wednesday, October 17th, 2007

I gave a talk recently on how to improve the front end performance of a rails app using YSlow as a tool to measure said performance.

10 Best Tools For Testing, Debugging, & Optimizing Websites

Sunday, September 23rd, 2007

I’ve learned a lot about web apps in recent months, so I thought I summarize what I have found to be the most useful resources in terms of helping me do things well.

1. Firebug: http://www.getfirebug.com Firebug is a plugin for firefox that, well, lets you see any detail about a web page that you could conceivably what to see. I’ve only ever heard good things about, and the accolades are very well deserved. So far I’ve used it for:

  1. Analyzing the DOM
  2. Stepping through (and setting break points) in Javascript
  3. Viewing Javascript errors
  4. Viewing Styles

To be honest – I think I’ve only just scratched the surface.

2. Firefox Web Developer Toolbar https://addons.mozilla.org/en-US/firefox/addon/60 There may be some overlap between this and firebug, but I use both. I find this particularly good for debugging styling. ‘View Style Information’ is killer. It is also very useful for testing your site with javascript or cookies disabled.

3. YSlow http://developer.yahoo.com/yslow/ This is actually a plugin for firebug (yeah – a plugin for a plugin). It analyzes a page using 13 metrics (all with very details descriptions that are linked to), and gives a grade for each one, as well as an overall grade. I took my score from 33 to 60+ but my site is so much more responsive than it used to be. The biggest gain was simply by putting all the javascript at the end, so the page visually loads so much faster. I’m moving to a dedicated server at present, and will then be able to increase the grade even more.

4. Total Validator https://addons.mozilla.org/en-US/firefox/addon/2318 This basically just redirects you to a online html validator, though the pro version does it locally I believe. As I understand, valid HTML is good for both SEO & cross browser compatability (well – except for IE).

5. Selenium http://www.openqa.org/selenium/ Selenium uses javascript to test drive your app. I wrote about it before. Backend testing is easy in rails, but there is no way to test the user interface, especially for javascript heavy sights. Selenium is the answer. With the IDE you can even record actions and run them as test later :-)

6. IE Developer Toolbar (ie toolbar download) This is basically a combination of firebug & the firefox web developer toolbar. It’s pretty good, and I’ve used it several times to track what was happening in IE. It only works with IE7 though – which is too bad since most of my problems are with IE6…

7. ScreenGrab http://www.screengrab.org/ This firefox plugin lets you render a page (visible portion or whole thing) to an image file. One note – it allows you to save with a .jpg extension, but really saves in .png format. This caused me problems when I was trying to do something with an image that needed to really be in .jpg format…

8. Quick Locale Switcher https://addons.mozilla.org/en-US/firefox/addon/1333 This is ideal for testing an app with localization. I’ve only played around with it quickly as I’m not doing localization yet, but it will come in very handy when I do.

9. Site Report Card http://www.sitereportcard.com This is an online tool that checks a number of things on your site, such as inclusion in search engines, html validity, spelling, links, etc.

10. Love Love Okay – so I really only have 9 tools – but 10 just seems like a better number for a title… Love is good though. Spread the love and all will be well…

So there’s my opinion of the top 10 tools for testing, debugging, and optimizing web apps. most of them are firefox add-ons, but I would recommend against getting too dependent on firefox. The <problem> with firefox is the lack of bugs… Rotate browsers when developing…

Cross Browser Testing & Tools

Sunday, September 9th, 2007

So, at least for the site I’ve been working on, cross browser verification has been troublesome. This is probably the worst case scenario since it is javascript heavy, has a complex Dom, and has themes (34 and growing)…

So – how have I been testing it? (if I’m missing anything – please let me know!!!)

Well first, I have 4 browsers installed on my machine:

  1. Firefox 2.0 : http://en.www.mozilla.com/en/firefox/
  2. Safari for windows : http://www.apple.com/safari/ (firefox is better for developing, but Safari just tends to look really good and work really well)
  3. IE7 : http://www.microsoft.com/windows/downloads/ie/getitnow.mspx
  4. IE6 standalone http://browsers.evolt.org/download.php?/ie/32bit/standalone/ie6eolas_nt.zip

Beyond that, there are 2 other things I found very useful, each corresponding to the 2 things that are needed for cross browser testing: Styles & Behaviour

1- BrowserCam : http://www.browsercam.com/ It takes screenshots of your webpage using a whole range of browsers on a whole range of platforms. If you’re stingy you can get a demo account, but it’s worth signing up for at least a month. This helps ensure cross browser compatibility for styles.

2 – Selenium : http://www.openqa.org/selenium/ Selenium test drives your apps using javascript. It’s really ingenuous. You write (or record using Selenium IDE) scripts to perform actions, like type data, click, drag and drop, etc. You can also create assertions on page titles, dom elements, page contents, etc. If you have a javascript heavy site, Selenium is a must!

You can write selenium scripts in a variety of languages, and run it from either the front end or the backend. That is, you can drive it from a local server and test any site on the web, or, using selenium on rails, http://www.openqa.org/selenium-on-rails/ write some tests, and then just run them by visiting (test.myapp.com/selenium). I actually recommend the former, after having tried both. I’ll write more about selenium sometime later, as there is lots to cover.

I’m putting together a list of the other tools I use (plugins, etc) and will post that shortly.

Time Breakdown for Developing A Rails App: Postmortem

Thursday, August 30th, 2007

With v1.0 MomentVille now launched, I was doing a bit of a postmortem on the process. I hope that this will help other new app developers judge how much time they might need to deploy a new app… I’d love to hear what others find for their breakdown in terms of percentages.

1 Month: Learning: First, before even starting, I needed to learn Ruby on Rails to sufficiently start (with no web dev background besides HTML with table layouts). I would estimate this took about 1 month. I did start developing the wedding website builder before feeling really comfortable with rails, but most of the time in the first month was just getting comfortable with rails and web app development. I also got a book on CSS (highly recommended for anyone who still considers using tables) and that was included in my learning time.

These are rough estimates, but I would roughly categorize my time for this app as follows:

time.JPG

~25% Prototype Development: Writing the core of the application.

~ 25% Code Adjusments:

  • Code Refactoring: cleaning up hackish or silly things I did because I was just trying to get something working, or I didn’t know better.I think this should be down along the way, otherwise you end up with nasty bandaids everywhere.
  • My Code Adjustments: making adjustments to my code so things were a little more friendly. Eg: making the polls more user friendly,
  • Shared Code Adjustments: Adjusting shared code that I used to fit into my system. Eg: making the authentication code use email address as login id, update InPlaceRichEditor for undo edits when cancel is hit, etc…

~ 25% Cross Browser Testing

  • Gosh, this was painful. I hope it gets easier over time. A lot of the testing I did was manual, because I was looking for visual inconsistencies which I couldn’t find a good way to test in Selenium. I wanted to make sure that the cursors were correct based on mouse position, and state of the app, etc… Ugh. Start testing on IE6 early. This was probably made more difficult by the fact that I have a large number of themes (styles) over which to test. More on this in a later post…

~ 13% Styles

  • This is probably higher than most will be, since wedding websites on momentville can have any of a number of themes.

~ 12% Test Code

  • Test Writing: Writing unit & functional tests in Rails is easy. You should start early. Honestly. Just force yourself to learn how. It’ll take a day, and save many more….
  • Selenium Tests: Selenium is a great tool for UI testing. Rails testing is great for business logic, model verification etc, but you need to test what it is like to drive an app to, and Selenium is great for this.