Showing posts with label redesign. Show all posts
Showing posts with label redesign. Show all posts

Monday, June 14, 2010

Optimizing Site Performance

Purpose & Goal

Right now I’m running some tests through webpagetest.org to establish baselines for site performance. This week I hope to generate some CSS sprites for our common images and set up gzip and xpiration headers on the server. Those are the last 3 big things pointed out by YSlow (actually I’m using Google Page Speed, but YSlow is cool too). Hopefully soon I'll be able to run a new set of tests to compare to the baselines I'm running now.

Sampling

I'm trying to get a representative sample of of pages to test. The home page gets the most traffic, followed by the Current Students page. Pride Online has the most popular departmental home page, but it's utilitarian and not representative of other pages. That moves us down to the home page for the library.

Those 3 pages realistically represent only about 1/6 of our total pages, but it’s the most heavily visited 1/6. I could add one more test case and increase my representativeness to the majority of our pages, but we’d see diminishing returns in terms of traffic (only about 16% of total site traffic). Also, the remaining 5/6 of pages are mostly text heavy and image lite. The benefits to those pages will come from optimizing the overall site template, which will be partially reflected in the 3 chosen test cases.

Thanks to Google Analytics for the ability to access that info easily.

The Site Performance widget in Google Webmaster Tools says we gained nearly half a second in our rendering time around June 6th. That half second was enough to move us up from around the 73rd percentile to the 82nd percentile. I have no idea why we saw this jump in overall site performance but I'm glad to have it. Maybe we can even hold onto it.

The Results Are (Mostly) In

The 3rd and final test is still running as I type this. I’ll link out to the results as they become available.

Step 1: CSS Sprites

I'm using SpriteMe and my own best judgement to create some CSS sprites for commonly used background images. I'm assuming SpriteMe already has something like Smush.it built in.

Results

Ok, maybe I need to smush my sprites after all. I've added about 60kb to each page load while freeing up about 15 http requests. Smush.it can’t find anything to optimize, but the image optimizer in YSlow can shave about 5k total from 2 of the sprites. SpriteMe makes some less than optimal choices, even occasionally introducing bugs. But like all software it has to make certain assumptions and those don’t always pan out. I need to improve upon the default sprites while I’m at it. With these newly optimized sprites, let’s look at the trade offs.

jQuery UI Theme Icons for Play Controls

The first sprite I made was actually already made for me thanks to the jQuery UI Theme Roller. I used the blue and red versions of the UI sprite to replace the play control icons under the featured stories on the home page. The bad news is that almost doubles raw file size. In exchange, I pre-load a lot of UI elements that we're not currently using anywhere else. But I plan to make more use of the jQuery UI in the future. So I think this is a worthwhile change.

Baseline With Sprites Change
HTTP Requests 8 2 -6
Total Bytes 5,310 9,724 +4,414

Stripes Sprite

Both the header and the footer have background stripes that go all the way across the page. These were tiny, 1 pixel wide repeated images. But they were easy enough to combine.

Baseline With Sprites Change
HTTP Requests 2 1 -1
Total Bytes 905 122 -783

Image & Badge Drop Shadows

Some day I’ll be able to pull this off with pure CSS but in the meantime I’m stuck with background images. The one for the standard large image gets used on most pages. The one for smaller images at the same aspect ratio and the badges gets used fairly often too. The other 2 don’t see as much use. Some pages don’t use any of these, but the majority of our high traffic pages do. The image produced by SpriteMe left extra white space to the right of the 16px icons screwing up the placement. I had to edit the sprite in Photoshop. After that Smush.it actually did a better job compressing the resulting image than YSlow.

Baseline With Sprites Change
HTTP Requests 4 1 -3
Total Bytes 4,018 5,092 +1,074

Icons

The image produced by SpriteMe left extra white space to the right of the 16px icons screwing up the placement. I had to edit the sprite in Photoshop. After that Smush.it actually did a better job compressing the resulting image than YSlow.

Baseline With Sprites Change
HTTP Requests 18 1 -17
Total Bytes 14,589 13,677 -912

Logos

I combined our logo with the RODP logo that’s featured on every page. But that only nets us 1 less HTTP request and as you’ll see below costs us significant bytes due to the differences between .jpg and .png image formats.

Baseline With Sprites Change
HTTP Requests 2 1 -1
Total Bytes 12,270 39,876 +27,606

In a Nutshell

In a best case, a single page that references all these images (which is not terribly realistic), we’ve traded 28 fewer HTTP requests for 31,399 more bytes. That’s about 22 additional HTTP packets. Based on our test cases we’re realistically saving 12 – 15 HTTP requests per page. I know we’ll see a big pay off when we start effectively caching and gzipping this stuff, but I have to admit I’m disappointed with this first round of results.

Step 1.1: Learning from Mistakes

Ok, now I understand why the RODP logo was initially flagged as not to be included in a sprite due to being a jpg. I need to roll back the Logos sprite. I also need to alter the way we’re doing the random headers. We’ve been using something based on Dan Benjamin’s method from A List Apart but in terms of site performance it’s one of our slowest resources.

Results

We’re starting to see some minor pay off on the repeat viewing. Start render time on the current students page is now under 1 second. That’s pretty awesome, but we’ve still got work to do.

Step 2: GZip

I followed this guide as well as some official documentation from Microsoft. This online gzip test says we’re still not using compression but my web developer tool bar begs to differ.

Results

I just alphabetized the properties in each CSS declaration, primarily as a way to clean up my CSS and make it easier to manage. But Google’s Page Speed documentation points out the possibility of alphabetized CSS seeing more efficient gzip compression. Checking the alphabetized, minified, and gzipped version against the just minified and gzipped version with the Web Developer Toolbar (Information —> View Document Size) shows 8k either way. It doesn’t break it down into units any smaller than that. So maybe it saved me a few bytes, but not a kilobyte. So if we saw any gzip efficiency change from alphabetizing the CSS it’s less than 12.5%. If we assume rounding, then it’s less than 6.25%.

Step 3: Browser Cache

This one will be labor intensive. Before I put in the hours to set expiration dates and last modified dates for our various static resources I want to make sure they are properly optimized. We’ve covered CSS and JavaScript, but all the images that didn’t find their way into a sprite will need to be tested. I started this entry on Monday morning. It is now 1:30 on Wednesday. I this step will probably keep me busy the rest of today and a good chunk of tomorrow.

Ok, the clean up and optimization process has saved me about 10,000,000 bytes and 400 files. Gzip has been running for a full day and server’s resources don’t seem to be at all taxed. So far so good. Time to dive into Leverage Browser Caching.

I have a problem in that IIS reports the wrong last-modified date for certain files. Images seem fine. PHP files and other plain text files are not. Maybe I’m missing something in Dreamweaver. Our server also sends E-Tag hashes, which are newer than and in theory superior to last-modified headers. But they are also redundant together. E-Tags are apparently frowned upon when using multiple servers, such as a Content Delivery Network. All our content comes from just the one server so I don’t think it’s an issue with us. At worst we’s sending a single redundant HTTP response header.

So half the browser caching equation was essentially taken care of for us by IIS’s default settings. The other end of that equation is content expiration. I did not like that IIS just gave me a single check box to turn content expiration on. I wanted to be able to set it up by file extension. No such luck. I turned it on and did some testing with the Live HTTP Headers extension for Firefox. I was able to confirm that our php pages were not caching. Which is good. The last thing I want is someone to spend the next 6 months with an unchanging copy of our home page stuck in their browser cache. CSS and JavaScript files were caching, along with images. I already use version numbering on CSS, JavaScript, and image sprites. For the most part other images will have specific names anyway, so that’s good. Then I tested PDF files and did not like what I found.

I downloaded the PDF of our campus map and saw that the response headers told the browser to cache it for the next 6 months as well. We may need to update the map in the next 6 months. Maybe an office location changes to a new building or something. Worse still, many of our PDFs are newsletters. Monthly newsletters. Some offices have an archive listing years’ worth of issues while others just link to the most recent issue. In the latter case, I just save the new issue over the old issue on the server. With browsers caching these files, that wouldn’t work anymore. I’d have to give each issue a distinct name and adjust the HTML links to match, greatly complicating that process.

I rolled back those changes and tried setting up expiration on a directory by directory basis. So far I’ve only done /images/, /css/, and /js/. That covers the vast majority of our static files. Occasionally a directory off of root will have its own images directory. For now I’m leaving those alone. The handful of child directories inside /images/ also apparently did not did inherit the expiration settings of their parent folder.

The downside to all this experimenting is I have to bounce the IIS service for changes to take effect. That only takes about 8 seconds by my count, but I’t to think of someone submitting their final form for online orientation during that tiny window.

