Archive: April 2009

Retailers trying to stay upscale are heading down

A recent New York Times article about the decline in teen spending points out an undoubtedly larger problem for high-end retailers. From the source:

To maintain its prestigious image, Abercrombie has stood alone among mall retailers in not blaring its sales—a strategy that Wall Street analysts have blamed for its current decline. The company reported a 34 percent drop in sales for March at stores open at least a year, the worst performance of mall retailers that month…In the past, the chain has said it doesn’t want to tarnish its image with big discounts, but the risk is that consumers may retain the habit of thriftiness even after the recession ends.

This looks like a case of economic Darwinism—either evolve with your environment or become extinct. Other peddlers of prep fashion have been quicker to adapt:

Even the clearance items at Abercrombie do not exude the promotional fervor that can be found at American Eagle, which has a sign up front noting its shorts are under $25; or Aéropostale, where banners announce two-for-one bargains. Aéropostale also reported a sales increase last month, up 3 percent, a success that Mindy Meads, the company’s president, attributed to the right combination of product and value.

“We get the right looks,” she said. “At the same time, we’re very mom-friendly when it comes to the wallet.”

Retailers looking to grab those coveted teen dollars better rethink their approach. Teen jobs are vanishing. Allowances are undoubtedly shrinking. And thrift is officially chic.

Object Oriented CSS

Lately I’ve been concentrating on learning more and more about website performance, mainly on the Frontend side. I’d like to share a recent finding that I thought was rather interesting: Object Oriented CSS. OOCSS itself is a philosophy for writing Frontend code, focused on rapid development, efficiency of code, and maintainability. Recently, OOCSS Grids was created as an HTML/CSS framework to demonstrate these points in action and to give developers an ideal starting point, beyond a simple CSS reset.

Background

The OOCSS (Object Oriented CSS) Grids project is aimed at providing a framework for developers to rapidly produce performance oriented, easily manageable layout structures for their websites. OOCSS Grids was created by Nicole Sullivan, a Frontend Engineer and former member of Yahoo’s Exceptional Performance Team. Nicole is also cocreator of the image optimization tool smush.it, which I highly recommend. OOCSS Grids is loosely derived from YUI Grids.

Principles

As noted on the project’s Github page, OOCSS Grids has two key principles in mind:

  1. Separate structure and skin
  2. Separate container and content

Grids
These principles focus on keeping the page as flexible as possible by breaking down areas of the page into objects which use the same base markup for their containers. When an object requires special styling, it is easily extended by adding additional classes to the container element. This is ideal in a number of ways, perhaps the most important because it forces code to be produced in a much more predictable fashion. In the long term this will greatly assist Backend developers, content creators and designers in obtaining a concrete understanding of how the Frontend side of your site works. The idea being that team members who understand not only their own process, but also the process of those around them, will accomplish their tasks faster and more efficiently, while being measured against higher standards. A win for everyone.

A good question to ask right about now would be “won’t doing it this way produce a lot of extra, unnecessary markup?” The answer is yes and no. The extra markup will indeed make load times a little longer, but it is necessary to give flexibility for both current and future layout needs. For instance, what if a client wanted a sidebar container to suddenly have slick outer drop shadows along the border? Well, depending on the site’s current markup that could be a really tricky task to restyle, possibly involving new markup and a lot of QA for such a small task. However, with an OOCSS Grids implementation in place, it would be as trivial as extending our container element of class “mod” to include the class “complex”, which has styles to accommodate for similar border types. Next you would need to add and style a custom class, for example “tricky_shadow”, with some easy customizations, upload any necessary images and it’s good to go. Here is an example, based on the OOCSS Grids Modules page currently in the Git repository:

Before

<div class="mod">
    <b class="top"><b class="tl"/><b class="tr"/></b>
    <div class="inner">
        <h3>Some Module</h3>
        <p>Lorem ipsum dolor sit amet...</p>    </div>
    <b class="bottom"><b class="bl"/><b class="br"/></b>
</div>

After

