<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Redfin Developer Blog</title>
	<atom:link href="http://blog.redfin.com/devblog/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.redfin.com/devblog</link>
	<description>Notes on Redfin, technology, real estate and life at a startup.</description>
	<lastBuildDate>Wed, 24 Apr 2013 17:15:33 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5</generator>
		<item>
		<title>Promoting Education with &#8220;20 Percent&#8221;</title>
		<link>http://blog.redfin.com/devblog/2013/04/promoting-education-with-20-percent.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=promoting-education-with-20-percent</link>
		<comments>http://blog.redfin.com/devblog/2013/04/promoting-education-with-20-percent.html#comments</comments>
		<pubDate>Wed, 24 Apr 2013 17:15:33 +0000</pubDate>
		<dc:creator>Patrick Tsao</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Data]]></category>
		<category><![CDATA[Maps]]></category>

		<guid isPermaLink="false">http://blog.redfin.com/devblog/?p=1654</guid>
		<description><![CDATA[One of the major perks of working on the engineering team at Redfin is the privilege to take on side projects in addition to the day-to-day assignments. We call it our “quarterly objectives,” where each quarter, engineers or product managers are allowed to dedicate a portion of their time to projects that they’re passionate about....  <a href="http://blog.redfin.com/devblog/2013/04/promoting-education-with-20-percent.html" class="read-more">Read&#160;More</a>]]></description>
				<content:encoded><![CDATA[<p>One of the major perks of working on the engineering team at Redfin is the privilege to take on side projects in addition to the day-to-day assignments. We call it our “quarterly objectives,” where each quarter, engineers or product managers are allowed to dedicate a portion of their time to projects that they’re passionate about. As a result, we’ve shipped an internal search using <a href="http://lucene.apache.org/solr/">Solr</a>, deployed <a href="http://newrelic.com/">New Relic</a> for measuring web application performance, built <a href="http://blog.redfin.com/blog/2011/05/hey_beautiful_upload_your_photo.html">a negotiation reference for our own real estate agents</a>, and many others.</p>
<p>This time around, <a href="http://blog.redfin.com/blog/2009/05/breaking_news_jamie_demichele_wins_redfins_strongest-man_competition.html">Jamie DeMichele</a>, our Technical Lead, decided to take on adding the ability to search for listings by school attendance areas as his third-quarter objective in 2012.</p>
<p style="text-align: left"><a href="http://blog.redfin.com/devblog/2013/04/promoting-education-with-20-percent.html/jamie-robe" rel="attachment wp-att-1657"><img class="alignnone size-medium wp-image-1657" alt="jamie-robe" src="http://blog.redfin.com/devblog/wp-content/uploads/sites/3/2013/04/jamie-robe-200x300.jpg" width="200" height="300" /></a></p>
<p><i>What’s the</i> <i>big deal?</i> It turns out that <a href="http://blogs.wsj.com/developments/2011/11/16/one-antidote-to-foreclosures-good-schools/">schools play a crucial role in the real estate industry</a>, both in terms of helping buyers decide where to live, as well affecting resale values for homeowners. From the perspective of a Product Manager on the team, it is simply a dream come true when one of these side projects happen to be one of the most requested features by our visitors as well as real estate agents.</p>
<p>In Jamie&#8217;s own words, &#8220;after working on mostly backend functionality for many years, getting the chance to work end-to-end on a feature was an awesome experience!&#8221;</p>
<p><a href="http://blog.redfin.com/devblog/2013/04/promoting-education-with-20-percent.html/ldp-widget" rel="attachment wp-att-1655"><img class="alignnone size-full wp-image-1655" alt="ldp-widget" src="http://blog.redfin.com/devblog/wp-content/uploads/sites/3/2013/04/ldp-widget.png" width="925" height="315" /></a></p>
<p>&#8220;Adding search functionality via school boundary polygons is a huge benefit to our customers as well as our agents, especially when it didn’t require massive upgrades to our existing infrastructure. We also built an easy way to regularly update our school boundaries, ensuring a high quality bar for school boundary data on Redfin.&#8221;</p>
<p><a href="http://blog.redfin.com/devblog/2013/04/promoting-education-with-20-percent.html/map" rel="attachment wp-att-1656"><img class="alignnone size-large wp-image-1656" alt="map" src="http://blog.redfin.com/devblog/wp-content/uploads/sites/3/2013/04/map-1024x672.png" width="640" height="420" /></a></p>
<p>As usual, a big THANK YOU goes out to everyone on the engineering team who contributed to this feature. We truly enjoyed building a new way for our customers to search for homes, and we’re thrilled to continue <a href="http://www.redfin.com/about/redfin">reinventing real estate in the consumer’s favor</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.redfin.com/devblog/2013/04/promoting-education-with-20-percent.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Life with New Relic</title>
		<link>http://blog.redfin.com/devblog/2013/04/life-with-new-relic.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=life-with-new-relic</link>
		<comments>http://blog.redfin.com/devblog/2013/04/life-with-new-relic.html#comments</comments>
		<pubDate>Mon, 08 Apr 2013 22:10:36 +0000</pubDate>
		<dc:creator>Ben Phillips</dc:creator>
				<category><![CDATA[Data]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[new relic]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://blog.redfin.com/devblog/?p=1639</guid>
		<description><![CDATA[Improving performance is awesome. As a web developer, there is a unique satisfaction knowing a page now loads in half the time, or spends less time accessing databases. However, improving a page takes time; time that could have been spent making new features or wowing the user in more obvious ways. In addition, optimizing pages...  <a href="http://blog.redfin.com/devblog/2013/04/life-with-new-relic.html" class="read-more">Read&#160;More</a>]]></description>
				<content:encoded><![CDATA[<p dir="ltr">Improving performance is awesome. As a web developer, there is a unique satisfaction knowing a page now loads in half the time, or spends less time accessing databases. However, improving a page takes time; time that could have been spent making new features or wowing the user in more obvious ways. In addition, optimizing pages can be tricky. Sometimes you get to be the hero, but then there are those days&#8230; You know the kind: you fix a particularly slow page only to learn that it now loads in 6.0 seconds instead of 6.1. Oops. Then, it turns out there were only 5 visits to the page in the last month. Double oops. Finally, in order to &#8220;fix&#8221; the page, the code mutated from something straightforward to a creation that is strikingly similar to spaghetti.</p>
<p>This was our world as of last year. We had home brewed approaches to gather basic performance information. We knew which pages saw the most use, and we knew if they were getting slower or faster. However, we didn’t know why our pages were slower or faster. We could improve our performance, but it was an involved process.</p>
<h3>Enter New Relic!</h3>
<p dir="ltr">About this time we started looking into <a href="http://www.newrelic.com/">New Relic</a>. New Relic monitors application performance. Their code is easy to set up, and reports on a number of metrics. Some of our favorites were the slowest requests on the servers, the slowest database queries (and tables), traces of particularly slow web requests, and the aggregate errors being reported across our servers. There are plenty more features, but these were our favorites.</p>
<p><b><b><br />
<img class="aligncenter" alt="" src="https://lh4.googleusercontent.com/c1B4np327xoo1VJQMx7iAAxzsGtilj9df_ZNxu5yzZl5zE_SmMYEn7iQ-jeGWXWRcayObuxEGDTNtZMt1A6Wethnea13Fq3FvTUpWv4H3zzPRGhysl2ea_KA" width="616px;" height="311px;" /></b></b></p>
<p dir="ltr" style="text-align: center"><em>The overview of our site’s performance in New Relic</em></p>
<p><b><b> </b></b></p>
<p dir="ltr">Initially, we had a couple reservations about using New Relic. Mainly we were concerned with how it would affect our website performance. After all, New Relic adds an additional wrapper around our code, and it is sending performance data from our server to the New Relic server. We did some investigations and we found that the performance hit of using New Relic should be less than a 5% hit to our memory usage and CPU usage. In addition, the data passed to New Relic is sent asynchronously. If the New Relic server is down, then the local New Relic monitor will store data for up to 15 minutes, and then start dropping data. With these answers in hand we were willing to take the New Relic app for a spin.</p>
<p><b><b> </b></b></p>
<h3>New Relic FTW!</h3>
<p dir="ltr">New Relic won us over when it helped us catch an error we were not even aware of. We have some assistant servers that pre-render some of our pages, in some cases these assistant servers were throwing an error when they tried to write out a response. However, these errors were being caught (incorrectly) before we could log them. According to our logs, there were no errors. However, New Relic kept recording a disturbingly large number of errors on these servers. We investigated and fixed the root cause, but it was a tricky error. The fix could have taken a lot more time if we hadn&#8217;t know the exact urls that were causing the errors and seen the stack trace of the issue.</p>
<p><b><b><br />
<img class="aligncenter" alt="" src="https://lh5.googleusercontent.com/c1wMZPXpR7yWNKSyshP5o-y5gXAKru_Un6lazJQj19OBqPWmaYHhn1miDUNi0PlacON-GZJpaiHUFUC_RcInTLoefxhflBRv9nwoeKiA69luici6mQlJOwe2" width="622px;" height="301px;" /></b></b></p>
<p dir="ltr" style="text-align: center"><em>The New Relic error that helped us track down our silent server error</em></p>
<p><b><b> </b></b></p>
<h3>Is New Relic the Silver Bullet™?</h3>
<p dir="ltr">New Relic is an extremely useful tool, but at the end of the day it’s a tool. What you get out of it depends often depends on how well you understand the inner workings of your application. For example, we have a database table, logins, which sees a lot of use. If our database hits high loads then logins tends to take up a lot of time. So when the database backs up it tends to look like the logins table is holding everything back. However, the slow login table queries are merely a symptom of a high database load and not the cause.</p>
<p><b><b><br />
<img class="aligncenter" alt="" src="https://lh6.googleusercontent.com/BOQ8snXBKokUVEDvST8E8IQdF3k_o8Fwrg97CakIUdT-M4Ab_0bDj2W6K5qY1ZbXkNJKbpMTzbjVHDaV2f5UtNI6qYkAv46UQoh11jTxUfL4fKhz1FDXxmMY" width="622px;" height="388px;" /></b></b></p>
<p dir="ltr" style="text-align: center"><em>Misleading Login spike during DB slowdown</em></p>
<p><b><b> </b></b></p>
<p dir="ltr">In addition, New Relic is built as a website monitoring tool. It has the ability to monitor jobs, but it takes some digging to find out how to configure the New Relic agent for a job. When we set up jobs we had to change the newrelic.yml file to have the following lines (these changes may be Java specific, and there must be exactly two spaces to the left of each line in the config):</p>
<p dir="ltr">  sync_startup: true</p>
<p dir="ltr">  send_data_on_exit: true</p>
<p dir="ltr">  send_data_on_exit_delay: 20</p>
<p dir="ltr">Stack traces on jobs also leave something to be desired. New Relic only traces the first ~2000 method calls. This is fine in a web transaction, but this will only scratch the surface of long running jobs. Nevertheless, it’s nice to get some insight into how our jobs are influencing our database loads.</p>
<p><b><b> </b></b></p>
<h3>Final Thoughts</h3>
<p dir="ltr">New Relic helped us dive into our code in greater detail than ever before. Using their application, we could find out not only which pages were slow, but crucially we could find out precisely which queries and functions were slow. Now it is easier than ever to hunt down performance issues, which has led to an unanticipated benefit. Prior to New Relic, we had one dev who took on the mantle of performance guru. He let everyone know when pages were slowing down, and encouraged the teams in charge of those pages to fix them up. Some days it seemed he had a Sisyphean task. He could harp on the performance of a page, and it would slowly improve, but in the meantime other pages would slow down. Now that New Relic is in place there has been a noticeable shift. Teams have started to jump in and fix their own pages spontaneously. Even teams that don’t own code have been helping improve database performance.</p>
<p><b><b> </b></b></p>
<p dir="ltr">We have had a great experience with New Relic. If you want to give it a spin, check out <a href="http://www.newrelic.com">www.newrelic.com</a>!</p>
<p><b><b> </b></b></p>
<p dir="ltr"><em>Note: the screenshots in this post have been slightly altered to exclude some internal information.</em></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.redfin.com/devblog/2013/04/life-with-new-relic.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>It&#8217;s a Red, Red, Red, Red World</title>
		<link>http://blog.redfin.com/devblog/2013/03/its-a-red-red-red-red-world.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=its-a-red-red-red-red-world</link>
		<comments>http://blog.redfin.com/devblog/2013/03/its-a-red-red-red-red-world.html#comments</comments>
		<pubDate>Tue, 26 Mar 2013 16:32:39 +0000</pubDate>
		<dc:creator>Andrew Fischler</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[brand]]></category>
		<category><![CDATA[color]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[palette]]></category>
		<category><![CDATA[theme]]></category>

		<guid isPermaLink="false">http://blog.redfin.com/devblog/?p=1602</guid>
		<description><![CDATA[Viewing the World Through Red-Colored Glasses If you&#8217;re a frequent visitor to our site, you may have noticed something different about the page today. After years of living with a blue color scheme we affectionately called “cadaver blue”, we&#8217;ve finally gone and put the “red” into Redfin. The new look is just the latest &#8212;...  <a href="http://blog.redfin.com/devblog/2013/03/its-a-red-red-red-red-world.html" class="read-more">Read&#160;More</a>]]></description>
				<content:encoded><![CDATA[<p><strong>Viewing the World Through Red-Colored Glasses</strong></p>
<p>If you&#8217;re a frequent visitor to our site, you may have noticed something different about the page today. After years of living with a blue color scheme we affectionately called “cadaver blue”, we&#8217;ve finally gone and put the “red” into Redfin. The new look is just the latest &#8212; and most visible &#8212; example of our efforts to strengthen and evolve our brand. For example: <a title="Why Update the Logo? I’ll Tell You Why." href="http://blog.redfin.com/devblog/2012/08/why_update_the_logo_ill_tell_you_why.html">remember that tree in our logo</a>? Yeah, me neither.</p>
<p><a href="http://blog.redfin.com/devblog/2013/03/its-a-red-red-red-red-world.html/red-red-world-blog-post-1" rel="attachment wp-att-1613"><img class="alignnone size-full wp-image-1613" alt="Red brand vs. Our Old Blue" src="http://blog.redfin.com/devblog/wp-content/uploads/sites/3/2013/03/Red-Red-World-Blog-Post-1.jpg" width="1024" height="936" /></a></p>
<p><strong>A Look Into the Kitchen</strong></p>
<p>Redesigning an existing site can be very complex. Even pulling off a relatively small-scope change such as <a title="How Do You Like Our Remodel?" href="http://blog.redfin.com/blog/2013/02/how-do-you-like-our-remodel.html">updating our blog theme</a> can be so daunting that many companies and their designers decide to start from scratch. Why? Because when you’re updating an existing site, the hard work tends to be less in the design process and more in the updating for an ancient code base or normalizing different ways an element &#8212; like a button &#8212; can be put together.</p>
<p>To put it another way, which do you think is easier: cooking a great meal from scratch, or taking a bunch of leftovers and making a meal that tastes better than the original?</p>
<p>Back when the internet was younger and the technology was simpler, there were more complete redesigns done, but as the net has matured and the number of people relying on sites has grown, “redesign” has given way to “refine” and “iterate”. That means more incremental changes &#8212; page by page, or section by section. That’s the approach we took.</p>
<p><strong>But It&#8217;s Not Just a Fresh Coat of Paint</strong></p>
<p>When we started the effort to update our web site&#8217;s visual branding, we took a long, hard look at the common elements that make up our site &#8211; the “widgets”, if you will. We&#8217;re in the midst of unifying and updating them on our site, though it&#8217;s a long term project, and <a title="You Look Beautiful Darling" href="http://blog.redfin.com/blog/2012/12/redfin-updates-home-details-page.html">our refreshed home details page</a> was just the beginning.</p>
<p>Redfin was built by many hands over many years, using different programming languages, styles, and coding practices. Eventually we&#8217;re going to unwind all this and have everyone using the same set of widgets, but in the meantime, we&#8217;re using the power of CSS to bring some visual similarity to the elements that have the same purpose &#8212; page navigation, buttons, tooltips, dialogs, etc. One of our goals is to simplify the elements you interact with, just like we want to simplify real estate.</p>
<p><a href="http://blog.redfin.com/devblog/2013/03/its-a-red-red-red-red-world.html/red-red-world-blog-post-2" rel="attachment wp-att-1614"><img alt="What makes Red Brand tick" src="http://blog.redfin.com/devblog/wp-content/uploads/sites/3/2013/03/Red-Red-World-Blog-Post-2.jpg" width="1024" height="776" /></a></p>
<p>It may be a lot of small changes, but in this case, small changes make a big impact. Just by removing the blue backgrounds we reduced the “boxiness” &#8212; the heavy framing of some elements &#8212; by an astounding 70%! Okay, so maybe that’s a made-up metric, but it still illustrates the dramatic effect we were able to achieve. One small change that gives the site a night-and-day kind of difference.</p>
<p><strong>Express Yourself</strong></p>
<p>We&#8217;re also starting to express Redfin&#8217;s personality with our new color palette &#8212; bright, vibrant, engaging, alive. That’s how we want people to see Redfin, because that’s just what we are as a company. Compare that to cold &amp; confined &#8212; two words we heard about our old theme &#8212; and you feel the disconnect in who we are and how we presented ourselves to the world. Now our outsides have started to match our insides.</p>
<p>These changes have been a long time in coming, and by no means are we done yet. In the past year, we’ve doubled the size of our design team between our Seattle and San Francisco, which means these changes are going to be coming fast and furious as we work on improving the look of other elements and sections of the site, which you’ll be seeing in the coming weeks and months.</p>
<p>So a huge thank you to everyone who has helped make this a reality over the past few months. This was a labor of love, and I was proud to have played a part in its creation. And to our dear customers, we hope you will enjoy our face lift. Let us know what you think in the comments below.</p>
<p>That said, we’re thrilled to finally be putting our fresh, new face forward.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.redfin.com/devblog/2013/03/its-a-red-red-red-red-world.html/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Recap: Seattle JS Meetup @ Redfin HQ</title>
		<link>http://blog.redfin.com/devblog/2013/03/recap-seattle-js-meetup-redfin-hq.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=recap-seattle-js-meetup-redfin-hq</link>
		<comments>http://blog.redfin.com/devblog/2013/03/recap-seattle-js-meetup-redfin-hq.html#comments</comments>
		<pubDate>Sat, 16 Mar 2013 00:44:06 +0000</pubDate>
		<dc:creator>Wei-Ting Lu</dc:creator>
				<category><![CDATA[Meetups]]></category>
		<category><![CDATA[Talks]]></category>

		<guid isPermaLink="false">http://blog.redfin.com/devblog/?p=1582</guid>
		<description><![CDATA[After a very successful night of hosting the Seattle Scalability Meetup few weeks back, we decided to host another one! This time, we hosted the Seattle JS Meetup. Just like last time, we had an incredible turnout from the Seattle community, with more than 100(!!) attendees sitting in our newly renovated office. This time, we started off...  <a href="http://blog.redfin.com/devblog/2013/03/recap-seattle-js-meetup-redfin-hq.html" class="read-more">Read&#160;More</a>]]></description>
				<content:encoded><![CDATA[<p style="text-align: center"><a href="http://blog.redfin.com/devblog/2013/03/recap-seattle-js-meetup-redfin-hq.html/jsmeetup" rel="attachment wp-att-1584"><img class="size-full wp-image-1584 aligncenter" alt="Crowd at Redfin HQ for March Seattle JS Meetup" src="http://blog.redfin.com/devblog/wp-content/uploads/sites/3/2013/03/JSMeetup.jpg" width="1024" height="302" /></a></p>
<p>After a <a title="Recap: Seattle Scalability Meetup @ Redfin HQ" href="http://blog.redfin.com/devblog/2013/03/recap-seattle-scalability-meetup-redfin-hq.html" target="_blank">very successful ni</a><a title="Recap: Seattle Scalability Meetup @ Redfin HQ" href="http://blog.redfin.com/devblog/2013/03/recap-seattle-scalability-meetup-redfin-hq.html" target="_blank">gh</a><a title="Recap: Seattle Scalability Meetup @ Redfin HQ" href="http://blog.redfin.com/devblog/2013/03/recap-seattle-scalability-meetup-redfin-hq.html" target="_blank">t of hosting</a> the Seattle Scalability Meetup few weeks back, we decided to host another one! This time, we hosted the <a title="Seattle JS Meetup" href="http://www.meetup.com/seattlejs/events/104167682/" target="_blank">Seattle JS Meetup</a>. Just like last time, we had an incredible turnout from the Seattle community, with more than 100(!!) attendees sitting in our newly renovated office.</p>
<p>This time, we started off with lightning rounds, where anyone can come up and give a quick, two minute presentation about anything JavaScript related. After the lightning rounds, we had our first speaker, Yuriy Dybskiy, who talked about <a title="Meteor" href="http://meteor.com/main" target="_blank">Meteor</a>, a JS framework that allows developers to quickly create and deploy a web application. He went through and showed us how to create a simple JS web app that allows users to log in and show a picture of their avatar (if they have <a href="https://en.gravatar.com/" target="_blank">Gravatar</a> account associated with the email), all using JavaScript and the Meteor API.</p>
<p>Next we had Ryan Eastridge, who created <a title="Glowstick" href="https://github.com/forgejs/glowstick" target="_blank">Glowstick</a>, a cool API that allows you to control LEDs on a custom made Arduino board. He created this in part to introduce kids and young adults to the world of computer science and programming. Using simple syntax and APIs, kids can go from creating simple light patterns to making intricate moving rainbow lights (note: <a href="http://www.youtube.com/watch?v=QH2-TGUlwu4" target="_blank">cat not included</a>).</p>
<p>Ryan actually brought in two custom-made light boards to the meetup for the attendees to try. The board was connect to our local network and anyone could access it through the network. All they had to do was open up a web browser and navigate to the board. Next, open the console on the browser, and start programming LED light patterns. During the presentation someone actually made a semi-working game of <a title="Pong" href="http://en.wikipedia.org/wiki/Pong" target="_blank">Pong</a> using the Glowstick API. Redfin engineers also created a Redfin Logo using the Glowstick API.</p>
<p><a href="http://blog.redfin.com/devblog/2013/03/recap-seattle-js-meetup-redfin-hq.html/redfinlightboard" rel="attachment wp-att-1583"><img class="alignnone size-medium wp-image-1583" alt="Redfin Logo on Glowstick Lightboard" src="http://blog.redfin.com/devblog/wp-content/uploads/sites/3/2013/03/RedfinLightBoard-241x300.jpg" width="241" height="300" /></a></p>
<p>After the talks people mingled while some continued to program cool lights into the light board. Overall it was a great experience meeting other developers in the Seattle area and hearing all the cool projects people are working on.</p>
<p>We&#8217;ll be hosting more awesome events in the future. Until next time!</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.redfin.com/devblog/2013/03/recap-seattle-js-meetup-redfin-hq.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Debugging in the Browser</title>
		<link>http://blog.redfin.com/devblog/2013/03/debugging-in-the-browser.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=debugging-in-the-browser</link>
		<comments>http://blog.redfin.com/devblog/2013/03/debugging-in-the-browser.html#comments</comments>
		<pubDate>Tue, 05 Mar 2013 19:02:09 +0000</pubDate>
		<dc:creator>Meaghan Kjelland</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Browsers]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Programming Languages]]></category>

		<guid isPermaLink="false">http://blog.redfin.com/devblog/?p=1573</guid>
		<description><![CDATA[If you’re new to Web development, I highly recommend learning how to use a few different browser’s developer tools. I came from a background of mostly Java, and learning javascript can be tricky since it is used is such a different way. I used Chrome’s developer tools to learn how javascript behaves. I think it...  <a href="http://blog.redfin.com/devblog/2013/03/debugging-in-the-browser.html" class="read-more">Read&#160;More</a>]]></description>
				<content:encoded><![CDATA[<p>If you’re new to Web development, I highly recommend learning how to use a few different browser’s developer tools. I came from a background of mostly Java, and learning javascript can be tricky since it is used is such a different way. I used Chrome’s developer tools to learn how javascript behaves. I think it would have been much more difficult to learn javascript without using the dev tools, so you should learn how to use them too! I will mostly focus on Chrome’s tools since I’m most familiar with them, but Firebug (<a href="http://getfirebug.com/">http://getfirebug.com</a>) has a similar debugger for Firefox. But I think Chrome’s tools are prettier, which is why I use them!<b><b><br />
</b></b></p>
<h3>Elements Tab</h3>
<p>To access Google Chrome developer tools, right click on the element on the page that you want to see the HTML of (or anywhere if you just want to open the tools) and select Inspect element. This will take you to the Elements tab. Here you can see all of the HTML for a page and all CSS styles that apply to each element. Here are some uses for the Elements tab:<b><b><br />
</b></b></p>
<ul>
<li>Edit HTML directly in this view by right clicking on the element you want to change and selecting Edit as HTML.</li>
<li>Notice how all of the styles that apply to the selected element are in the right sidebar of this tab.</li>
<li>Unselect styles to make them no longer apply by hovering over the style you don’t want and deselecting the checkbox next to it, or you can edit the styles by double clicking on the style you want to change.</li>
<li>If the style is crossed out, then another style has overwritten the value of that style, if the style has a yellow exclamation mark next to it then the browser doesn’t understand what it means.</li>
<li>Create new CSS selectors in the dev tools directly by clicking on the little plus sign above the Style’s section, this can be useful if you’re trying to figure out how to select a certain element.<img alt="" src="https://lh6.googleusercontent.com/LE8X7XwfM-wRLMhTkMvqUQeH_Tn9CBp1bOyYaX37nkk0xtdUIsxlWle66RdXMB87SW4Ny01AQLst9BIQdJs4ezzuZyIWmQclX4UQBLpjNCiloH97qPA" width="703px;" height="382px;" /></li>
</ul>
<p><em>Elements tab of Google Chrome developer tools<b><b><br />
</b></b></em></p>
<h3>Sources Tab</h3>
<p>Chrome’s javascript debugger can be found in the Sources tab of the developer tools. Here are some of the uses of the Sources tab:<b><b><br />
</b></b></p>
<ul>
<li><strong>(This is bold, because it’s important!) Before you start debugging, you should set the debugger tools to pause when there is an uncaught exception. To do this, press the stop sign in the bottom left corner with a pause symbol in the middle of it until it turns purple, then scripts will pause when there is an uncaught exception and you’ll be able to see what is causing the exception by checking the values of local variables at the point where the exception is thrown.</strong> You can also set it to pause on all exceptions, but this can be very noisy, and usually if there is a caught exception you were already aware of it.</li>
<li>To use the debugger, click on the arrow in the top left corner to see all of your javascript files. Browse through the scripts until you find the one you want to debug.</li>
<li>To set a breakpoint, click on the line number to the left of the line you want to set the breakpoint at. Once the breakpoint has been hit, there are basic stepping and running buttons in the top right corner. Another way of setting a breakpoint is to put “debugger;” directly in your code, the Chrome developer tools will recognize this as well.</li>
<li>When you are paused in the debugger, look at the right sidebar of this tab. You can see all local and global variables and their values in the Scope Variables section.</li>
<li>You can see the stack trace in the Call Stack section, and you can see all breakpoints that you have set in the Breakpoints section. The breakpoints will persist on page reload.</li>
<li>Edit javascript on the spot in the developer tools, just edit the file in the Sources tab, then Ctrl+s and the new javascript will run, but this does not persist when the page reloads. I’ve never used this functionality, mostly because you can’t make the js persist, and most of the time you want it to.<img alt="" src="https://lh4.googleusercontent.com/2Wl9XB_R55TLbJTVaxOY1VvJ70t2O6eCI3xVFgaYt3DoAOV7WU2-i275DC6ACNWD3TOzDDafpDRTnRHFm2EUI-pRC6KbH0O4_6JYt7Uq8aZXs1F64E8" width="672px;" height="366px;" /></li>
</ul>
<p><em>Sources tab of Google Chrome developer tools<b><b><br />
</b></b></em></p>
<h3>Console Tab</h3>
<p>The Console tab of chrome developer tools has a lot of useful features. The console is also accessible from other tabs by clicking the Show console button in the lower left corner. Here are some things you can do with the console tab:<b><b><br />
</b></b></p>
<ul>
<li>To show information about the code in the console, use console.log(string) in your code, this is really useful for logging errors, or seeing how long something took to run.</li>
<li>Right click in the console and select Log XMLHttpRequests Then you can see whether your XHR requests have been successful or not directly in the console. You can also see the details of these calls in the Network tab.</li>
<li>Type the name of a variable in the console and see it’s value. You can dereference the variables you find in the console to find their fields. The console will autocomplete the variables for you showing you which variables that it knows about in the current scope.</li>
<li>Query for HTML elements in the console using jquery/dojo/whatever you use. Ex: dojo.byId(&#8220;my_object_1&#8243;); Or select the element you want to see in the Elements tab and type $0 into the console.</li>
<li>You can also execute javascript in the console, it will execute in the current scope, so if you’re paused in the debugger you can set variable values to something else in the console and see how it behaves.</li>
<li>Use the monitorEvents method, pass it an element and you’ll see all events that are being fired on that element.</li>
</ul>
<h3>Debugging in Internet Explorer</h3>
<p>If you have a bug specific to Internet Explorer (which you probably will at one point or another), you may need to use their debugger tools. They are a little harder to use than Chrome’s tools. I do most of my internet explorer debugging by googling my problem, a lot of people have problems with IE, so try that before learning how to use their tools, I get by mostly without them.<b id="internal-source-marker_0.03996836766600609"></b></p>
<p>To open Internet Explorer’s F12 developer tools, press F12. F12 developer tools allow you to change the<b id="internal-source-marker_0.03996836766600609"> </b>Browser/Document mode of internet explorer so that you can see how it looks in previous versions of Internet Explorer, to do this click on Browser Mode or Document Mode and select the version you want to see. However, beware of relying totally on testing in IE9 set to IE8 mode, we once had a bug where we tested everything using the developer tools in IE9 and setting the browser and document mode to IE8, but if you were actually in IE8, you would get a really ugly error popup that said “Stack overflow”, we didn’t find this until after deploying, so I recommend you also do some testing in real IE8 before deploying anything big. To inspect HTML go to the HTML tab, press the little refresh button, then press the pointer button and click on the HTML element on the page that you want to see. CSS and HTML will be visible here. The HTML in the tab only updates once you press refresh so if you click something to change the state, you have to refresh the developer tools again.<b id="internal-source-marker_0.03996836766600609"> <img alt="" src="https://lh4.googleusercontent.com/bACND5DK8DiCvPA3Kb3LlsqLSvv-Lg7OR6U3d5lBmQF-rFBZ65BxPKep7gMUtU566oFeO4Wlt7CJPonQLTHCFbO21BkiP2cC1yNhi1nnxxduvko4JhY" width="625px;" height="268px;" /></b></p>
<p><em>HTML tab of Internet Explorer F12 Developer Tools<b id="internal-source-marker_0.03996836766600609"></b></em></p>
<p>To debug javascript, go to the Script tab, press the Start debugging button, then you’ll see one really long file with your scripts in it. The best way I’ve found to navigate this is to copy the line of javascript that you want to set your breakpoint at, and search for it in the Script tab. You should be able to find the line this way. Then you set breakpoints and step through the code with the basic debugging buttons in that tab.<b id="internal-source-marker_0.03996836766600609"> </b><em><b id="internal-source-marker_0.03996836766600609"><img alt="" src="https://lh5.googleusercontent.com/7JhfP4dDHWgoeLCs4DRFCCG-Xy5lkXznv1eGXszdioyTbfQAlnBUyR5hCt4JrOf2R7H1lF2F7DigVWXCP2lto9MpNB1b-B6dAYICkGn1VW0VLhXF6nI" width="692px;" height="294px;" /><br />
</b>Script tab of Internet Explorer F12 Developer Tools<b id="internal-source-marker_0.03996836766600609"><br />
</b></em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.redfin.com/devblog/2013/03/debugging-in-the-browser.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Recap: Seattle Scalability Meetup @ Redfin HQ</title>
		<link>http://blog.redfin.com/devblog/2013/03/recap-seattle-scalability-meetup-redfin-hq.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=recap-seattle-scalability-meetup-redfin-hq</link>
		<comments>http://blog.redfin.com/devblog/2013/03/recap-seattle-scalability-meetup-redfin-hq.html#comments</comments>
		<pubDate>Sat, 02 Mar 2013 00:29:19 +0000</pubDate>
		<dc:creator>Bridget Frey</dc:creator>
				<category><![CDATA[Meetups]]></category>

		<guid isPermaLink="false">http://blog.redfin.com/devblog/?p=1535</guid>
		<description><![CDATA[Redfin Engineering had an incredible time hosting the Seattle Scalability Meetup earlier this week. In the past, we&#8217;ve had celebrity guest speakers give talks in our San Francisco office, but we&#8217;ve just never been able to make it happen in Seattle before. (If you&#8217;re curious, see Ryan Dahl on node.js, Alex Payne on how and why...  <a href="http://blog.redfin.com/devblog/2013/03/recap-seattle-scalability-meetup-redfin-hq.html" class="read-more">Read&#160;More</a>]]></description>
				<content:encoded><![CDATA[<p><a href="http://blog.redfin.com/devblog/2013/03/recap-seattle-scalability-meetup-redfin-hq.html/photo-8" rel="attachment wp-att-1542"><img class="aligncenter size-large wp-image-1542" alt="Crowd at Redfin HQ for February's Seattle Scalability Meetup" src="http://blog.redfin.com/devblog/wp-content/uploads/sites/3/2013/03/photo-8-1024x356.jpg" width="640" height="222" /></a></p>
<p>Redfin Engineering had an incredible time hosting the <a title="Seattle Scalability Meetup" href="http://www.meetup.com/Seattle-Hadoop-HBase-NoSQL-Meetup/events/88624542/" target="_blank">Seattle Scalability Meetup</a> earlier this week. In the past, we&#8217;ve had celebrity guest speakers give talks in our San Francisco office, but we&#8217;ve just never been able to make it happen in Seattle before. (If you&#8217;re curious, see Ryan Dahl on <a href="http://blog.redfin.com/devblog/2010/07/ryan_dahl_introduces_nodejs.html" target="_blank">node.js</a>, Alex Payne on <a href="http://blog.redfin.com/devblog/2010/05/how_and_why_twitter_uses_scala.html" target="_blank">how and why Twitter uses Scala</a>, and Jeff Hammerbacher on <a href="http://blog.redfin.com/devblog/2010/06/evolving_a_new_analytical_platform_with_hadoop.html" target="_blank">Hadoop</a>.)</p>
<p>Part of what made this possible now is the fact that we recently expanded and remodeled our Seattle headquarters.  Our new space includes a meeting room overlooking the waterfront that was able to accommodate the 100 attendees for this vibrant meetup.</p>
<p>We were treated to two excellent technical talks.  The first was from Paul Gross at <a href="www.braintreepayments.com">Braintree</a>, who spoke about how Braintree supports high availability.  The talk covered how Braintree has engineered every layer of their stack to be tolerant of both planned and unplanned outages.  Braintree has open sourced quite a bit of the code they use to accomplish this, including a custom load balancer and scripts for handling automated failover for Postgres.</p>
<p>Next, we heard from Mike Miller, the Chief Scientist at <a href="www.cloudant.com">Cloudant</a>.  Cloudant describes its product as &#8220;a globally distributed, document database-as-a-service that scales from megabytes to petabytes.&#8221;  Supporting geospatial indexing and querying is a key part of Cloudant&#8217;s value-add, so their team has taken a hard look at geospatial in technologies like PostGIS, and then applied those learnings to features that work on their globally distributed database.</p>
<p>Afterwards, we met up for a beer at Sonya&#8217;s, which is just down the street from Redfin HQ.  We&#8217;re looking forward to hosting this Meetup again in April.  We&#8217;ll also be hosting the Seattle JS meetup for the first time on March 14th (<a href="http://www.meetup.com/seattlejs/events/104167682/" target="_blank">http://www.meetup.com/seattlejs/events/104167682/</a>).</p>
<p>Hope to see you there!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.redfin.com/devblog/2013/03/recap-seattle-scalability-meetup-redfin-hq.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Stealth Internship: Collections</title>
		<link>http://blog.redfin.com/devblog/2012/12/stealth_internship_collections.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=stealth_internship_collections</link>
		<comments>http://blog.redfin.com/devblog/2012/12/stealth_internship_collections.html#comments</comments>
		<pubDate>Thu, 20 Dec 2012 15:00:31 +0000</pubDate>
		<dc:creator>Robert Gay</dc:creator>
				<category><![CDATA[Internships]]></category>

		<guid isPermaLink="false">http://blog.redfin.com/devblog/?p=1487</guid>
		<description><![CDATA[Kelsey, a Product Manager (PM) intern here at Redfin over the summer, took a non-traditional approach to writing about her summer internship &#8211; she created a mock-up. We&#8217;ve been sitting on it for months while we published posts by other interns describing their impact, their pre-Redfin identity crises, past lives in biostatistics, and how there&#8217;s...  <a href="http://blog.redfin.com/devblog/2012/12/stealth_internship_collections.html" class="read-more">Read&#160;More</a>]]></description>
				<content:encoded><![CDATA[<p><em>Kelsey, a Product Manager (PM) intern here at Redfin over the summer, took a non-traditional approach to writing about her summer internship &#8211; she created a mock-up. We&#8217;ve been sitting on it for months while we published posts by other interns <a href="http://blog.redfin.com/devblog/2012/08/right_place_right_time.html">describing their impact</a>, <a href="http://blog.redfin.com/devblog/2012/10/enter_stage_left_redfin.html">their pre-Redfin identity crises</a>, <a href="http://blog.redfin.com/devblog/2012/10/redfin_journey.html">past lives in biostatistics</a>, and how <a href="http://blog.redfin.com/devblog/2012/11/theres_no_place_like_redfin.html">there&#8217;s no place like Redfin</a>, but now that we&#8217;ve released <a href="http://www.redfin.com/collections">Redfin Collections</a> (<a href="http://blog.redfin.com/blog/2012/12/a_beautiful_find.html">maybe you&#8217;ve heard of it?</a>) we&#8217;re finally allowed to hit publish! </em></p>
<p><img class="aligncenter size-full wp-image-1488" src="http://blog.redfin.com/devblog/wp-content/uploads/sites/3/2012/12/My-Summer-Internship.png" alt="" width="714" height="1028" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.redfin.com/devblog/2012/12/stealth_internship_collections.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automagic event emails</title>
		<link>http://blog.redfin.com/devblog/2012/12/automagic_event_emails.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=automagic_event_emails</link>
		<comments>http://blog.redfin.com/devblog/2012/12/automagic_event_emails.html#comments</comments>
		<pubDate>Mon, 17 Dec 2012 18:15:59 +0000</pubDate>
		<dc:creator>Eric Gideon</dc:creator>
				<category><![CDATA[Email]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://blog.redfin.com/devblog/?p=1450</guid>
		<description><![CDATA[Using the Eventbrite API to automate email promotions &#160; At Redfin, the Marketing team contacts customers all over the country about upcoming classes and events near them. We don’t send a lot of email to each recipient – nobody likes spam – but we do send a great deal of small campaigns each week, and...  <a href="http://blog.redfin.com/devblog/2012/12/automagic_event_emails.html" class="read-more">Read&#160;More</a>]]></description>
				<content:encoded><![CDATA[<h3>Using the Eventbrite API to automate email promotions</h3>
<p>&nbsp;</p>
<p>At Redfin, the Marketing team contacts customers all over the country about upcoming classes and events near them. We don’t send a lot of email to each recipient – nobody likes spam – but we do send a great deal of small campaigns each week, and they add up: this year, Redfin will put on almost 1,100 events, and year to date we&#8217;ve sent over 2.8 million emails promoting them. There&#8217;s so much going on that early this year, the team hired a third coordinator to further distribute the work involved in planning, scheduling, and promoting all these events. At the time, the process for building out an email for a class took somewhere under an hour, two or three different pieces of software, and a lot of manual HTML editing. We recently eliminated a couple of steps by integrating Eventbrite’s data API with a platform that generates the HTML emails, taking email prep time down to about 10 minutes and eliminating a lot of potential bugs and omissions.</p>
<div id="attachment_1451" class="wp-caption alignright" style="width: 300px"><a href="http://blog-3.redfintest.com/devblog/wp-content/uploads/sites/3/2012/12/event_email_raw.png"><img class="size-medium wp-image-1451 " title="event_email_raw" src="http://blog-3.redfintest.com/devblog/wp-content/uploads/sites/3/2012/12/event_email_raw-300x225.png" alt="" width="300" height="225" /></a><p class="wp-caption-text">Ugh. Have fun editing agent information.</p></div>
<p>The first step was figuring out how the event coordinators currently worked with email. It wasn’t pretty – they were cracking open HTML email templates I’d built previously, modifying the copy and event information, and sending them out. Our email sending platform prepends tags to links, making even simple tasks like editing anchors problematic. At one point, we managed to create an email that previewed fine in a browser, but after parsing by our system it rendered without the entire bottom half. While the vast majority of emails had no issues, what we were doing was complex and hardly ideal. This started a discussion: we already had a great deal of data in Eventbrite, didn&#8217;t have a short-term solution for building our own events platform, and really wanted to lock down the HTML to prevent avoidable errors.</p>
<p>It wound up being fairly simple to put together. We&#8217;d build a list of our markets, hit <a href="http://eventbrite.github.com/" rel="nofollow" target="_blank">Eventbrite&#8217;s jQuery API</a>, and pull down all the upcoming events from the selected area. Eventbrite gives you a ton of data, but most of what we wanted was in the event description – and would have been tough to parse and jam into an email. Instead, we scrape the event titles for keywords that let us figure out what type of event has been selected. Once that&#8217;s determined, the editable fields (and some uneditable ones, like location, date, and time) are prepopulated with some boilerplate information. At this point the events team can modify the content, toggle some features – do we want to promote an upcoming event? will there be food at the class? – and they&#8217;re ready to go.</p>
<div id="attachment_1452" class="wp-caption alignright" style="width: 300px"><a href="http://blog-3.redfintest.com/devblog/wp-content/uploads/sites/3/2012/12/event_email_generator.png"><img class="size-medium wp-image-1452" title="event_email_generator" src="http://blog-3.redfintest.com/devblog/wp-content/uploads/sites/3/2012/12/event_email_generator-300x290.png" alt="" width="300" height="290" /></a><p class="wp-caption-text">Adding an instructor in the generator is as simple as searching for their name or email.</p></div>
<p>But what about solving the busywork of getting agent information? We have hundreds of agents in markets all over the country, and nobody wants to spend 5 or 10 minutes per email searching for their latest photo and verifying that their phone number and email are correct. At this point I got together with Ben &amp; Robert on the Commerce team, who build &amp; maintain our internal Agent Tools platform, and got some pointers. They&#8217;d just recently implemented type-ahead search, and it would perfectly solve the agent data problem for our emails. With a lot of help from them, and a little bit of tweaking, the generator was updated to pull down agent information and jam it directly into the template. Once we&#8217;re done, <a href="http://f.cl.ly/items/0w1s2K2Q383A2k442F0G/Redfin_event_email_sample.html">the email looks like this</a>!</p>
<p>After smashing some bugs that the events team graciously helped find (it took several days of building emails with the beta generator to really nail things down), we had a pretty robust, semi-automated way to create emails quickly and consistently. The events team can now prep and send promotions much faster than before, and we&#8217;ve been able to really standardize our emails on a couple of minor variations. Even better, we&#8217;re looking into ways to improve and expand automatic HTML generation beyond emails and into other marketing promotions.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.redfin.com/devblog/2012/12/automagic_event_emails.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iOS SDK 6 MKMapKit Behavior</title>
		<link>http://blog.redfin.com/devblog/2012/12/ios_sdk_6_mkmapkit_behavior.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=ios_sdk_6_mkmapkit_behavior</link>
		<comments>http://blog.redfin.com/devblog/2012/12/ios_sdk_6_mkmapkit_behavior.html#comments</comments>
		<pubDate>Tue, 11 Dec 2012 00:00:20 +0000</pubDate>
		<dc:creator>chunglai</dc:creator>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Maps]]></category>
		<category><![CDATA[Mobile]]></category>

		<guid isPermaLink="false">http://blog.redfin.com/devblog/?p=1321</guid>
		<description><![CDATA[A while ago, we updated our mobile app to be compatible with iOS 6 and iPhone 5. While we were working with the latest Xcode that comes with SDK 6, we found a strange behavior in MKMapKit&#8217;s regionThatFits method. In MKMapView,  a region is an area defined with a lat/long coordinate as the center and a span...  <a href="http://blog.redfin.com/devblog/2012/12/ios_sdk_6_mkmapkit_behavior.html" class="read-more">Read&#160;More</a>]]></description>
				<content:encoded><![CDATA[<p>A while ago, we updated our <a href="http://itunes.apple.com/us/app/redfin-real-estate-homes-for/id327962480?mt=8">mobile app</a> to be compatible with iOS 6 and iPhone 5. While we were working with the latest Xcode that comes with SDK 6, we found a strange behavior in MKMapKit&#8217;s <em>regionThatFits</em> method.</p>
<p>In <a href="http://developer.apple.com/library/ios/#Documentation/MapKit/Reference/MKMapView_Class/MKMapView/MKMapView.html">MKMapView</a>,  a region is an area defined with a lat/long coordinate as the center and a span to specify the distance it covers in lat/long delta. Depending on the dimensions of the MKMapView, the region specified may not fit into the view properly.  So there exists a handy method &#8220;<em>regionThatFits</em>&#8221; which takes a region as an argument and returns a new region that will include the region you pass in and fits properly in the aspect ratio of the MKMapView. In SDK 5, if the region specified is very tiny, which means the MKMapView&#8217;s zoom level can&#8217;t support it, the <em>regionThatFits</em> method used to return a minimal region that it can zoom in to. However, with the recent SDK 6 release, the &#8220;<em>regionThatFits</em>&#8221; method returns a region that the map cannot properly zoom to when you give it a tiny input.</p>
<p>In order to prove this finding, we have come up with a simple prototype an app to perform the following steps:</p>
<ol>
<li>Create a MKMapView in an app</li>
<li>Call MKMapView&#8217;s <em>regionThatFits</em> method with a tiny region and output the returned region from <em>regionThatFits</em>. In our prototype,<br />
<em>MKCoordinateRegion region = {{37.787096, -122.391},{1.14441e-05, 9.91821e-05}};</em><br />
<em> MKCoordinateRegion zoomedRegion = [mapView regionThatFits:region];</em></li>
<li>Call MKMapView&#8217;s <em>setRegion</em> method with the region returned from <em>regionThatFits</em><br />
<em>[mapView setRegion:zoomedRegion animated:YES];</em></li>
<li>Inspect the MKMapView&#8217;s current region and compare with the region returned from <em>regionThatFits</em>. Notice the current MKMapView&#8217;s region is larger than the region returned from <em>regionThatFits</em>!</li>
</ol>
<div>In this prototype app, we have created a MKMapView with two buttons and two labels. One of the button zooms the map into a region that works, and another button which zooms into a tiny region that can reproduce the issue (which <em>regionThatFits</em> supposes to return a region that fits in MKMapView). One of the labels indicates the region returned from <em>regionThatFits</em>, and another label that indicates the MKMapView&#8217;s region after calling <em>setRegion</em> with the region returned from <em>regionThatFits</em> so that you can compare the before and after value are DIFFERENT. We also include a iOS version label to indicate the current iOS version since this issue only happens in iOS 6. And here are the screenshots of the result.</div>
<div></div>
<p></p>
<div>Here are the results&#8217; screen shots in the order of (<em>Left to right</em>): iOS 5 with a normal region, iOS 5 with a tiny region, iOS 6 with a normal region, and iOS 6 with a tiny region. Notice the difference in the last one.</div>

<a href='http://blog.redfin.com/devblog/2012/12/ios_sdk_6_mkmapkit_behavior.html/ios_5_normal_region' title='iOS_5_normal_region'><img width="150" height="150" src="http://blog.redfin.com/devblog/wp-content/uploads/sites/3/2012/09/iOS_5_normal_region-150x150.png" class="attachment-thumbnail" alt="iOS_5_normal_region" /></a>
<a href='http://blog.redfin.com/devblog/2012/12/ios_sdk_6_mkmapkit_behavior.html/ios_5_tiny_region' title='iOS_5_tiny_region'><img width="150" height="150" src="http://blog.redfin.com/devblog/wp-content/uploads/sites/3/2012/09/iOS_5_tiny_region-150x150.png" class="attachment-thumbnail" alt="iOS_5_tiny_region" /></a>
<a href='http://blog.redfin.com/devblog/2012/12/ios_sdk_6_mkmapkit_behavior.html/ios_6_normal_region' title='iOS_6_normal_region'><img width="150" height="150" src="http://blog.redfin.com/devblog/wp-content/uploads/sites/3/2012/09/iOS_6_normal_region-150x150.png" class="attachment-thumbnail" alt="iOS_6_normal_region" /></a>
<a href='http://blog.redfin.com/devblog/2012/12/ios_sdk_6_mkmapkit_behavior.html/ios_6_tiny_region' title='iOS_6_tiny_region'><img width="150" height="150" src="http://blog.redfin.com/devblog/wp-content/uploads/sites/3/2012/09/iOS_6_tiny_region-150x150.png" class="attachment-thumbnail" alt="iOS_6_tiny_region" /></a>

<p>We have filed a bug report to Apple&#8217;s iOS SDK team. Hopefully they can address this issue soon, although we don&#8217;t rely heavily on regionThatFits returned region to do any computation at this point.</p>
<p>We hope every mobile developer is having fun with the latest Apple Maps! If anyone has insight about this issue, please leave us a comment.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.redfin.com/devblog/2012/12/ios_sdk_6_mkmapkit_behavior.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dojo Phased Javascript Loading</title>
		<link>http://blog.redfin.com/devblog/2012/12/dojo_phased_javascript_loading.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=dojo_phased_javascript_loading</link>
		<comments>http://blog.redfin.com/devblog/2012/12/dojo_phased_javascript_loading.html#comments</comments>
		<pubDate>Mon, 03 Dec 2012 19:41:48 +0000</pubDate>
		<dc:creator>Robert Law</dc:creator>
				<category><![CDATA[HTML]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Programming Languages]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://blog.redfin.com/devblog/?p=1315</guid>
		<description><![CDATA[Here at Redfin, we undertook a rather large project to redesign one of our most visited pages: the details of a home. This was no easy task but one of the main choices we made early on in the redesign was to fully embrace javascript for handling all of our view code. While this approach...  <a href="http://blog.redfin.com/devblog/2012/12/dojo_phased_javascript_loading.html" class="read-more">Read&#160;More</a>]]></description>
				<content:encoded><![CDATA[<p dir="ltr">Here at Redfin, we undertook a rather large project to redesign one of our most visited pages: the details of a home. This was no easy task but one of the main choices we made early on in the redesign was to fully embrace javascript for handling all of our view code.</p>
<p>While this approach is very appealing from a developers point of view of harmonizing the programming languages for building our pages, we were concerned about the size of the javascript required to be downloaded, parsed and ready to go before even showing anything to our users. In fact, we ran into this issue before with our map page. It had ballooned so much that it required over a MB of JS to be downloaded before anything was rendered on the page.</p>
<p>So, with the new design and the inevitable addition of more and more widgets, we took some time and figured out a strategy for handling a page that requires a lot of javascript. Not only that, we wanted to prioritize the “above the fold” content to render as fast as possible.</p>
<h2>Dojo Parsing</h2>
<p>There are a couple approaches to creating widgets with in dojo. One is to use the parseOnLoad flag of dojo to signal to it that it should parse the DOM once dojo itself and all the dojo.require’s have finished. Another is to hook directly into the dojo.addOnLoad function callback and start creating your own widgets. In both of these cases, in a production environment, we will have to require a main profile rollup of all our javascript code.</p>
<h2>Institutionalizing Javascript Phases</h2>
<p>However, since we wanted to split up the way we did our rollups, dojo didn’t necessary provide us an easy mechanism when certain JS definitions do not exist yet. At first we looked at trapping the errors of missing widgets in parseOnLoad and just re-invoking dojo.parse.parser() once we got the requires but while this somewhat accomplished what we wanted, it wasn’t quite an elegant solution to our problem. It masked other errors that might have happened with the widget creation.</p>
<p>So we looked deeper at the parser and started pulling out parts it so we could control when and where we wanted to invoke the parser.</p>
<h2>A different Dojo type parser</h2>
<p>We decided we would divide up our widgets so that the top of the fold widgets would be in one grouping, the middle content in another grouping and any leftover widgets in the last grouping. Internally we call these groupings “phases”. It’s arbitrary in how many phases we have and what widgets we assign to what phase, but we divided them into three main phases so we could minimize the amount of network requests while still having the top of the fold and middle fold content render as early as possible.</p>
<p>The order in which this parser works is pretty simple. First, it will start executing once dojo.addOnLoad invokes our callback. This essentially means for us that it’s pulled down our main dojo.js rollup and the first “phase” rollup. This enables us to start bootstrapping the page by sending out data requests (see our data loader post later!) and then for the leftover javascript rollups. The key here is that we don’t eval the javascript yet, just store it until we’re ready. It may be the case that the javascript is already cached but we still want to render the page in a certain order so that the users will see the top of the fold content first and as early as possible.</p>
<p>So, after we’ve sent out our network requests, we can start the first widget creation phase. The majority of our widgets extend from a widget that is aware that we’re loading our javascript in phases. This widget overrides the buildRendering phase. We disable _Templated’s scanning for children and just inform our parser that the widget it just created has children that need to be created. The parser does this for each widget it creates, collecting each new dojoType within the templates of the widgets. When it collects these types, it first checks to see if it can create it (does the class exist) and if not, saves it off to be reparsed in the subsequent phase loading.</p>
<p>Once the parser finishes up its first phase scan and widget creation, it will invoke the startup() method on all the widgets. This is pretty much inline with the traditional life-cycle definition of startup(). After all the widgets have been informed, the parser will eval the next phase of javascript and loop through all the saved off dom nodes that it did not find the dojo class for yet.</p>
<p>Upon reaching the last phase, if there are still classes left over, we put in some debugging statements that help us identify any dojoTypes that were never created. We also adjusted the creation of the widgets to not blow up the whole page meaning that whenever there is an error while creating a widget, it will be removed from the list and move on.</p>
<p>All this gives us the ability to render each of our phases, attach them to the DOM and present to the user our content as soon as possible.</p>
<h2>_delayedAdopt</h2>
<p>The last little detail with this setup is programmatic creation. We had to get a little clever so that we could create something once all the javascript rollups have been downloaded. Inspired by <a href="http://higginsforpresident.net/2010/01/widgets-within-widgets/">Higgin’s article for _Adopt</a> (something that we also use for programmatic creation), we created a second function that acts just like adopt() but uses a string for the class name.</p>
<p>delayedAdopt: function(/* string */cls, /* object? */props, /* dom node */node, /* function */callback) {}</p>
<p>The callback is automatically bound to the context it was created in just like the normal adopt() but will not execute until that the require for that widget has been pulled down. This lets us make the creation of widgets that are not necessary in the top of the fold content be created in a later phase.</p>
<h2>Phased loading</h2>
<p>With all this together, this gives us the ability to split up our javascript into chunks and force an order of creating the page. It reduces the initial page size down so that the user is interacting and seeing something almost immediately. Most people eat with their eyes and dislike pages that seem to be loading slowly. Hopefully this makes it <em>seem</em> like the page loads faster for users.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.redfin.com/devblog/2012/12/dojo_phased_javascript_loading.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