Page Speed still says we fail the browser cache check, but that’s due to the FEMA widget currently on our site. All resources being served from volstate.edu pass. So let’s run another batch of tests.

Results

Conclusion

This has been less a blog entry and more 4 days of notes to myself. Tomorrow I will try to recap the high points and present my data analysis.

Thursday, December 03, 2009

First month with the new site

Yesterday was December 2nd. We launched the new site on November 2nd. So as of today, I have one solid month of data on the new site available in Google Analytics. Let’s take a look at how we’re doing compared to November 3rd through December 3rd of last year. The dates don’t match up exactly so that we start on a Monday and end on a Tuesday with both date ranges.

  • Visits up 27.53%
  • Unique Visitors up 89.16%
  • Page views up 38.51%
  • Average page views up 8.61%
  • Average time on site up 22.44%
  • Bounce rate down 46.09%
  • Percentage of new visits up 90.69%

These are all positive changes. Bounce rate is a bad thing, so seeing that number go down is good. We’re reaching more people, who are looking at more pages and spending longer stretches of time before leaving. But I’m not ready to say all this is due to the redesign. After all, we’ve seen a significant enrollment increase this semester, so all these numbers should be improved over a year ago.

So let’s also compare the first month with the new site to a similar date range the month previous; 11/02/2009 through 12/02/2009 compared to 9/28/2009 through 10/28/2009, again starting on a Monday and ending on a Tuesday.

  • Visits up 0.22%
  • Unique Visitors up 15.27%
  • Page views up 30.01%
  • Average page views up 29.72%
  • Average time on site up 41.74%
  • Bounce rate down 51.39%
  • Percentage of new visits up 35.89%

This comparison is less straight forward. The new site has Thanksgiving break in this data set where the old site has no breaks, which would seem to put the new site at a disadvantage. But the old site’s figures come before registration opened up for the Spring, so in other ways it’s at a disadvantage. In other words, don’t read too much into this comparison.

It does help make it clear that the sorts of metrics tied to raw traffic have little to do with the redesign. The percentage change in visits is virtually zero. But metrics that measure engagement, such as time on site and bounce rate, actually show more improvement against a month ago than they do against a year ago. This probably helps show the natural boost we get thanks to registration opening up this time of year. When we’re talking about aggregate data it’s important to keep in mind all the variables that have nothing to do with the design of the site.

I’m more comfortable attributing large shifts in metrics for specific sections of site content that have been significantly overhauled as part of the redesign. For example, the list of our programs of study saw an increase in visits of 502.65% and an increase in unique visitors of 290.45% compared to figures for October of this year. Compared to a year ago, the difference is 548.75% increase in visits, 333.29% increase in unique visitors. One of my primary goals with the redesign was to increase the visibility of this content because I think it’s an important part of the “shopping” process. I think we can safely call that a success.

Wednesday, July 08, 2009

The Culture of Technological Abundance

In one of my computer science courses the instructor asked if computing resources have reached the point where efficiency can safely be ignored. I responded with a resounding “No!” but some of the younger pups in the class disagreed. I'm begging to think I was showing my age, at least within certain contexts.

Something in my brain makes me love the idea of optimization. I actually police myself away from it, but I still find myself spending hours upon hours thinking about “better ways” to do things. I was recently debating with myself about storing telephone numbers in a database as integers vs. strings. I found the integer approach most appealing. It just felt right. But I quickly figured out that would require formatting the data to be human readable every time I needed to display it as well as a bit of trickery on the front end to get the form input (which would be in a human readable format) into a basic int structure. That consumes a lot of my time, and possibly a lot of time for the users who eventually put the collected data to use. In exchange, I save a little bit of hard drive space.

The new server has 500 gigs of RAIDed space. A formatted telephone number string, such as “(888) 555 - 1234” takes up 16 characters. That's a 17 byte VARCHAR. Even less if we default to something shorter for unrequired fields left blank by the user. But for the sake of argument let’s go with VARCHAR. Storing “8885551234” as a BIGINT requires 8 bytes, saving us 9 bytes. That’s 9 out of over 500 billion available. We’ll end up with a few hundred form fields that will see a few hundred hits per year. For the sake of argument let’s say 400 squared, or 160,000. If my attempts at optimization save an average of 9 bytes per field per record, we'll run out of space after about 350,000 years. I'm not sure what the clock cycles are involved in fetching or even comparing a 16 character string vs a 10 digit number, but probably even more negligible than the storage space. Obviously, server resources are abundant when compared to my time and the time of my users.

I’m about half way done building the forms on my to-do list and I just convinced myself to change the way I handle things. Oy vey.

If data is collected for the purpose of being later presented to humans, I will store it as a string, optimization be damned. I’ll use numeric types for data that is collected to be crunched, which in all honesty if rare right now. In situations where it could conceivably be used for both, such as dates, I’m probably better off storing both versions and fetching (or sorting by) whichever is most appropriate rather than running a timestamp through the date() function as needed or converting user input into the MySQL DATE format (which is both human readable and easily sortable).

2 years into this redesign project and I’m still not done. In hindsight, the biggest setback has been my own perfectionism. I have a hand crafted attitude towards my work. I take great pride in it. But at what cost? It feels great when I see something like Smashing Magazine’s list of current best practices in form validation and I realize I’m already doing the majority of those things simply because they “feel right”. But I spent all day yesterday working on a single form, stayed 45 minutes late, and still didn’t get it done. That felt anything but great. What’s the trade off? Where do I draw the line?

I’m even doing it now. I’m encoding my apostrophes and quote marks. Can anyone out there notice the difference between “this” and "this"? It's 12 extra key strokes for me to use the "proper" encoded characters. For all I know, Blogger auto-converts them for me anyway. (*EDIT* No, it doesn’t.) I've just developed the habit over the years of hand coding HTML. 12 keystrokes per quote pairs times 5 quotes per page times 3,000 pages at 400 characters per minute is 7.5 hours. That's a full workday over the past 2 years. Is that too high a price to pay for typographic correctness?

What's the cost of XHTML validation? Of ADA compliance? That last one could end up saving us a mint if lawsuits start getting tossed around. I know where my personal comfort level lies on most of these issues and I'm willing to re-evaluate in light of new information and fresh perspectives. As the only web guy around here I guess I get to make those judgement calls for the institution. But in a freelance situation my time is the client's money, which is definitely a scarce resource. A 0.2% markup cost for things like typographic correctness may not sit well with some clients, but there's plenty of designers out there who also don't care. Maybe they can service those clients.

Thursday, June 04, 2009

.Edu websites and brand perception

I’ve been a member of a site called EduStyle since right after I took this job. It’s a gallery site for higher ed redesigns. I’ve been consistently blown away by the innovations, both visually and technologically, coming out of small, private colleges and universities compared to the standard 4-years.

In regards to technology, Douglas Adams said:

  1. Everything that's already in the world when you're born is just normal;
  2. anything that gets invented between then and before you turn thirty is incredibly exciting and creative and with any luck you can make a career out of it;
  3. anything that gets invented after you're thirty is against the natural order of things and the beginning of the end of civilization as we know it until it's been around for about ten years when it gradually turns out to be alright really.

The modern web was “born” in 1993. We can go with the release of Mosaic and say April 22, in which case the web is now old enough to drive. Or we can move a little later in the year with the Eternal September in which case the web is still stuck with a learner’s permit. Either way, it’s old enough to be shopping around online and planning for its academic future. Our personified web will be a traditional starting freshman come Fall 2011.

A .edu website communicates a lot about the brand of the institution. If we're horribly behind the times in technology that our primary recruiting demographic considers part of the natural order of things, we will suffer for it. I’ve observed a gap developing over the past couple of years, and I admit that our site is on the wrong end of that gap. But I'm trying to catch up.

Compare Yale and Columbia to Denver Seminary and Biola Undergraduate Admissions. I’m picking on the Ivy League and perhaps a bit unfairly. Cornell’s design is good enough that it’s inspired many other redesigns, including our own. But it’s possible that the University of Southern California inspired Cornell.

The reason I single out the Ivy Leagues is because today’s potential students have an innate, subconscious ability to judge us based on our web presence even if they lack the prior knowledge to understand things like published research and accreditation. Does anyone go to the University of Phoenix because of the great research they produce? I highly doubt it. But their website feels more up to date than MIT. We can delude ourselves and pretend that somehow our students are too smart to fall for such marketing gimmicks. But it ain’t just gimmicks to them.

I think it’s easy for us to forget what it’s like to be a teenager shopping for a school. We’ve turned academics into a career, so we forget how alien a world it can be to an outsiders. And let’s be honest, the vast majority of our potential students are outsiders.