<div class="mod complex tricky_shadow“>
    <b class="top"><b class="tl"/><b class="tr"/></b>
    <div class="inner">
        <h3>Some Module</h3>
        <p>Lorem ipsum dolor sit amet...</p>
    </div>
    <b class="bottom"><b class="bl"/><b class="br"/></b>
</div>

What our custom CSS might look like

.tricky_shadow .inner {
    border:solid 10px #fff;
    margin:0 4px;
}
.tricky_shadow b {
    background-image:url(images/shadow.png);
}

.tricky_shadow .tr,
.tricky_shadow .tl {
    width:20px;
}

.tricky_shadow .top,
.tricky_shadow .bottom {
    height:4px;
    margin-top:0px;
}

.tricky_shadow .bl,
.tricky_shadow .br {
    height:16px;
    margin-top: -12px;
}

Note: remember that the “mod” and “complex” styles would be already have been predefined for the basic layout of the container.

Performance

So, where does the promised performance benefits come in to play? Well, duh, it comes in the form of constantly reusing the same base classes, thus minimizing the amount of CSS needed and maximizing the utilization of the browser’s ability to cache and reuse commonly occurring elements. To delve further, because every page will be using the same basic location independent styles, the browser will have less unique objects to render. It will render the generic objects and extend them only when necessary, resulting in pages that appear faster.

To help demonstrate, below is a visual representation of the Mozilla.org homepage being flowed into the browser. While it isn’t using OOCSS Grids, it’s still utilizing some of the same practices, because after all, it is Mozilla. Pay special attention to the way the columns are being created.

An added bonus gained from these location independent styles is the reduction in the impact reflows have. A reflow is when the browser repositions all child elements as well as any elements following it in the DOM. It can be triggered a number of ways, notably when JavaScript is used to change a class or style for an element. Knowing this, it is best to be as specific as possible and target only what you need to change when using JavaScript in this manner. Because OOCSS states all of the elements should be styled based on either their own class or those of their immediate (or very close) ancestors, reflow effects are kept to a minimum.

Recap

Pros

  • Faster development times
  • Graded browser support
  • Easier to comprehend what the HTML is doing
  • Markup that is easy to style, from new modules to complete overhauls of the design
  • Promotes low impact on browser reflows
  • Easy to maintain, especially when inheriting code from someone else
  • Small learning curve

Cons

  • Likely to have more markup, meaning more DOM nodes for our Javascript to parse through and larger file size
  • A little overcomplicated for small sites, in which case you wouldn’t want to use it
  • It has a learning curve, where those using it will most likely already know how to get the job done (even if it’s in a less efficient manner) and resist changing their way

Conclusion

For the most part, OOCSS is a cool idea. While the general concept of reusing styles in CSS is not new by any stretch, the creation of such a concise framework that champions the strict use of these concepts should be welcomed with open arms. Nicole Sullivan deserves a ton of respect for all of the time she has put into this project and for all the other related articles she’s published, such as the information on reflows and repaints.

Now, the real question is how do we take these CSS frameworks and turn them into great looking, high performance websites that reflect the brand messages of our clients? That is what we’ll be focused on and I’m sure we’ll come up with some really great stuff.

To spend or not to spend, that is the question

The fantastically talented New Yorker economics writer James Surowiecki took a look back at acquisition, advertising, and R&D spend during past recessions and what it meant for those who cut back. From the source:

In the late nineteen-twenties, two companies—Kellogg and Post—dominated the market for packaged cereal. It was still a relatively new market: ready-to-eat cereal had been around for decades, but Americans didn’t see it as a real alternative to oatmeal or cream of wheat until the twenties. So, when the Depression hit, no one knew what would happen to consumer demand. Post did the predictable thing: it reined in expenses and cut back on advertising. But Kellogg doubled its ad budget, moved aggressively into radio advertising, and heavily pushed its new cereal, Rice Krispies. (Snap, Crackle, and Pop first appeared in the thirties.) By 1933, even as the economy cratered, Kellogg’s profits had risen almost thirty per cent and it had become what it remains today: the industry’s dominant player.

Surowiecki cited more examples of companies who won big by spending during tough times, including Plymouth, Kraft, Texas Instruments, and Apple. Of course there’s an equal amount of failures, which is why companies find themselves wondering whether they are “sinking the boat” on bad bets or “missing the boat” by letting opportunities pass by:

