Joseph Smarr

Thoughts on web development, tech, and life.

Author: jsmarr (page 3 of 5)

Great video interview about lunch 2.0

The PodTech crew shot and edited a really nice video at our recent Lunch 2.0 at Netgear. It covers the event and features an interview with the lunch 2.0 founders, including your humble narrator, on the origins of Lunch 2.0.

I conducted the entire interview while lying on a bed in Netgear’s “lifestyle room” showcase, watching TV using their wireless media center product. And I’m wearing a commemorative Netgear apron from their BBQ lunch.

I love living in Silicon Valley. :)

Here’s the video (thanks, Jeremiah!):

Twitter status and upcoming events now on my blog sidebar

BTW, I’ve added my current twitter status (using Twit-Twoo) and events I’m attending (via upcoming.org) to the left sidebar of my blog. It’s cool how easy it is these days to integrate data from third-party sites without having to write any API client code. Like we found with Plaxo’s widget, when you can just give people some HTML/JavaScript to copy and paste, the barrier to adoption is dramatically lowered compared to requiring even simple direct API consumption.

Of course, as someone who reads blogs exclusively inside Bloglines, I rarely see the actual web pages where people host their blogs. If you’re like me, now you know I have this extra info on my site. But from what I’ve seen, it appears many (if not most) people still read blogs by typing in the URLs and seeing if there’s anything new. It seems crazy not to take advantage of RSS, especially given how user-friendly many blog readers are these days, but I guess old habits die hard. :)

WordPress "XML-RPC server accepts POST requests only."

This morning I found I couldn’t publish to WordPress using Windows Live Writer any more. I would get errors like “Invalid Server Response – The response to the blogger.getUsersBlogs method received from the weblog server was invalid.” and when I looked at the request in HTTPAnalyzer, WordPress’s xmlrpc.php was sending “XML-RPC server accepts POST requests only.”, even though I WAS posting. Since WordPress’s WSYWIG and HTML editors both horribly mangle any code samples you try to use, this was quite frustrating.

But after a bit of Googling, I found a quick solution that worked perfectly. Just add the following line of PHP to the top of your xmlrpc.php file (inside the <?php of course):

$HTTP_RAW_POST_DATA = file_get_contents("php://input");

Thanks to helpful bloggers like Will for reporting solutions to problems like this, and thanks to Google for helping other distressed hackers find them! I hope this increases the ease with which this particular solution can be found by others.

The hidden cost of meta-refresh tags

We just discovered at Plaxo that redirecting using meta-refresh tags has a surprising performance penalty as a side-effect: it causes all cached resources on the redirected-to page to be re-requested (as if the user had hit the “refresh” button). Even though most of them should return 304s (if you’re caching them properly), this still results in a ton of extra requests and round-trips. A good workaround is to replace the meta-refresh tags with JavaScript redirects.

A bit more detail

A standard technique for redirecting users from one web page to another is to put a “meta refresh” tag in the first page that says to immediately redirect to the other page, e.g.

<html>
<head>
<title>Redirecting...</title>
<meta http-equiv=refresh content="0; url=http://new-page" />
...

When browsers see this, they go to the URL specified, and if the time specified before redirecting is (the “0;” in the above example), they’re even smart enough to remove the redirecting page from the browser history so when you press Back you don’t get re-redirected.

However, there is a side effect that none of us knew about or expected. We only discovered it while performance-tuning Plaxo Online 3.0 (coming real soon now!!) while using HTTPAnalyzer. For some people, after the initial visit to the site, on return visits none of the images would be re-requested (we send long cache expiration times, so this is good behavior). But for others, they’d be requested each time they went to the page.

The difference turned out to be that some people were accessing the site by a slightly different URL that uses a meta-refresh tag to go to the actual site. Since “http-equiv=refresh” means “treat this as if I’d sent the equivalent HTTP header ‘refresh'”, the browser (especially IE) acts as if the user had hit the reload button and re-requests all cached images on the redirected-to page with If-Modified-Since and If-None-Match headers. If you’ve got the right cache headers, these requests will all return 304 (i.e. the images won’t actually be re-downloaded), but it still results in a big–and unnecessary/unintended–performance hit because you’re now sending a bunch of extra round-trip requests while loading the page.

The ideal solution for redirecting is to send a 302 redirect response from the web server itself to avoid even loading the intermediate web page. However, there are times when this isn’t feasible, e.g. if you don’t have that level of control over the server or if your template system wants to only do this if certain variables are set. Another case is if you want to redirect from an HTTPS page to an HTTP page–if you try to do this on the server, you’ll get a browser warning about redirecting from a secure page to an insecure page, but if you do it with meta-refresh, it works fine (bravo, browser security dudes, heh). So in these cases you want to redirect client-side, but you don’t want to incur the side-effect of re-fetching all the cached resources.

A good solution is to use JavaScript (while some web developers like to degrade gracefully when JavaScript is disabled, we’re redirecting to a rich Ajax app, so this isn’t really an issue). Wherever you’d use a meta-refresh tag, instead insert the following script block:

<script type="text/javascript">
location.replace('http://real-page');
</script>