I’ve been at the top of my class throughout my entire academic career. I was recommended for West Point and was encouraged to apply to lots of prestigious schools. I didn’t pursue those options because I wanted to stay in Tennessee and I didn’t think I could afford Vandy. I don’t regret those decisions, but I admit I may have chosen differently had I been equipped with a better understanding of financial aid. I didn’t know who SACS was until my alma mater went through their own accreditation review while I was a student. I still don’t know the exact different between a Bachelor of Arts and a Bachelor of Science. If I ever need to list my degrees, I’ve gotta go look that up. I didn’t know my degree from Pellisiippi was an Associates of Applied Science until I literally had the piece of paper in my hand. All I knew was that it was a degree that could advance my chosen career path. I had no reason to care about the academic nomenclature. I doubt today’s students are much different.

Managing and protecting our online brand perception is a big part of my job. As much as I loathe jargon, I can't really think of a better way to say it. I’m lucky to be working on a campus that understands that concept (if not in all the gory technical detail) in spite of the rarity of an administrator who was under 30 in 1993. :)

Wednesday, April 22, 2009

The Proper Care and Feeding of VolState.edu

Most literature on user centered design (UCD) focuses on redesigning existing products or creating wholly new products. No literature I’ve found focuses on applying these ideas to established, mature products in the maintenance stage of their lifecycles. However, with an eye towards abstraction, I think we should be able to take the high-level concepts and apply them to any stage of a product’s lifecycle. My goal with this document is to establish some guidelines for making iterative improvements to VolState.edu using my current understanding of UCD practices, without having to shift into a full redesign.

There is a split among experts in the field of usability. Some strive for true science. Tests use many participants, drawn from the target audience, with tight statistical fit. Conditions are controlled and kept close to real-world environments. Participants use high fidelity prototypes that are functionally complete, or very nearly so. The data such tests produce is significant and reliable. But these tests also cost into the tens or even hundreds of thousands of dollars. Attempts have been made to codify formal systems for web site development, but these systems do little to address the practical concerns of time and money. (De Troyer & Leune, 1998)

In 1989, Jacob Nielsen introduced the concept of discount usability in a paper titled “Usability engineering at a discount”. The gist of the argument, to borrow a phrase from Steve Krug is “Testing with 1 user is 100% better than testing none.” Many people, Nielsen included, have tried to show statistically where the sweet spot for return on investment lies in conducting usability studies. Many other people, such as Jared Spool, have counter argued against such reasoning. Each side tends to rely on math supplemented with anecdotal evidence. This is all well and good as a distraction for academics. Personally, I’m much more interested in producing a better product for our users than in the math and science underlying the methodology.

I’m following Krug’s ideas most closely. He goes even beyond Nielsen’s discount usability into what he calls “lost our lease, going out of business sale usability testing”. Such testing can have value without the need for strict scientific validity. He’s even gone so far as to call himself a usability testing evangelist, actively encouraging people to integrate it into their workflow. In his book, Don’t Make Me Think, he addresses the top 5 excuses for not performing usability testing.

  1. No time – Keep testing as small a deal as possible and you can fit it into one morning a month. The data produced will actually save time by pointing out obvious flaws in a way that sidesteps most possible internal politics and by catching these problems as early as possible, when they are most easily fixed.
  2. No money – Testing can be performed for as little as $50-$100 per session. While that’s not free, it’s far from the $50,000+ price tag of big ticket professional testing. In terms of ROI, it’s one of the wisest investments you can make.
  3. No expertise – Experts will be better at it, but virtually any human being of reasonable intelligence and patience can conduct basic testing that will produce valuable results.
  4. No usability lab – You don’t need one. Since Krug first wrote his book, things have actually gotten even easier with software such as Silverback.
  5. Can’t interpret results – You don’t have to use SPSS to mine for valuable data. The biggest problems will be the most obvious. Even if you only identify and fix the most obvious 3 problems, that’s 3 fewer problems in the final product.

Obviously if my goal were to get published, even as a case study, I would worry a bit more about scientific validity than Krug stresses. Although even among the academic literature some examples of successful case studies can be found where no attempt was made in recruiting beyond very broad user categories. (Bordac & Rainwater, 2008) But my goal in this document is to create a framework for usability testing that is simple and affordable enough to be actionable at Vol State. Ideally, it should be straightforward enough to persist beyond my tenure in this position. For those goals, Krug seems a perfect fit.

Involving Users Through the Development Process

Step 1: Identify a Problem or Unmet Need

Occasionally, users may volunteer information related to areas where improvements are possible or identify desired features not currently available. Anything we can do to encourage and facilitate this can only help.

Direct observation may also provide vital insight. Students may be observed unobtrusively in computer labs or in the library. Employees could be observed, with their permission, within their everyday work environment. Surveys and focus groups may also assist in identifying unmet needs at a high level of abstraction.

Problems exist within the context of users and goals. A proper definition of a problem should identify these contexts. Some possible examples:

  • Students wish they could perform a task online that currently requires a visit to an office on campus
  • Parents want easier access to a certain type of data
  • Faculty need a way to share educational resources
  • Sports fans need a better way of viewing or sorting our events listings

Understanding these contexts is vital to the success of a possible solution. If parents express a desire for easier access to student records, that may very well violate FERPA, in which case that problem is not actionable. Faculty looking for ways to share educational resources may be best served by training on Delicious. Even though we won’t stress a strict statistical fit with our test participants, understanding user groups in broad categories such as this allows for quick and easy targeting which should add value to the data collected via future testing.

Step 2: Establish Benchmark (Where Applicable)

Persistent, longitudinal data collected via survey could also apply at this step. Google Analytics is another powerful tool we have at our disposal. The type of benchmarking would depend greatly on the type of problem. For example, problems that require adding new pages to the site would have no data available in Google Analytics against which to establish benchmarking. But if those pages address an unmet need revealed via surveys that fail to turn up as an unmet need in a future survey, that could serve as a benchmark. (Comeaux, 2008) While I hope to incorporate this step as often as possible, I don’t want it to serve as justification for abandoning a project due to a lack of a method of establishing a proper benchmark.

Step 3: Wireframe Possible Solutions

Brainstorm for possible solutions to the problem. Produce low-fi wireframes such as semi-functional HTML prototypes or paper prototypes. Research seems to indicate that testing multiple prototypes produces more useful data (Tohidi et al, 2006). Test 3 or 4 users loosely recruited from the broad user category identified in step 1. Aim for 3 testable prototypes, but again don’t let this guideline derail an otherwise healthy project.

Step 4: Develop Solution Based on Wireframe Testing

Perhaps a clear winner will emerge from step 3, or perhaps the best possible solution will incorporate elements from multiple prototypes. Entering into the development phase with even a small dose of user involvement cuts down on costs and ensures that we “get the right design.” (Tohidi et al, 2006)

Step 5: Think-Aloud Usability Testing with Prototype

Construct a task list informed by the context and goal(s) identified in step 1. Recruit loosely from the broad user group as in step 3. Spend a morning walking 3 or 4 users through the task list. Record sessions using Silverback. Take quick notes between each session, recording the biggest issues while they are fresh in memory. Produce a single page list of issues, not a full report. Writing formal reports consume a lot of time better invested in fixing problems or further testing. Review session recordings with stakeholders as appropriate.

Step 6: Tweak Based on Testing

Fix the biggest 3 issues revealed in step 5. Avoid the temptation to go for the low hanging fruit until the truly catastrophic issues have been resolved. If something can be fixed with 15 minutes of work, by all means do so. But don’t count that as one of the big 3 unless it is also a major problem. After the big 3 and the easy fixes are addressed, act on any remaining issues as time permits.

Step 7: Launch & Evaluate

Put the solution into production. If benchmarks were established, collect data for a length of time allowing for a reasonable comparison up to a maximum of 1 year. If the data does not indicate improvement (and the criteria for judging this will be highly subjective and depend a great deal on context) consider returning to step 1 with an eye towards testing any assumptions in the original problem description.

Don’t Sweat the Details

Use the tools at our disposal to the best of their ability. Maybe a focus group would be the perfect tool for a given job. But we can pull that off because of finances or because it’s summer and campus is like a ghost town. Move on to a less than perfect solution, or plan to readdress that particular issue when the timing is right. But if we postpone one project, we should find something to keep us busy in the meantime. With a site as large and complex as VolState.edu, we should always be able to find something to improve.

The Tools of the Trade

In this section I will list some of the tools available to us. While I’ve made an honest effort to exhaust my knowledge on the subject, I make no claims to knowing every possible method. We should actively look for new tools and add them to this list as we become aware of them.

Card Sort Studies