Today, most companies are far more worried about sinking the boat than about missing it. That’s why the opportunity to do what Kellogg did exists. That’s also why it’s so nerve-racking to try it.

The full article is a fast, fun, and informative read, as most of Surowiecki’s tend to be. His blog is also definitely worth a bookmark.

Taking a Dip Into the ASP.NET MVC Framework

mvc1.JPGJust as I was becoming comfortable playing in the familiar waters of web forms-based ASP.NET applications, Microsoft announced the release of the ASP.NET MVC framework, an alternative to the ASP.NET Web Forms pattern for creating MVC-based Web applications.  According to Microsoft, the ASP.NET MVC framework offers the following advantages:

  • It makes it easier to manage complexity by dividing an application into the model, the view, and the controller.
  • It does not use view state or server-based forms. This makes the MVC framework ideal for developers who want full control over the behavior of an application.
  • It uses a Front Controller pattern that processes Web application requests through a single controller. This enables you to design an application that supports a rich routing infrastructure.
  • It provides better support for test-driven development (TDD).
  • It works well for Web applications that are supported by large teams of developers and Web designers who need a high degree of control over the application behavior.

My first reaction to reading about the ASP.NET MVC Framework was a mixture of excitement, fear, and confusion.  I was excited by the idea of having a new tool to make better designed/engineered web applications; I feared the unknown of a world without web forms and view state; and I was confused by the semantics of MVC.  Wasn’t I already programming using the MVC pattern?