By using location.replace (instead of, say, location.href=), the browser will purge the redirecting page from the browser history, just like a meta-refresh tag with 0 wait time, which is a good thing. And you won’t get any bad caching side effects, which is also a good thing.

Thanks to the two Ryans for figuring this out! Now you know too. :)

Lunch 2.0 has been chronicled

Yep, that’s right: the story of Lunch 2.0 is featured today on the front page of the San Francisco Chronicle in a great article written by Jessica Guynn! Jessica spent a lot of time talking with us and visiting the recent Lunch 2.0 at LinkedIn, and she even read Terry’s and my recent tomes on the subject. :)

Thanks again to everyone that’s organized or attended a Lunch 2.0 event, and here’s to all fun ahead!

I’m so impressed with f8

Facebook Platform Launch (photo by Ted "Dogster" Rheingold)

As f8 would have it, I was in San Francisco yesterday for Facebook’s platform launch and hackathon. What a day it was!

The event itself quite a spectacle (they filled the SF Design Center with about 800 people, Mark gave a Jobs-esque keynote, and the hackathon was set up with tons of couches, tray-passed hors d’oeuvres, a DJ, and Facebook engineers a plenty to help out with the hacking).

But the platform itself was the real star–Facebook really wants developers to be able to build apps that are as powerful and as integrated as the ones Facebook could build themselves, and the Platform really delivers on that audacious goal. You can host your app pages inside Facebook’s chrome, add items to news feeds, send notifications, and basically hook into all the places that Facebook’s existing apps do.

The technology to make this work–and still be safe–is quite clever: basically they curl your page with enough query args to let you access their APIs, you construct the page results, and they display it inside Facebook. Instead of returning straight HTML, they have a modified version they call FBML which, in addition to stripping out JavaScript and sandboxing your CSS, lets you insert special facebook tags to easily do things like link to your friends, use Facebook-styled UI widgets, and even some basic AJAX (they proxy the call through Facebook and then give you a limited-but-still-quite-powerful set of options for what to do with the results, like injecting them into a given DOM node). And since they’re just calling your page via HTTP and it’s up to you to interact with Facebook’s REST API while constructing your result, there’s no need to even write your Facebook app in PHP (which is good news for me, since I’m no Terry, heh).

But the most impressive thing to be about f8 is just how much Facebook “gets it”. They could have continued to be a walled garden–they were doing quite well at it!–but it’s clear from their words and their actions that they really believe they will be more successful by being an open platform and letting developers have real power to extend the experience and take advantage of the social graph they’ve built up. They’re pushing the limits of technology to enable deep integration, they’re providing prominence to third-party apps inside Facebook to help them spread, and they’re even letting the apps keep 100% of the ad money they generate. It’s of course quite defensive for Facebook inasmuch as it disincentivizes people from trying to build new social networks and gives them a multiplier on the features they can offer their users, but it still shows great vision and I couldn’t be happier or more impressed with what they’re doing!

See you at Internet Identity Workshop

IIW2007 Registration banner

I’ll be attending the Internet Identity Workshop (IIW2007a, to be precise) this Mon-Wed at the Computer History Museum in Mountain View, CA. I went to IIW2006b last year and was immediately excited to be a part of this community. The people involved are not only very smart, they’re pragmatic, hands-on, accessible, and motivated by all the right reasons.

The progress of OpenID has been stunning–developing the standard, building libraries, folding in related projects, and getting broad support–and I think we may well start to see its adoption hit the mainstream this year (we’re certainly playing with it at Plaxo these days).

Like other workshops and conferences that I go to, this will also be an opportunity to catch up with a lot of friends that I (for whatever reason) seem to only find time to see at events like these. So if you’re planning to attend, come say hi or give me a call (my latest contact info is linked to from my blog sidebar, thanks to Plaxo of course).

See you there, js

I’m speaking at OSCON in July

Now that the OSCON 07 site is up, I guess it’s official–for the second year in a row, I’ve been selected to give a talk at O’Reilly’s annual Open Source Convention (OSCON) in Portland, OR from July 23-27.

The title of my talk this year is “High-Performance JavaScript: Why Everything You’ve Been Taught is Wrong“. I’m basically going to share all the secrets we learned the hard way while building Plaxo Online 3.0 and trying to make it fast. It turns out that so many of the techniques and axioms used by the AJAX community have serious performance implications, so I’ll explain how we discovered and worked around them. I’ll also argue that a different design philosophy is necessary if performance is truly a goal–one in which every line of code you write has a cost that needs to be justified and in which you assume the platform (web browser) is fragile and brittle rather than infinite and omnipotent. In other words, you have to stop asking “what can I make the browser do?” and instead ask “what should I make it do?”.

In the last few years I’ve been going to a lot of conferences on behalf of Plaxo, and OSCON is easily my favorite of them all. (Thanks again Terry for turning me on to it!) I think it’s because there’s a higher signal-to-noise ratio of people attending who are really building and influencing things to those that are just attending to figure out what all the latest hype is about. It doesn’t feel corporate; it feels like a bunch of smart hackers trying to figure things out together and share what they’ve learned. It’s what many conferences aspire to but so rarely achieve these days. Plus Portland is a really fun town to spend a week in (last year I went to the rose garden, Japanese tea garden, a custom martini bar, and not one but two Dresden Dolls shows).