These studies are often used for organization and naming conventions. There are 2 varieties. (a) Closed card sort studies involve asking participants to sort pre-determined items into pre-determined categories. (b) Open card sort studies involve asking participants to sort pre-determined items into groups which can then be labeled any way the participant chooses. Such studies are cheap and easy to conduct and provide valuable information within the limited context of language choices and organization schemes. Such problems are commonly reported in the literature involving case studies of university libraries. (Bordac & Rainwater, 2008; Proffitt, 2007; Shafikova, 2005)

Surveys

In the past we’ve had great luck with SurveyMonkey.com. Care should be taken in wording questions in such a way as to avoid biasing the answers. Surveys, particularly those delivered online, allow for a great number of participants from a wide range of our target audience. Smaller, more targeted surveys can also be conducted in person or on paper depending on the need. We also have access to data collected through marketing surveys conducted in 2003, 2008, and hopefully 2009.

Observation

Don’t underestimate the power of simply watching people using a system under normal conditions. Observation alone will often only produce hints or assumptions about possible problem areas. But that can be a great starting point from which to branch out into interviews or surveys. In the case of formal observations, such as with employees, a quick follow up interview can probe for more details immediately. (Pekkola et al, 2006)

Focus Groups

While there are dangers associated with relying too heavily on preference and opinion based data such as that produced by focus groups, they can provide data useful to our purposes. For example, it could be a great way to test assumptions arrived at through observing students using the website at the library. We’ve observed students doing X, which we assume is a way of working around problem Y. We could conduct a focus group to discover if Y really is a problem at all, or if students are engaging in behavior X for reasons we didn’t think of. Focus groups are most effective when drawn from within a single user category. For example, we probably would not want to mix students and faculty in the same focus group, nor faculty and administrators for that matter. (Kensing & Blomberg, 1998)

Interviews

Interviews could be paired with observations, helping to clarify and test assumptions much like a focus group. Or they could be used to help us construct personas. They would be most useful early on to help explain the context within which a given problem may be occurring.

Prototypes

Paper mock ups for a possible user interface can be produced quickly and cheaply. In a team environment, building such prototypes could even become a collaborative, iterative process. Some teams have reported success even with complex interactive paper prototypes. (Tohidi et al, 2006; see also i ♥ wireframes) Testing with such low-fi prototypes can lead to a greater willingness for participants to offer criticism since it’s obviously a work in progress.

HTML prototypes can range from semi-functional to fully functional. I’m personally much better at HTML wireframing than illustrating, so in the absence of outside assistance I will probably rely on HTML prototypes for both low-fi and high-fi testing.

Personas

Using demographic data, marketing research, and perhaps focus groups/interviews to construct an idealized but fictional user can help make user needs more personal and real (ironically enough) to a development team. Knowing that we have students with family and work obligations is important. But building a persona around that particular cluster of user attributes can make it easier to relate to and also give the development team a shorthand for addressing those issues.

For example, we could create a persona named Barbara who is a single mother of 2, working full time graveyard shift as a manager at a 24 hour restaurant, attending Vol State for 3-6 hours per semester working on a degree in Hospitality Management. She tries as often as possible to take classes on Tuesday/Thursday to minimize the burden of day time child care. She’s not technologically proficient, but she’s willing to learn. If given the choice between driving 45 minutes to campus or performing a task online, she prefers the online option in spite of her technological limitations.

That’s a very basic persona, but it still gives us enough detail to say “But what about Barbara?” rather than “But what about students who may have family or work obligations that prevent them from easily making an on campus visit on Mondays and Wednesdays?” Obviously personas could have applications outside of the realm of website development. Barbara could also provide insight into event planning, for example.

Think-Aloud Usability Study

This is the crown jewel in my usability toolbox. In a nutshell, it’s as simple as sitting a real human being in front of your product and watching them try to make sense of and use it. Ideally, you should have some specific tasks to ask them to perform and keep them talking about what they are looking at, what they think they should do next, what they expect to happen when they do it, their reaction to what actually happens when they do it, etc.

Full descriptions of the methodology can be found in lots of different places. I personally recommend Krug’s book. He’s even made the final 3 chapters of the first edition available on his website as a free download. Those chapters contain the bulk of the info on this sort of testing. There are other books, academic articles, and even blogs available, so pick your poison. Jakob Nielsen and Jared Spool have both written prolifically across many distribution channels.

Heuristic Study/Expert Review

My list would not be complete were I to leave this off, but personally I find this the most suspect. The general idea is you have an expert go over the interface and critique it based on a list of guidelines. This idea originated with Nielsen too and his list of guidelines can be found on his website. (Nielsen, 2005)

The highest value should be placed on methods that involve observations of real people interacting with some form of the interface in question. Preference and opinion based methods, such as surveys, focus groups, and interviews, can be quite effective for collecting marketing type data. But usability data relies too heavily on context for these methods to work alone. (Krug, 2008) However, any methods requiring direct human contact in the context of a college campus present a particular problem.

Sweat Some Details, but Document Them

One detail we have to sweat is the Institutional Review Board. All those highly valued methods that involve human interaction will require IRB approval. Even with approval, there’s no guarantee that a particular methodology will work. For example, I recently put together a proposal for a card sort study that failed to successfully recruit any participants. The good news is I’ve learned one method that does not work on this campus, so we can avoid any recruitment schemes that rely solely on face to face recruitment with no offers of compensation in the future. Eventually we will discover methods that both appease the IRB and meet with success out in the field. When that happens, we should save the IRB proposal, the information letter, the release forms, and all other deliverables. The next time the need for such a test comes up, we can build on the previous success. Many researchers, Krug among them, provide examples of their own materials that we can also integrate into our workflow.

Recommendations

  • Develop an easy to use feedback mechanism into VolState.edu such as a simple for to “Report a problem with this page” or an Amazon style “Was this page helpful to you?” tool. Possibly both.
  • Develop a standardized survey to be delivered via SurveyMonkey.com on an annual basis. Collecting standardized, longitudinal data will allow for some forms of benchmarking. Each iteration of the survey can include a handful of questions of a more timely nature in addition to the standard set. For example, a question about a specific change made in the past year.
  • Continue to develop our use of Google Analytics for statistical and possible benchmarking data. However, do so with the understanding that Jared Spool has called analytics “voodoo data” because they lack context. (Spool, 2009)
  • Integrate user testing to provide the context currently missing from our toolset as laid out in the 7 step model above.

Bibliography

  • Bordac, S, & Rainwater, J (2008). User-Centered Design in Practice: The Brown University Experience. Journal of Web Librarianship.
  • Comeaux, D.J. (2008). Usability Studies and User-Centered Design in Digital Libraries. Journal of Web Librarianship.
  • De Troyer, O, & Leune, C (1998). WSDM: a user centered design method for Web sites. Computer Networks and ISDN Systems.
  • Kensing, F, & Blomberg, J (1998). Participatory Design: Issues and Concerns. Computer Supported Cooperative Work.
  • Krug, S (2005). Don't Make Me Think: A Common Sense Approach to Web Usability, 2nd Edition. New Riders.
  • Krug, S (2008). Steve Krug on the least you can do about usability. Retrieved April 22, 2009, from blip.tv Web site: http://blip.tv/file/1557737/
  • Nielsen, J (2005). Heurisitics for User Interface Design . Retrieved April 22, 2009, from useit.com: usable information technology Web site: http://www.useit.com/papers/heuristic/heuristic_list.html
  • Pekkola, S, Kaarilahti, N, & Pohjola, P (2006). Towards formalised end-user participation in information systems development process: bridging the gap between participatory design and ISD methodologies. Proceedings of the ninth conference on Participatory design: Expanding boundaries in design. 1, 21-30.
  • Proffitt, M (2007). How and Why of User Studies: RLG's RedLightGreen as a Case Study. Journal of Archival Organization. 4
  • Spool, J Journey to the Center of Design. Retrieved April 22, 2009, from YouTube Web site: http://www.youtube.com/watch?v=WCLGnMdBeW8
  • Tohidi, M, Buxton, W, Baecker, R, & Sellen, A (2006). Getting the right design and the design right. Proceedings of the SIGCHI conference on Human Factors in computing systems

Monday, April 13, 2009

Version Control for the Web

Does #lazyweb work on blogs?

So I've had an idea. And it may be what finally gets me to implement a version control system around here.

A little over a year ago, I did a survey with our website visitors (by “our website” I mean VolState.edu). I expected the biggest problem to be reported would be trouble locating information. I have full access to the server and have worked directly with the file structure for nearly 2 years now and I still have trouble finding stuff. I was surprised to see that problems with findability were the 2nd most commonly reported. #1 went to outdated info.

I assume the 2 problems feed off each other. You spend 15 minutes trying to find something, and then once you finally locate it, it's obviously out of date. I know I'd be upset if placed in the same situation. And unfortunately that's a situation we place our website visitors in every day.