Being the cautious yet curious person that I am, I decided it was time to stick my big toe into the proverbial ocean of the ASP.NET MVC framework.  Thus, my first order of business was to address my confusion over MVC.   Reviewing the definition of MVC seemed like a good place to start (ref. http://msdn.microsoft.com/en-us/library/dd381412.aspx):

  • Models:  Model objects are the parts of the application that implement the logic for the application’s data domain. Often, model objects retrieve and store model state in a database. For example, a Product object might retrieve information from a database, operate on it, and then write updated information back to a Products table in SQL Server.
  • Views:  Views are the components that display the application’s user interface (UI). Typically, this UI is created from the model data. An example would be an edit view of a Products table that displays text boxes, drop-down lists, and check boxes based on the current state of a Products object.
  • Controllers:  Controllers are the components that handle user interaction, work with the model, and ultimately select a view to render that displays UI. In an MVC application, the view only displays information; the controller handles and responds to user input and interaction. For example, the controller handles query-string values, and passes these values to the model, which in turn queries the database by using the values.

Wasn’t I already programming using the MVC pattern?  After all, isn’t the ASPX the same as “view,” the code-behind the same as the “controller,” and my data classes the same as the model?  It turns out that the answer to that question is “yes,” but the flavor of MVC pattern programming that I currently employ is not the same as MVC pattern supported by the new ASP.NET MVC framework.  One of the main differences, in my opinion, is in the controller. (There are many other differences, but this one got my attention first.)  ASP.NET web form-based applications use the “Page Controller” pattern, which has a single controller object per page as opposed to the single object for all requests.  Some of the liabilities of using the page controller pattern are the following:

  • It’s hard to test.  You cannot instantiate and test the controller classes outside the Web framework.  If you want to run a suite of automated unit tests on the controller class (the page code-behind), you would have to start the Web application server for each test case. You would then have to submit HTTP requests in a format that executes the desired function.
  • One controller per page. The key constraint of Page Controller is that you create one controller for each Web page. This works well for applications with a static set of pages and a simple navigation path. Some more complex applications require dynamic configuration of pages and navigation maps between them. Spreading this logic across many page controllers would make the application hard to maintain, even if some of the logic could be pulled into the base controller.

On the other hand, web applications built using the ASP.NET MVC framework use a “Front Controller” pattern that processes Web application requests through a single controller. When you build a traditional ASP.NET Web Forms application, there is a one-to-one correspondence between a URL and a page.  When building an ASP.NET MVC application, in contrast, there is no correspondence between the URL that you type into your browser’s address bar and the files that you find in your application. In an ASP.NET MVC application, a URL corresponds to a controller action instead of a page on disk.  An ASP.NET MVC application is application logic centric, whereas an ASP.NET Web Forms application is content-centric.

After reading about the differences between page controllers and front controllers, I began to understand some of the excitement surrounding the ASP.NET MVC framework.  It just makes sense to have a centralized point to handle/process requests made to your web application.  It’s kind of like national defense.  It makes sense for the federal government (front controller) to be in control of our nation’s military, instead trying to defend our nation using de-centralized state militias (page controllers).  I’m not sure that’s the best analogy, but it works for me.

Confident in my understanding of the various nuances of MVC implementation, I decided it was time to wade a bit further into the ASP.NET MVC framework (up to my ankles at least).  I found that Scott Hanselman’s video (http://videos.visitmix.com/MIX09/T49F), Creating NerdDinner.com with Microsoft ASP.NET Model View Controller (MVC) and corresponding walkthrough tutorial (http://www.hanselman.com/blog/FreeASPNETMVCEBookNerdDinnercomWalkthrough.aspx) to be a great starting point.  The sections on unit testing and support for mobile devices were especially intriguing.

I’m about half way through the walkthrough sample code (it is 196 pages long).  At this point, I’d like to leave you with a few casual observations/opinions:

  • The ASP.NET MVC framework is a whole new world compared to the “old” web forms approach, and will take significant effort/time (for me at least) to develop an adequate level of competence to use it in the real world.
  • In comparing the advantages between web forms framework versus the MVC framework (see Microsoft’s ASP.NET MVC Overview http://www.asp.net/learn/mvc/tutorial-01-vb.aspx), it makes more sense continue using web forms for the types of projects that I’m currently working on.).
  • In order to prepare myself for bigger, more complex projects in the future, I definitely believe it is important to continue growing my fledgling ASP.NET MVC framework skills (Besides, it will be good for my brain’s elasticity too!).

Happy programming!

Multi-Part Messages and AJAX (MAJAX? MXHR?)

Digg has an article on their blog explaining their new MXHR technique for returning multi-part messages using AJAX. While their demos appear to be magical, the underlying technology is actually very similar to the existing COMET techniques. In a typical COMET application the browser creates an XHR connection and leaves it open until the server decides to send back some data. At the end of the request the connection is closed and the browser opens a second connection.

Digg’s MXHR Stream makes use of an oft-overlooked HTTP content type, “multipart/mixed.” Basically all the messages are sent over the same request with a delimiter marking the beginning of the next message. The main advantage being that for COMET to work, a series of connections needs to be closed and opened while MXHR can use a single connection. A basic message might look like this:

MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="|||"
--|||
Content-type: text/plain

This is message 1
--|||
Content-type: text/plain

This is message 2
--|||--

You can of course get clever with it, as Digg did, and pass back multiple mime types and handle each one differently. Combined with specific call-backs for each type, this method can be quite powerful.

var s = new DUI.Stream();
s.listen('text/html', function(payload) {
  $('#stream').append(payload);
});
s.listen('text/javascript', function(payload) {
  $('body').append('<script type="text/javascript">' + payload + '</script>' + payload + '');
});
s.listen('application/json', function(payload) {
  //do something with JSON
});
s.load('mixedstream.php');

The server might send back a file that looks like this:

MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="|||"

--|||
Content-type: text/html

<p>This is message 1</p>
--|||
Content-type: text/javascript

alert('This is message 2');
--|||
Content-type: application/json

{"message":"This is message 3"}
--|||--

When looking over the spec for miltipart/mixed messages one can’t help but think, “holy crap! Bowsers can handle multipart messages?!?”  But the truth is that browsers don’t handle mixed messages. Digg’s MXHR is simply using a standard RFC message format and parsing it with JavaScript. It works like this:

  1. Make a request to a miltipart/mixed file using standard AJAX
  2. Listen for the readyState to change to “3″ which means “Downloading”
  3. At this point the responseText will contain part of the document
  4. Parse the responseText into the individual messages (see the processPacket() function) using JavaScript, splitting the message at the boundary.
  5. Set an interval at 15miliseconds and continue to read the responseText from the end of the last known messages and process the complete messages as they arrive.

While this initially looks to be some sort of undocumented browser magic, in reality it is a clever application of an existing message protocol and using JavaScript to parse a string. The implications are still pretty interesting; it isn’t hard to imagine making great use of this for complex AJAX applications or for enhancing a tool like google.load. Imagine using code like this to pull in all of your required libraries bundled into one request:

<script src="http://www.google.com/jsapi"></script>
<script>
  // this is fake code
  google.combine("jquery", "1.3.2");
  google.combine("jqueryui", "1.7.1");
  google.combine("swfobject", "2.1");
  google.loadCombined();
</script>

I’d like to teach the world to link

• “Your business card is crap!”

• Americans blame ad agencies for economic crisis

• Facebook use linked to lower GPAs

• First commercially flown 747 now a Korean restaurant

To overcome consumer inertia, tighten the deadline

Nothing gets work done quite like a deadline. But the pressure of a ticking clock is typically associated with activities we don’t want to do (i.e. filing income taxes, writing a term paper). Virginia Postrel wrote an article for the Atlantic Monthly about consumer behavior towards shopping incentives with deadlines such as coupons and gift cards.

Postrel interviewed behavioral economists Suzanne B. Shu and Ayelet Gneez about a study they conducted to see how consumers react to different offer time frames. From the source:

In an experiment, Shu and Gneezy first surveyed 80 undergraduates, asking how they would feel about a gift certificate for a slice of cake and a beverage at a local café and how likely they were to use it. Forty-two survey participants were asked to consider a certificate good for three weeks, and 38 were asked about a two-month certificate. More than two-thirds of the group with the longer deadline said they would use such a coupon; only half of the group with the shorter deadline said they would.

Shu and Gneezy then ran the experiment in real life, with a different group of 64 undergraduates. Half the participants got certificates good for three weeks and half for two months. Both groups were far less likely to cash in their cake coupons than predicted. And contrary to predictions, the shorter deadline encouraged more indulgence. Ten out of 32 people redeemed the three-week certificate; only two of 32 used the two-month pass. Those who redeemed their certificates said they’d enjoyed themselves, while those who didn’t said they regretted letting the deadline slip.

So the tighter the deadline, the more likely consumers will stop looking for excuses and start acting. Shu cites Disneyland as a great example of a business giving consumers “a justification and a deadline” with their free birthday pass program. Postrel goes into even greater detail on deadlines, tiered promotions, and other incentives in the article, which is most definitely worth you time. Just don’t put it off for later.

Just buy it already

“Do I need this?”

“I’m not sure about the color.”

“Maybe I’ll come back for it.”

It often takes someone else’s opinion for you to finally pull the trigger on a purchase. Natalie Zmuda of AdAge wrote an article detailing the latest frontier for this timeless retail interaction—online. From the source:

In the coming weeks, two technologies — friend-based merchandising that involves Facebook and collaborative shopping — are being rolled out to big-name retailers, including Vans, Lucky Brand Jeans and Warner Entertainment.

The collaborative-shopping technology, which is now live at Vans.com, allows consumers who are building custom shoes on the site to chat with friends in real time about the product design. The customer clicks on a link saying, “Invite friends to design with you,” giving them the ability to access friends through AIM, e-mail or any other service a link can be sent through.

By creating a forum where consumers can get the validation they need to make the purchases they want, retailers could see less abandoned shopping carts and more sales.

Where did you get those shoes?

Moccasins in Miami. Stilettos in Syracuse. Loafers in Lubbock. Be prepared to be mesmerized by this map developed by Zappos that shows where product orders are being placed across the country in real time.

Perhaps by showing the endless stream of purchases, Zappos will inspire consumers to pick up a little something for themselves.

Fans of footwear, geography unite

Moccasins in Miami. Stilettos in Syracuse. Loafers in Lubbock. Be prepared to be mesmerized by this map developed by Zappos that shows where product orders are being placed across the country in real time.

Perhaps by showing the endless stream of purchases, Zappos will inspire consumers to pick up a little something for themselves.