I can’t wait. See you there!

Has it really been five years already??

My Stanford class book pageI can’t believe it, but Stanford is already telling me to get ready for my five-year college reunion this fall. Five years–that’s as long as I was in college (including my Master’s degree) but this five years sure went by a lot faster than the previous five! Then again, I just passed my five-year anniversary at Plaxo (the math is a bit funny because I started working at Plaxo before I finished my MS, which btw is not advisable for one’s sanity).

Anyway as part of the reunion they asked everyone to make a page for a “class book” that they’ll be distributing. It’s a one-pager where you share some of you Stanford memories and give an update on your life since graduating. I think they expected most people to draw their class book page by hand and snail-mail it in or use their web-based pseudo-WYSIWIG editor, but I wanted a bit more control. So I downloaded the template PDF and opened it in Adobe Illustrator, which converted it to line-art (wow–product compatibility, who knew?!). Then I was able to add the type and graphics in Illustrator and save the final copy back out to a PDF.

For me, life since Stanford meant three things: doing NLP research (this is the reunion for my undergrad class), working at Plaxo, and getting married. As scary as it is to consider that five years have gone by already, when I actually stop to think of all the wonderful things that have happened since then, I consider myself extremely fortunate. I couldn’t be happier. In fact, I could really use another five years like this one!

One quick technical note: Since I embedded lots of photos in my class book page at their original resolution (I just scaled them down in Illustrator so they would still print at high quality), the file ended up being almost 200MB. When I first exported it as a PDF, I kept all the default options, including “preserve Illustrator editing capabilities” and the resulting PDF was 140MB. Clearly I could not e-mail this to Stanford nor post it on my web site. So I tried again, unchecked the Illustrator option, and also went into the compression settings and told it to use JPEG for the color images (which of course the originals were, but the default PDF option is to use 8-bit ZIP). This made a huge difference and the PDF was only 3MB but still high resolution. I also tried the compression option “Average downsampling at 300 dpi” for color images, but that essentially took out all the resolution in the images, so as soon as you magnified the document at all, they were very pixelated (looked more like 72 dpi to me). Apparently just telling it to use JPEG with the original images is plenty.

Handling GeoCoding Errors From Yahoo Maps

One of the best features of Yahoo’s AJAX Maps API is its ability to geo-code full-text mailing addresses into lat/long on-the-fly, so you can say for instance “draw a map of 1300 Crittenden Lane, Mountain View, CA 94043“. (By now, Google and MSFT also offer geocoding, but Yahoo had it way earlier because they embraced JSON-P at a time when everyone else was still scratching their heads).

Yahoo does a pretty good job of geocoding addresses even if the format is a bit weird or some the info is missing, but of course they can’t always figure it out, especially if the address is garbage to start with. Their API indicates (somewhat cryptically) that you can capture an event when geocoding completes, but they don’t tell you what data you get or how to deal with it. Since there doesn’t appear to be much discussion of this on the Internets, I thought I’d provide the answer here for the record.

When creating a YMap, you can register a callback function to get triggered every time geocoding completes, like so:

var map = new YMap( … );
YEvent.Capture(map, EventsList.onEndGeoCode, myCallback);
…
function myCallback(resultObj) { … }

Yahoo’s API claims that you can also pass an optional private context object, but as far as I can tell they never send it back to you. Of course you can always use a closure around your callback function to achieve the same thing.

Now for the part they don’t tell you: your callback is called with a single resultObj argument. You can figure out the contents of this argument by just writing your callback function to take an argument and then writing console.dir(resultObj) to print out its full nested structure in the unbelievably useful Firebug (Joe, you’re my hero!). Here’s what you’ll see:

var resultObj = {
  success: 1, /* 1 for success, 0 for failure */
  /* Original address you tried to geo-code */
  Address: “1300 Crittenden Lane Mountain View, CA 94043″,
  GeoPoint: {
    /* This is a YGeoPoint, which also has a bunch of functions you can call */
    Lat: 37.424663,
    Long: -122.07248
  },
  ThisMap: { /* reference to the YMap */ }
};

So in your callback function you just test for resultObj.success, and if the geocoding failed, you can show an appropriate error message.

One trick I found for showing an error message is that you can embed a hidden div with an error message inside the map-holder div you pass to the YMap constructor, and YMap won’t get rid of it. If you use absolute positioning and give it a z-index, you can then show it when geocoding fails and get a nice “Map not available” right where the map would normally be.

Here’s a working example of handling geocoding and showing an error message. Thanks Yahoo! for the great API, and hopefully some of this info will find its way into the next rev of your API docs. :)

PS: Special thanks to Mark Jen for finding me a decent code-writing plug-in for Windows Live Writer! Boy did I struggle with getting WordPress not to mangle my code in the eval post!

Older posts Newer posts

© 2016 Joseph Smarr

Theme by Anders NorenUp ↑