I can publish content updates once they cross my desk, but I can't summon them from thin air. But I also realize we've got a lot of busy people on this campus who may not have the time to proofread their web content and alert me when updates are needed. I could use that as an excuse, pass the buck, and move on with my life. But I don't like that.

One thing I've done in the redesign is to link to content from a single authoritative source as often as possible. For example, the current site often lists course and curriculum info. (I'm using our Health Information Technology program as an example here, but most of our programs follow this model.) Now that's important info for both current and potential students, so I understand why we'd want to publish it. But that's redundant info that can quickly fall out of date. The catalog is the definitive source for course descriptions and curricula info. I can also count on that getting updated every year. Thankfully, Acalog, our 3rd party online catalog service, makes it possible to link to individual program descriptions. So the redesigned program pages send people there for the course and curriculum info.

That's one less point of possible failure. I know those pages will be kept up to date. I no longer have to worry about them, and neither do the deans and program directors.

Along the same lines, I'm thinking about a way to implement a reporting system that could alert me to each page that has gone X days without an update. I figure a good version control system would support this, but at this stage that's a big assumption on my part.

But if that's possible, I could create a system where the people responsible for providing content would be notified when a page could potentially be out of date. If nothing has changed in the past X days to render the content out of date, that's fine, but I'd like to be able to document that. I don't want to be seen as The Web Nazi, but if the first gentle reminder fails to get any feedback, I could follow up in a month or so including traffic figures from Google Analytics. “X people have viewed potentially out of date information on http://www.volstate.edu/YourDirectory/ since [date of initial notice]”

So my goals for this week are to generate a deliverable for my user centered design course (I tried a research project, but that failed to materalize once I hit the recruitment stage, still learned a lot though) and researching SVN, Git, CVS, etc.

Thursday, February 12, 2009

Javascript performance testing

I've been horribly disappointed with IE's performance with some of my javascript, so the point that I've pretty much decided to simply hide the troublesome functions from IE users. That's nearly 85% of our audience who won't get to experience the work I've put in to some of this stuff. I thought I needed to get some actual figures on performance, so I took the worst offender and turned it into a test case. Then I thought while I'm doing that I might as well compare jQuery 1.2.6 to jQuery 1.3.1. So I made a 2nd test case.

First of all, you need to understand that I'm terribly abusing the plugin in question. I'm using treeview to do the online version of our organizational chart. There's a demo showing how it works with large lists. That demo has 290 total list items, 53 of which are expandable. Our org chart has 403 list items, 81 of which are expandable. It's large enough that I had to edit the default images to extend all the way down the fully expanded list.

I added a crude counter to the plugin. Here's the code. The lines involving Date() and getTime() and alert() functions are my additions (114 to 127 or so). It's far from perfect, but it should be equally imperfect for all browsers and therefore free of bias. What this does is whenever the expand all or collapse all function is triggered, it grabs the time early on in that process, then grabs the time again near the end of that process, computes the difference (in milliseconds) and alerts the value. In each browser I expanded the list, recorded the value, collapsed the list, recorded that value, and repeated the process until I had 15 measurements for both the expand and the collapse feature.

The Data

We'll do the Mac browsers first. I'm running on a 20 inch iMac with a 2.0 gHz Intel Core Duo processor and 4 gigs of RAM. I ran these tests under "normal" conditions. So I had other applications going and in the case of Firefox several other tabs open.

All figures are in milliseconds.

Firefox 3.0.6

jQuery: 1.3.1 1.2.6
Expand Collapse Expand Collapse
Tests
  1. 838
  2. 840
  3. 847
  4. 826
  5. 827
  6. 821
  7. 839
  8. 835
  9. 827
  10. 827
  11. 825
  12. 839
  13. 824
  14. 816
  15. 845
  1. 1178
  2. 1184
  3. 1183
  4. 1188
  5. 1188
  6. 1184
  7. 1187
  8. 1205
  9. 1186
  10. 1190
  11. 1189
  12. 1182
  13. 1185
  14. 1182
  15. 1190
  1. 506
  2. 514
  3. 511
  4. 493
  5. 482
  6. 513
  7. 480
  8. 510
  9. 493
  10. 484
  11. 508
  12. 484
  13. 492
  14. 512
  15. 491
  1. 1006
  2. 1024
  3. 999
  4. 998
  5. 1011
  6. 998
  7. 1010
  8. 1003
  9. 1009
  10. 1008
  11. 1005
  12. 1002
  13. 1000
  14. 997
  15. 994
Min 816 1178 480 994
Max 847 1205 514 1024
Range 31 27 34 30
Median 827 1186 493 1003
Average 831.73 1186.73 498.2 1004.26

The most surprising thing here is that jQuery 1.2.6 is actually a bit faster than 1.3.1. Of course, 1.3.2 is supposed to release soon. And as we'll see that's not true for every browser. Collapsing takes longer than expanding. I'll leave explaining that to someone that knows more about jQuery DOM transversal.

Safari 3.2.1

jQuery: 1.3.1 1.2.6
Expand Collapse Expand Collapse
Tests
  1. 262
  2. 256
  3. 267
  4. 269
  5. 264
  6. 269
  7. 266
  8. 267
  9. 270
  10. 270
  11. 267
  12. 269
  13. 292
  14. 267
  15. 267
  1. 161
  2. 159
  3. 164
  4. 163
  5. 167
  6. 164
  7. 169
  8. 165
  9. 163
  10. 164
  11. 165
  12. 164
  13. 164
  14. 166
  15. 166
  1. 311
  2. 311
  3. 326
  4. 316
  5. 314
  6. 311
  7. 311
  8. 319
  9. 312
  10. 314
  11. 310
  12. 316
  13. 318
  14. 318
  15. 317
  1. 147
  2. 146
  3. 149
  4. 151
  5. 148
  6. 148
  7. 146
  8. 149
  9. 149
  10. 149
  11. 149
  12. 151
  13. 148
  14. 152
  15. 150
Min 256 159 310 146
Max 292 169 326 152
Range 36 10 16 6
Median 267 164 314 149
Average 268.13 164.27 314.9 148.8

At first I thought the performance boost for 1.3.1 here was pretty small, but I think the fact that all the numbers involved is tiny threw me off. If you add up the median figures, you'll find a difference of about 7.5%. That's nothing compared to the relative advantage Safari already has over most of the other browsers, but I think it's still a decent speed boost for the new jQuery release.

Safri's js engine is awesome. :)

Can anyone explain why in Safari collapse is quicker than expand, but in Firefox it's the other way around?

Opera 9.63

jQuery: 1.3.1 1.2.6
Expand Collapse Expand Collapse
Tests
  1. 692
  2. 690
  3. 737
  4. 667
  5. 711
  6. 703
  7. 715
  8. 703
  9. 704
  10. 692
  11. 719
  12. 680
  13. 731
  14. 695
  15. 682
  1. 698
  2. 709
  3. 721
  4. 709
  5. 715
  6. 730
  7. 697
  8. 695
  9. 692
  10. 696
  11. 705
  12. 704
  13. 697
  14. 713
  15. 696
  1. 875
  2. 944
  3. 904
  4. 875
  5. 872
  6. 869
  7. 864
  8. 929
  9. 905
  10. 910
  11. 891
  12. 885
  13. 926
  14. 857
  15. 918
  1. 691
  2. 711
  3. 692
  4. 692
  5. 684
  6. 692
  7. 741
  8. 688
  9. 652
  10. 687
  11. 674
  12. 707
  13. 701
  14. 692
  15. 690
Min 667 692 857 652
Max 737 730 944 741
Range 70 38 87 89
Median 703 698 891 692
Average 701.4 705.13 894.93 692.93

Opera seems slow compared to Safari, but it's on par with Firefox, and more than tolerable. We also see a decent speed boost with 1.3.1 here.

Windows Browsers

I'm running Windows XP via virtualization with 412 megs of RAM. These tests were run with no other running applications, so more "ideal" conditions than the Mac browsers got. Then again, the Macs get a ton more RAM and aren't running in a virtual machine. I tested both Firefox 2 and Firefox 3 because a decent portion of our Firefox using audience haven't upgraded yet.

Firefox 2.0.0.20

jQuery: 1.3.1 1.2.6
Expand Collapse Expand Collapse
Tests
  1. 1018
  2. 1069
  3. 1019
  4. 1019
  5. 1019
  6. 1019
  7. 989
  8. 1049
  9. 1019
  10. 989
  11. 1029
  12. 1009
  13. 1029
  14. 999
  15. 969
  1. 1169
  2. 1109
  3. 1129
  4. 1129
  5. 1139
  6. 1159
  7. 1129
  8. 1189
  9. 1149
  10. 1129
  11. 1128
  12. 1129
  13. 1129
  14. 1189
  15. 1119
  1. 629
  2. 629
  3. 609
  4. 649
  5. 609
  6. 639
  7. 619
  8. 629
  9. 619
  10. 649
  11. 630
  12. 629
  13. 640
  14. 629
  15. 639
  1. 740
  2. 719
  3. 739
  4. 729
  5. 749
  6. 749
  7. 749
  8. 730
  9. 739
  10. 739
  11. 759
  12. 750
  13. 759
  14. 719
  15. 769
Min
Max
Range
Median
Average

Here we're starting to get slower than I'd like. A full second for anything to happen is a bit much. Then again, 403 list items in 81 lists is a lot of munch on. Once again we loose a little speed with the new jQuery release. Hmm.

Firefox 3.0.6

jQuery: 1.3.1 1.2.6
Expand Collapse Expand Collapse
Tests
  1. 431
  2. 449
  3. 461
  4. 434
  5. 464
  6. 472
  7. 558
  8. 493
  9. 481
  10. 436
  11. 457
  12. 442
  13. 472
  14. 462
  15. 458
  1. 657
  2. 688
  3. 648
  4. 623
  5. 657
  6. 708
  7. 632
  8. 650
  9. 695
  10. 649
  11. 634
  12. 649
  13. 648
  14. 659
  15. 625
  1. 450
  2. 467
  3. 424
  4. 475
  5. 443
  6. 456
  7. 446
  8. 472
  9. 460
  10. 477
  11. 449
  12. 464
  13. 483
  14. 468
  15. 440
  1. 618
  2. 650
  3. 634
  4. 638
  5. 667
  6. 637
  7. 632
  8. 632
  9. 646
  10. 643
  11. 622
  12. 614
  13. 628
  14. 651
  15. 640
Min
Max
Range
Median
Average

Here we go! Come on Firefox users, update already!

Safari 3.2.1

jQuery: 1.3.1 1.2.6
Expand Collapse Expand Collapse
Tests
  1. 253
  2. 326
  3. 277
  4. 257
  5. 268
  6. 288
  7. 278
  8. 269
  9. 244
  10. 271
  11. 264
  12. 281
  13. 284
  14. 281
  15. 293
  1. 141
  2. 171
  3. 148
  4. 160
  5. 147
  6. 143
  7. 147
  8. 150
  9. 151
  10. 171
  11. 163
  12. 158
  13. 154
  14. 142
  15. 147
  1. 303
  2. 300
  3. 324
  4. 327
  5. 313
  6. 312
  7. 283
  8. 297
  9. 355
  10. 332
  11. 367
  12. 332
  13. 360
  14. 317
  15. 307
  1. 130
  2. 133
  3. 129
  4. 134
  5. 135
  6. 134
  7. 129
  8. 130
  9. 132
  10. 130
  11. 133
  12. 135
  13. 148
  14. 133
  15. 129
Min
Max
Range
Median
Average

Safari continues to be awesome, even on Windows. :)

Opera 9.63

jQuery: 1.3.1 1.2.6
Expand Collapse Expand Collapse
Tests
  1. 470
  2. 480
  3. 469
  4. 480
  5. 480
  6. 499
  7. 490
  8. 580
  9. 469
  10. 519
  11. 460
  12. 470
  13. 479
  14. 563
  15. 480
  1. 399
  2. 410
  3. 429
  4. 409
  5. 419
  6. 399
  7. 419
  8. 409
  9. 400
  10. 400
  11. 400
  12. 430
  13. 410
  14. 399
  15. 399
  1. 949
  2. 989
  3. 949
  4. 929
  5. 939
  6. 939
  7. 939
  8. 929
  9. 939
  10. 939
  11. 959
  12. 949
  13. 958
  14. 1009
  15. 989
  1. 370
  2. 380
  3. 390
  4. 409
  5. 400
  6. 390
  7. 370
  8. 390
  9. 380
  10. 400
  11. 399
  12. 420
  13. 380
  14. 400
  15. 420
Min
Max
Range
Median
Average

With Opera on Windows, we see some pretty solid speed boosts with the 1.3.1 release of jQuery.

Chrome 1.0.154.48

jQuery: 1.3.1 1.2.6
Expand Collapse Expand Collapse
Tests
  1. 229
  2. 203
  3. 191
  4. 195
  5. 158
  6. 208
  7. 201
  8. 188
  9. 204
  10. 244
  11. 360
  12. 327
  13. 307
  14. 305
  15. 178
  1. 88
  2. 77
  3. 119
  4. 88
  5. 79
  6. 106
  7. 84
  8. 86
  9. 95
  10. 158
  11. 116
  12. 145
  13. 135
  14. 61
  15. 81
  1. 512
  2. 598
  3. 546
  4. 607
  5. 607
  6. 640
  7. 526
  8. 674
  9. 545
  10. 631
  11. 549
  12. 635
  13. 581
  14. 616
  15. 531
  1. 111
  2. 112
  3. 133
  4. 115
  5. 109
  6. 105
  7. 103
  8. 103
  9. 105
  10. 106
  11. 133
  12. 112
  13. 109
  14. 110
  15. 114
Min
Max
Range
Median
Average

Chrome also sees some good boosts from 1.3.1 and manages to out awesome even Safari. When you look at the range as a percentage, it's all over the place. Sometimes the alert box would have a check box in it that would say something to the effect of "prevent this site from producing alert boxes" and I think those tended to take longer to generate. Maybe Chrome's doing other stuff behind the scenes. I'd need to do more specific research to figure this one out.

IE 7.0.5730.13

jQuery: 1.3.1 1.2.6
Expand Collapse Expand Collapse
Tests
  1. 2990
  2. 2897
  3. 2867
  4. 2917
  5. 3016
  6. 2877
  7. 2877
  8. 2847
  9. 2907
  10. 2897
  11. 2877
  12. 2916
  13. 2897
  14. 2888
  15. 2848
  1. 1718
  2. 1738
  3. 1832
  4. 1718
  5. 1668
  6. 1708
  7. 1678
  8. 1678
  9. 1698
  10. 1709
  11. 1728
  12. 1738
  13. 1689
  14. 1688
  15. 1708
  1. 2538
  2. 2587
  3. 2557
  4. 2557
  5. 2577
  6. 2568
  7. 2567
  8. 2557
  9. 2548
  10. 2707
  11. 2548
  12. 2708
  13. 2558
  14. 2568
  15. 2568
  1. 1248
  2. 1219
  3. 1249
  4. 1248
  5. 1279
  6. 1249
  7. 1208
  8. 1228
  9. 1258
  10. 1229
  11. 1229
  12. 1239
  13. 1389
  14. 1229
  15. 1239
Min
Max
Range
Median
Average

Ugh! I'm in browser hell! What's up with this? 2.5 to 3 seconds to expand the list? Come on!

IE6

I don't know the exact version number here because of the way the Multiple IE installer works.

jQuery: 1.3.1 1.2.6
Expand Collapse Expand Collapse
Tests
  1. 10779
  2. 12577
  3. 13060
  4. 14085
  5. 15034
  6. 16123
  7. 17272
  8. 19549
  9. 19859
  10. 21121
  11. 23080
  12. 23249
  13. 24961
  14. 24770
  15. 25953
  1. 4935
  2. 5165
  3. 5774
  4. 5964
  5. 6314
  6. 7032
  7. 7152
  8. 8021
  9. 8231
  10. 8611
  11. 9082
  12. 9402
  13. 9892
  14. 9959
  15. 10349
  1. 11078
  2. 12617
  3. 13167
  4. 14785
  5. 15684
  6. 16876
  7. 19643
  8. 21740
  9. 20642
  10. 21947
  11. 22726
  12. 23925
  13. 36235
  14. 28810
  15. 29422
  1. 3899
  2. 4005
  3. 4356
  4. 4715
  5. 5105
  6. 5534
  7. 6453
  8. 7366
  9. 6842
  10. 7453
  11. 7801
  12. 8241
  13. 9700
  14. 9364
  15. 9849
Min
Max
Range
Median
Average

No. I was wrong before. This is browser hell. Notice how each test gains about 1 full second? I think that means we've got memory leaks. I closed and relaunched the browser between test cases to avoid skewing the results between jQuery versions.

I'll complete the number crunching and do a bit more in depth analysis tomorrow. It's 5 o'clock and I'm heading home for the day.

Monday, December 15, 2008

Cleaning up the existing site

At first I thought we'd be launching the redesign before our SACS review. The powers that be have other plans. At first I was happy to have a few extra months to work and test and debug prior to launch. But then it hit me. I was gonna need to clean up the site content for the review. That means I've got to deal with the pretty much total lack of any real information architecture on the existing site.

As a first pass, I ran a site wide link report. My first step was to get rid of the orphans. I quickly discovered 2 problems wit this idea.

  1. The current site uses many JavaScript driven pop up windows using code generated by GoLive. DreamWeaver apparently doesn't know how to check these links. Therefore all such content shows up as orphaned.
  2. Ditto for the Flash stuff. This is more surprising since Flash is also a Macromedia product from back in the day. This means the the thousands of photos we have in the various Flash driven galleries all show up as orphans.

The initial report said that out of 24,000+ files, 13,000+ were orphans. More than half the files on the server showed up as not being linked to at all. Of those 24,000-something files, 10,626 were HTML/ASP files. The rest were images, PDFs, and stuff like that. We're now down to a total of 19,957 files, 9,413 of which are HTML/ASP. But 6,138 still show up as orphaned. I bet a few of those really are orphans. Probably no more than 200. And most of those would be images. I'm primarily worried about indexable content that could turn up in a Google search but present horribly outdated information. The trouble there is not all of those files are orphaned. We're still linking to many of them. I guess the next step will be to search for obviously outdated files. Stuff with years in the file names, for example. Then I'll probably need to run another orphan check for freshly orphaned files once that content is cleaned up.

The good news is I've reduced the size of my local directory by 45%, from about 3.4 gigs to 1.9 gigs. The majority of that was the files we're still hosting from last year's CIT conference. But I never need to update those, so there's no need to store them locally. Some of those PowerPoint files got crazy big.

Of course, currently the beta site takes up a total of 339 megs. But it's not quite complete. Still, I'll be surprised if it grows to anywhere near 1.9 gigs before launch. Due to simple changes like getting rid of tables for layout and abandoning the <font> tag in favor of CSS we've shaved about 35k per page. We've also eliminated many pages. The beta site currently contains just 985 PHP files. That's about 10% of the files the current site contains, but we've migrated way more than 10% of the content. One of the big changes in that regard is that we now link to the online catalog for curriculum and course descriptions. There goes 2 pages per degree program plus at least a page per course offered. I think the current site has a lot of redundancy in course description pages among the various program directories. Most of the remaining content will be database driven.

Wednesday, December 10, 2008

My personal knowledge management problem

Full Disclosure:

This post and probably a couple of future posts will serve to fulfill a requirement in my graduate course on knowledge management. But I'm trying hard to approach this in such a way that such requirements are totally transparent asside from this note. Maybe I'll pull it off and this will bear some interest for folks other than my proff. Or maybe I'll totally drop the ball and not engage anyone with this content and totally screw up the assignment to boot. If so, maybe I'll at least fail spectacularly enough to get some good schadenfreude going.


I tried going through the exercises Kirby put together. The basic goal is to figure out which tasks I perform as a knowledge worker bring the most value to my organization, then figure out how much of my time I spend on those tasks vs. less valuable tasks, then try to maximize the time I can devote to the valuable stuff and minimize the time wasted (although that's a slightly harsher term than it needs to be in this context) on less valuable tasks.

I'll be honest, I don't think those exercises work for me right now. There's a couple of reasons for this.

  1. I'm 18 months in to this job and the task that has dominated my time thus far, redesigning the website (we launched the beta by the way, I don't think I took the time to announce that officially here, although I did on the Vol State blog), is not typical of the work someone in this position would be doing otherwise. Once the redesign launches, the way I work will shift, rather radically. It's hard if not impossible for me to look at the last 18 months and make conjectures for the next 18 months.
  2. The biggest drain on my productivity falls outside of my realm of influence; IE it's a trend I am powerless to address. I won't go into detail here but Kirby if you want specifics just email me and I'll fill you in.

So I've been looking at the way Kirby breaks down his model of personal knowledge management and one area I see a lot of room for improvement in the way I currently handle things is with information organization and retrieval. The sad part is I've been sitting on the tools to address this issue for years. I just need to be mindful of how I use them.

I signed up for a Ma.gnolia account back when they were still in beta. I used it for a while, then I found Stumble Upon (hereafter: SU). My thoughts at the time were that SU did all the social bookmarking stuff I had been using Ma.gnolia for with the added element of discovery of new content at the push of a button. That's true in theory. 2 years later, it's obvious that it falls apart in practice.

SU does the whole discovery thing very well. I don't think I ever would have found jQuery without SU. I had been underwhelmed by the JavaScript libraries I had seen during the first few months of that whole buzz and had pretty much written off the whole idea. I was just gonna stick to writing my own custom unobtrusive JavaScript using the Document Object Model. Now I literally use jQuery every day. My job would not be the same without it.

But I discovered jQuery at a time when I actually had the time to take on the learning curve, as gentle as it may be. The official documentation is complete enough that managing access to the information I needed to direct my own learning wasn't an issue either. The only exception I could find to that would be the plug ins, but truth be told if the plug in doesn't make intuitive sense and isn't well documented, I don't use it.

Compare that to some things I hope to learn more about in the near future, such as Drupal and Cake PHP or Perl. Or even compare it to some of the stuff I'm already using but need to reference source material rather than working from the top of my head, like regular expressions and PEAR or Active Directory. Now we're talking about steeper learning curves just as what little time to learning new skills is shaved away as I try to push the redesign through the beta testing phase and into launch. I keep stumbling onto sources for these topics, but lacking the time to fully digest them, I thumb them up and move on.

Ok, that last statement begs the question, if I don't have time to digest this stuff how do I have time to keep stumbling onto new content? First of all, SU is addictive. On top of that, it's so easy to just click the stumble button (with or without specifying a topic to stumble through, such as web design) that I can click through a fresh page or two while I'm checking in the files I just completed working on in Dreamweaver (hereafter: DW). Or while I wait for DW to generate the broken link reports I've been running lately. Actually, now that I bring that up, I really hope DW performs better on the redesigned site. The current site is such a mess of spaghetti code that DW is prone to take its sweet time or even crash when I ask it to perform a site wide action. The redesign is much leaner. Based on the work done so far, the code we shave off should be equivelant to about 68 copies of the complete works of Shakespeare. No, really. Project Gutenberg has the complete works of Shakespeare as a plain text file. I've done the math. :)

This is where the problem comes in. I find these great resources, or at least potentially great, but going back to find them later gets to be a real pain. Sometimes I don't take the time to write my own tags for a page. I just thumb it up and switch back to DW or click the stumble button again. But SU being socially driven, the tags default to the category chosen by the person submitting the site. I currently have 143 stumbles tagged with “graphic-design”. I'm not a graphic designer. I don't really even consider myself a web designer. If you want to split hairs, I consider myself more of a web developer. When I tag an article relating to design, I use “web-design”. I've got 418 of those. But it's possible I didn't personally tag all of them. If the person submitting them tagged it as “web-design” and I just thumbed it up and moved on without bothering to apply my own tags to it, then that's how it would default. It's obvious that graphic design is a pretty popular tag in the wild and the zeitgeist is polluting my tag cloud.

An Example

Over a year ago (November 1st of 2007 according to my SU history), I stumbled upon Scott Jehl's StyleMap script. At the time I thought, “This is how we need to do the org charts.”. Previously we had done the org charts in Microsoft Viso and then those files were exported to HTML. But that produces a tangled mess of frames and images. It's hard to navigate, hard to maintain, and doesn't even work on my Mac (thanks Microsoft). I thumbed it up and moved on.

In October of this year, I finally turned my attention to the org charts for the redesign. I remembered stumbling upon this script a long time ago that would be perfect. But I couldn't find it in my SU history. I tried Google searching every combination I could think of. I literally wasted an entire day trying to find this script.

The problem was the default tag the page was assigned had nothing to do with how I conceptualized the content of the page. I don't even remember what it was now and I have since gone back and edited the entry with my own tags. Google wasn't working because I had forgotten that it was written as a script to do site maps rather than org charts. To add insult to injury, when I finally dug up the article and tried to put the script into use, our org chart proved to be way too complex. But I could have discovered that in an hour had I not wasted an entire day (and part of the following morning) digging up the script.

The Problem

Partly due to flaws in the way I use it, and partly due to flaws in the way it's designed, SU is failing me as a means of efficient information organization and retrieval. In defense of the development team behind SU, it is designed more as a discovery engine than as an organization tool. And I can't sing enough praises as to how well it performs its core function.

The Solution?

So I turn my attention to my neglected Ma.gnolia account. If I start using both these tools to perform the tasks for wich they were designed, and approach my use of these tools in a mindful way, I think I can milk a lot more productivity out of my days. I'll map out that plan in a future entry. Stay tuned.

Friday, September 12, 2008

The joys of debugging

Looking at other people's code can be enlightening. I've been looking for an excuse to try out Benjamin Keen's smartlist plugin for jQuery for a while now. (The jQuery website was recently redesigned and is even more awesome now.)

One of the most important questions a potential student may hope to answer on our website is “Can I get the degree I want?” Actually, it's probably a bit more abstract than that. I know when I evaluate schools, from my own time at a community college to my undergrad days to my current graduate program, I care less about the degree than I do about the topics covered and the skills developed. I care about the topics because if I'm going to devote a couple years of my life to a program, I want to make sure it will hold my interest. The skills are important because ultimately that's what gives me an edge in my chosen job market. I doubt anyone surfs over to our website specifically looking for a degree in biotechnology, but s/he may have an interest in chemistry and biology already and may be considering a career path where such a degree offers a competitive edge.

In it's simplest form, this question could be written as “What do you have to offer me?” (The only question more important than this one is probably “How much will it cost me?”) Each student evaluates that question through criteria specific to his or her needs, wants, and experiences. The form of this evaluation follows traditional models of interpersonal communication (that is, a spoken conversation) more so than print materials. We really need a new model for a new communications medium, but I'll leave that for this generation's Peirce or McLuhan or Leary. (No, really. Leary wrote and lectured on cyberspace and virtual reality after the whole LSD thing blew over.) In the mean time, the idea of a conversation fits better than the idea of a book or newspaper article.

If you've taken a look at the smarlists demo you may see where I'm going with this.

The ability to tag (or flag, as Ben calls it) the items in a smartlist can foster the sort of back and forth communication that the web thrives on. This is something that will need a lot of testing, of course, because the initial set of tags may not fit the words in the minds of our students. There's also a careful line to walk between providing enough tags to make the ability to sort through the data useful vs. introducing a new flavor of information overload. It's very experimental, but I think it can be done right and I think it can be a great help to our students, both current and potential.

So yesterday I actually started building this new application for the redesigned site (still only available via IP from on campus, I'll link it here once we publicly release the beta). The first thing I notice is the demo uses a table. I furrow my brow, thinking a table isn't necessarily the best way to approach this as far as semantics go. I look a bit closer and realize the plugin is written in such a way to allow me to use any html tags I want. I just need to apply the right classes to those elements so the script knows what everything means. Ideally, I'd like to use a definition list. But that would require me to wrap each <dt> / <dd> set in a <div> since the script expects the list of tags (or flags) to be a child element of (that is, contained completely inside) the element defined as an “item”. I don't think a <dl> likes being filled with block level elements like <div>s between itself and its children. I could do a definition list per item, but that seems like over kill. Eventually, I settled on an unordered list with a few paragraph tags inside the list items and appropriate classes scattered throughout.

I build enough of the list that I feel it's testable. In hindsight, I should have built the smallest possible test case, something like 3 items and 4 tags. Everything worked fine as long as you clicked links. Pagination worked. Filtering by clicking on the tags worked. Resetting the list by choosing the default option on the drop down list also worked. Selecting a tag from the drop down resulted in all items being hidden. Strangely, the pagination still worked. In other words, if the list is showing 10 items per page, and you select a tag with 25 items, you get the links for 3 pages just like you should. But all 3 pages are blank. I run in to this particular error around lunch time yesterday. I pour over the code for about 3 hours looking for differences between my local, broken code and the functioning code published with the demo. It appears to be exactly the same, and it should be, I downloaded from the source, right?

Eventually, I check the jQuery code on the demo. That's version 1.2.3. I'm running 1.2.6 (actually just one revision removed, 1.2.4 and 1.2.5 were skipped for various reasons). I ran into a similar problem with a plug in when 1.2.3 was new. Back then I found a page in the documentation that explained exactly what functions were changed and how. That made it very easy to discover a couple of functions were being called that were no longer available. I replaced those 2 functions with the new single function that supersedes them in the new version and was back up and running in less than an hour. This time around, I the documentation on the changes (short version, full version) between versions was less helpful. :(

But at least now I know it's a problem due to changes in the most recent version of jQuery. Now I feel justified in contacting the author directly. I use the form on Ben's site to contact him, explaining what I've found so far so at least he knows I tried to fix the problem myself, and ask if he has put any work into updating the plugin that just haven't been published to the site yet. I go back to troubleshooting for about half an hour before I bother checking for a reply. Turns out that was a mistake because he replied almost immediately. He said I was the 3rd person to write him on the same issue and it seems to be a change to the inArray() function but he hasn't tracked down the exact nature yet.

I start to reply talking about how that doesn't seem to make sense because I had just read over that bit of code in the half hour since I first wrote him and the inArray() function is called the same way no matter which event triggers the action. Since it works fine when clicking a link but fails when selecting from the drop down menu, the problem has to be related to the triggering event. But the only place I can find where that makes a difference is the way a specific variable is set. I checked the state of that variable after it's set using either method and it contains the proper value. These are the thoughts going through my head as I begin to type my reply, but I don't quite make it that far. If you've got any experience debugging JavaScript or any other loosely typed language you may have figured this out already too.

The problem was the variable was a number when set by the click event, and a string when set from the drop down menu. The default value worked because it's a string rather than an index number.

You know what? I just realized that the fix I made last night introduces a new bug. I was just casting the value via the Number() function, but that screws up the default string value. Crap. So the full fix is an if statement checking for the default value and casting if it's not found. I'm off to make that change and then hopefully I'll be done.

Look for updated code to hit Ben's site in the not too distant future. :)

Monday, June 23, 2008

Google is so awesome

Seriously. I keep waiting for the other shoe to drop. How can a company be this cool, constantly, at no immediate cost to me? Have you seen the Google AJAX Libraries API? Nothing I can say here can do it justice. Just follow the link. I'm gonna try using this to load jQuery in the redesign.

Tuesday, April 29, 2008

Why jQuery Rocks

As a lazy developer, I love jQuery. I'll try to enumerate my top reasons:

  1. It's among the smallest of the full featured javascript libraries. So I don't have to worry about adding a lot of overhead to my pages to use it. For example, minified and gzipped, jQuery is about 15k. Dojo is about 24k, which, I admit, it still pretty impressive.
  2. jQuery does tons of cool stuff out of the box and doesn't require me to understand complex extension packages (moo tools and the Yahoo! User Interface Library are the most extreme examples I can think of).
  3. I can call functions as soon as the DOM is ready. (What's the DOM?)
  4. Simple, CSS style syntax for selecting elements combined with chainable functions allow me to write in 1 to 5 lines what used to take 12 to 50.
  5. jQuery's also got some great plug ins.

Of course, not every plug in available is amazingly awesome or even a good fit for every project. In fact, some of the best, in my opinion, have a very narrow, targeted application. Today I was asked to create an image gallery from a collection of 50 shots taken at the graduate awards ceremony Friday night. In the past, we've used Flash to make our image galleries. I suck at Flash, so I'm sure it would take me all week to recreate something like that, even if I had a basic template to go by. I have no idea how long it took Ken (former webmaster, current director of public relations and therefore my boss) to generate something like that. But I figured I could whip up something similar in jQuery in an afternoon.

There are lots of image gallery plug ins for jQuery. I wanted one that looked impressive while being easy to navigate and not so flashy as to distract from the images themselves. I also wanted something that required nothing but a list of images identified by an ID or class. The idea there is, if someday move to a CMS, the end users could build a gallery by simply adding the class (or ID) to a list of images. That's the sort of thing we could easily cover in training. It helps that as of right now my favorite CMS is Drupal, which comes pre-packaged with jQuery.

I looked at slideViewer, but I like thumbnails. I looked at jqGalViewII but for this particular application I don't want to spend time generating my own thumbnails. Then I looked at Galleria and this seemed to be the best fit for my immediate needs.

It took about 15 minutes of code work to repurpose the key elements from the demo page for our needs. That includes time spent minifying the javascript and uploading the external files to the server. I changed a few color values in the CSS, altered the fonts slightly, linked in our images, and had a fully functional image gallery in less time than it took to crop the images. The only snag I ran into was the preloading function wasn't working properly in IE (curse you IE!). But updating the core jQuery library to the latest version fixed this bug pretty quickly. I should have done that earlier, but I've been focusing on the development server, not the “live” server.

I hope to incorporate some standard implementations of things like this into the redesign. I'm keeping the possibility of a future move to a CMS in mind, but there's plenty of other benefits to having a few well documented solutions like this. It saves me time. That's a good start. I also occasionally take a vacation or occasionally get sick. If something comes up and I'm unavailable, a quick HowTo on implementing a cookie cutter image gallery like this could be a real life saver. I need to experiment with managing a mix of image sizes and maybe port the auto-thumbnail feature from Galleria into jqGalViewII and then offer up both options in a tidy package. Since it's all open source, I can easily do that.

Here's hopin' I don't automate myself out of a job some day. :)