<?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>Shawn Wilsher &#187; Firefox</title>
	<atom:link href="http://shawnwilsher.com/archives/tag/firefox/feed" rel="self" type="application/rss+xml" />
	<link>http://shawnwilsher.com</link>
	<description></description>
	<lastBuildDate>Sun, 04 Dec 2011 10:37:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Social Plugins&#8217; Memory Usage</title>
		<link>http://shawnwilsher.com/archives/549</link>
		<comments>http://shawnwilsher.com/archives/549#comments</comments>
		<pubDate>Thu, 25 Aug 2011 02:41:33 +0000</pubDate>
		<dc:creator>Shawn Wilsher</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[about:memory]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[memory]]></category>

		<guid isPermaLink="false">http://shawnwilsher.com/?p=549</guid>
		<description><![CDATA[Dietrich recently posted about the memory usage of social plugins, and I found the results rather surprising because, at least in the case of Facebook, I didn&#8217;t think it ever loaded enough code to consume 20+MB of memory. When I first learned about social plugins, I thought that they were a really cool idea and [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://autonome.wordpress.com/2011/08/23/wallflower-un-socializing-your-web/">Dietrich recently posted about the memory usage of social plugins</a>, and I found the results rather surprising because, at least in the case of Facebook, I didn&#8217;t think it ever loaded enough code to consume 20+MB of memory.</p>
<p>When I first learned about <a href="https://developers.facebook.com/docs/plugins/">social plugins</a>, I thought that they were a really cool idea and thought that they had a lot of potential.  If they use a ton of memory though, I feel like it&#8217;s a bit of a deal breaker to using them.  So, being the curious engineer that I am, I decided to test this out myself.  I conducted these tests in a new Firefox profile and I was not signed into Facebook (to try and replicate the experience Dietrich had).</p>
<h3>One Like Button</h3>
<p>For my first test, I had a very simple page for the default <a href="https://developers.facebook.com/docs/reference/plugins/like">like social plugin</a> pointing to my site.</p>
<p><script src="https://gist.github.com/1169663.js?file=like_test.html"></script></p>
<div><a href="http://shawnwilsher.com/wp-content/uploads/2011/08/like.png"><img src="http://shawnwilsher.com/wp-content/uploads/2011/08/like-300x198.png" alt="like page result" title="like" width="300" height="198" class="aligncenter size-medium wp-image-552" /></a></div>
<div><img src="http://shawnwilsher.com/wp-content/uploads/2011/08/like-data.png" alt="" title="like-data" width="576" height="152" class="align-none size-full wp-image-553" /></div>
<p>One like button doesn&#8217;t seem to add much, which is good!</p>
<h3>Two Like Buttons</h3>
<p>The next test I tried was duplicating the like button so it showed up twice.  This code is a bit naive since I duplicate a <code>&lt;div&gt;</code> element with the same <code>id</code> and don&#8217;t need to include the JavaScript twice.  However, it shows what someone who would just copy and paste will end up with, which I think is valuable.</p>
<p><script src="https://gist.github.com/1169669.js?file=like_2_test.html"></script></p>
<div><a href="http://shawnwilsher.com/wp-content/uploads/2011/08/like-2.png"><img src="http://shawnwilsher.com/wp-content/uploads/2011/08/like-2-300x202.png" alt="like page (two button) result" title="like-2" width="300" height="202" class="aligncenter size-medium wp-image-557" /></a></div>
<div><img src="http://shawnwilsher.com/wp-content/uploads/2011/08/like-2-data.png" alt="" title="like-2-data" width="569" height="154" class="alignnone size-full wp-image-558" /></div>
<p>As you can see, memory usage nearly doubled.  This is a bit surprising since the exact same JavaScript is included.  I would expect there to not be any additional <a href="https://developer.mozilla.org/En/SpiderMonkey/Internals/Property_cache#Shape"><code>shapes</code></a>, but that nearly doubles.  <code>scripts</code> and <code>mjit-code</code> also all double, and I would expect that at least the latter to not.</p>
<p>A more interesting version of this test would be to not include the JavaScript twice, and just add one additional <code>&lt;fb:like&gt;</code> button that doesn&#8217;t like the same url.</p>
<p><script src="https://gist.github.com/1169777.js?file=like_2b_test.html"></script></p>
<div><a href="http://shawnwilsher.com/wp-content/uploads/2011/08/like-2b.png"><img src="http://shawnwilsher.com/wp-content/uploads/2011/08/like-2b-300x198.png" alt="two like button test results" title="like-2b" width="300" height="198" class="alignnone size-medium wp-image-568" /></a></div>
<div><a href="http://shawnwilsher.com/wp-content/uploads/2011/08/like-2b-data.png"><img src="http://shawnwilsher.com/wp-content/uploads/2011/08/like-2b-data.png" alt="" title="like-2b-data" width="568" height="151" class="alignnone size-full wp-image-569" /></a></p>
<p>Interestingly, memory usage did not change significantly from the duplicate resource case!  So, what exactly is going on here?  This page ends up loading four additional resources:</p>
<table>
<thead>
<tr>
<td>File</td>
<td>HTTP Status</td>
<td>Size</td>
<td>Mime Type</td>
</tr>
</thead>
<tbody>
<tr>
<td><a href="http://connect.facebook.net/en_US/all.js#appId=167435886666146&#038;xfbml=1" title="http://connect.facebook.net/en_US/all.js#appId=167435886666146&#038;xfbml=1">all.js</a></td>
<td>304</td>
<td>143KB</td>
<td><code>application/x-javascript</code></td>
</tr>
<tr>
<td><a href="http://www.facebook.com/extern/login_status.php?api_key=167435886666146&#038;app_id=167435886666146&#038;channel_url=http%3A%2F%2Fstatic.ak.fbcdn.net%2Fconnect%2Fxd_proxy.php%3Fversion%3D3%23cb%3Df1b63e91087165a%26origin%3Dfile%253A%252F%252F%252Ff1d19be94c0f99c%26relation%3Dparent.parent%26transport%3Dpostmessage&#038;display=hidden&#038;extern=2&#038;locale=en_US&#038;next=http%3A%2F%2Fstatic.ak.fbcdn.net%2Fconnect%2Fxd_proxy.php%3Fversion%3D3%23cb%3Df2cb8410821cf5%26origin%3Dfile%253A%252F%252F%252Ff1d19be94c0f99c%26relation%3Dparent%26transport%3Dpostmessage%26frame%3Df13c5b92e0fb36%26result%3D%2522xxRESULTTOKENxx%2522&#038;no_session=http%3A%2F%2Fstatic.ak.fbcdn.net%2Fconnect%2Fxd_proxy.php%3Fversion%3D3%23cb%3Df1b97f8de7e7a6e%26origin%3Dfile%253A%252F%252F%252Ff1d19be94c0f99c%26relation%3Dparent%26transport%3Dpostmessage%26frame%3Df13c5b92e0fb36&#038;no_user=http%3A%2F%2Fstatic.ak.fbcdn.net%2Fconnect%2Fxd_proxy.php%3Fversion%3D3%23cb%3Dff68d6635d7af6%26origin%3Dfile%253A%252F%252F%252Ff1d19be94c0f99c%26relation%3Dparent%26transport%3Dpostmessage%26frame%3Df13c5b92e0fb36&#038;ok_session=http%3A%2F%2Fstatic.ak.fbcdn.net%2Fconnect%2Fxd_proxy.php%3Fversion%3D3%23cb%3Dfc9586db992bf6%26origin%3Dfile%253A%252F%252F%252Ff1d19be94c0f99c%26relation%3Dparent%26transport%3Dpostmessage%26frame%3Df13c5b92e0fb36&#038;sdk=joey&#038;session_origin=1&#038;session_version=3" title="http://www.facebook.com/extern/login_status.php?api_key=167435886666146&#038;app_id=167435886666146&#038;channel_url=http%3A%2F%2Fstatic.ak.fbcdn.net%2Fconnect%2Fxd_proxy.php%3Fversion%3D3%23cb%3Df1b63e91087165a%26origin%3Dfile%253A%252F%252F%252Ff1d19be94c0f99c%26relation%3Dparent.parent%26transport%3Dpostmessage&#038;display=hidden&#038;extern=2&#038;locale=en_US&#038;next=http%3A%2F%2Fstatic.ak.fbcdn.net%2Fconnect%2Fxd_proxy.php%3Fversion%3D3%23cb%3Df2cb8410821cf5%26origin%3Dfile%253A%252F%252F%252Ff1d19be94c0f99c%26relation%3Dparent%26transport%3Dpostmessage%26frame%3Df13c5b92e0fb36%26result%3D%2522xxRESULTTOKENxx%2522&#038;no_session=http%3A%2F%2Fstatic.ak.fbcdn.net%2Fconnect%2Fxd_proxy.php%3Fversion%3D3%23cb%3Df1b97f8de7e7a6e%26origin%3Dfile%253A%252F%252F%252Ff1d19be94c0f99c%26relation%3Dparent%26transport%3Dpostmessage%26frame%3Df13c5b92e0fb36&#038;no_user=http%3A%2F%2Fstatic.ak.fbcdn.net%2Fconnect%2Fxd_proxy.php%3Fversion%3D3%23cb%3Dff68d6635d7af6%26origin%3Dfile%253A%252F%252F%252Ff1d19be94c0f99c%26relation%3Dparent%26transport%3Dpostmessage%26frame%3Df13c5b92e0fb36&#038;ok_session=http%3A%2F%2Fstatic.ak.fbcdn.net%2Fconnect%2Fxd_proxy.php%3Fversion%3D3%23cb%3Dfc9586db992bf6%26origin%3Dfile%253A%252F%252F%252Ff1d19be94c0f99c%26relation%3Dparent%26transport%3Dpostmessage%26frame%3Df13c5b92e0fb36&#038;sdk=joey&#038;session_origin=1&#038;session_version=3">login_status.php</a></td>
<td>200</td>
<td>58b</td>
<td><code>text/html</code></td>
</tr>
<tr>
<td><a href="<br />
    http://www.facebook.com/plugins/like.php?action=like&#038;api_key=167435886666146&#038;channel_url=http%3A%2F%2Fstatic.ak.fbcdn.net%2Fconnect%2Fxd_proxy.php%3Fversion%3D3%23cb%3Df1b349661c9cd1c%26origin%3Dfile%253A%252F%252F%252Ff1d19be94c0f99c%26relation%3Dparent.parent%26transport%3Dpostmessage&#038;href=http%3A%2F%2Fshawnwilsher.com%2F&#038;layout=standard&#038;locale=en_US&#038;node_type=link&#038;sdk=joey&#038;send=true&#038;show_faces=true&#038;width=450" title="<br />
    http://www.facebook.com/plugins/like.php?action=like&#038;api_key=167435886666146&#038;channel_url=http%3A%2F%2Fstatic.ak.fbcdn.net%2Fconnect%2Fxd_proxy.php%3Fversion%3D3%23cb%3Df1b349661c9cd1c%26origin%3Dfile%253A%252F%252F%252Ff1d19be94c0f99c%26relation%3Dparent.parent%26transport%3Dpostmessage&#038;href=http%3A%2F%2Fshawnwilsher.com%2F&#038;layout=standard&#038;locale=en_US&#038;node_type=link&#038;sdk=joey&#038;send=true&#038;show_faces=true&#038;width=450">like.php</a></td>
<td>200</td>
<td>33KB</td>
<td><code>text/html</code></td>
</tr>
<td><a href="http://www.facebook.com/plugins/like.php?action=like&#038;api_key=167435886666146&#038;channel_url=http%3A%2F%2Fstatic.ak.fbcdn.net%2Fconnect%2Fxd_proxy.php%3Fversion%3D3%23cb%3Df69d9c19ebd99a%26origin%3Dfile%253A%252F%252F%252Ff1d8c7be660a56c%26relation%3Dparent.parent%26transport%3Dpostmessage&#038;href=http%3A%2F%2Fshawnwilsher.com%2Farchives%2F549&#038;layout=standard&#038;locale=en_US&#038;node_type=link&#038;sdk=joey&#038;send=true&#038;show_faces=true&#038;width=450" title="http://www.facebook.com/plugins/like.php?action=like&#038;api_key=167435886666146&#038;channel_url=http%3A%2F%2Fstatic.ak.fbcdn.net%2Fconnect%2Fxd_proxy.php%3Fversion%3D3%23cb%3Df69d9c19ebd99a%26origin%3Dfile%253A%252F%252F%252Ff1d8c7be660a56c%26relation%3Dparent.parent%26transport%3Dpostmessage&#038;href=http%3A%2F%2Fshawnwilsher.com%2Farchives%2F549&#038;layout=standard&#038;locale=en_US&#038;node_type=link&#038;sdk=joey&#038;send=true&#038;show_faces=true&#038;width=450">like.php</a></td>
<td>200</td>
<td>33KB</td>
<td><code>text/html</code></td>
</tr>
</tbody>
</table>
<p>That is 209KB of HTML and JavaScript that is being sent for two like buttons.  Something tells me that part of the problem here is that Facebook is sending more than it needs to for this (I did not look into exactly what was being sent).  The good news is that 143KB comes from the browser&#8217;s cache.</p>
<h3>Send Button</h3>
<p>The last test I did was the <a href="https://developers.facebook.com/docs/reference/plugins/send/">send button</a> pointing to my website.</p>
<p><script src="https://gist.github.com/1169664.js?file=send_test.html"></script></p>
<div><a href="http://shawnwilsher.com/wp-content/uploads/2011/08/send.png"><img src="http://shawnwilsher.com/wp-content/uploads/2011/08/send-300x202.png" alt="send test results" title="send" width="300" height="202" class="aligncenter size-medium wp-image-559" /></a></div>
<div><a href="http://shawnwilsher.com/wp-content/uploads/2011/08/send-data.png"><img src="http://shawnwilsher.com/wp-content/uploads/2011/08/send-data.png" alt="" title="send-data" width="578" height="138" class="alignnone size-full wp-image-560" /></a></div>
<p>Given that the like button test includes a send button as well, I&#8217;m not surprised to see that this used even less memory.</p>
<h3>Summary</h3>
<p>I think there are are two problems here:</p>
<ol>
<li>Firefox should create less shapes and do a better job of not duplicating the same JavaScript code in a given compartment.</li>
<li>Facebook needs to send less data down for their social plugins.  I have a hard time believing that that much JavaScript is needed in order to display a like button, a share button, and a faces of your friends who have liked a page.</li>
</ol>
<p>It&#8217;d be interesting to see how these numbers change when you are logged in, but I don&#8217;t have time to do that analysis.  I&#8217;ve provided all the code and steps I used to get these results, so it shouldn&#8217;t be too hard for someone else to come along and do that if they are interested.  Another interesting test would be to see how the Twitter and Google+ integrations break down too (but I leave that as an exercise for the reader).</p>
]]></content:encoded>
			<wfw:commentRss>http://shawnwilsher.com/archives/549/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Classic Straw Man</title>
		<link>http://shawnwilsher.com/archives/493</link>
		<comments>http://shawnwilsher.com/archives/493#comments</comments>
		<pubDate>Wed, 26 Jan 2011 19:29:25 +0000</pubDate>
		<dc:creator>Shawn Wilsher</dc:creator>
				<category><![CDATA[Firefox]]></category>
		<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[acid3]]></category>
		<category><![CDATA[rant]]></category>
		<category><![CDATA[straw man]]></category>

		<guid isPermaLink="false">http://shawnwilsher.com/?p=493</guid>
		<description><![CDATA[Erik Dahlström felt compeled to respond to limi&#8217;s post about why Firefox will not pass the ACID3 test. Erik&#8217;s post claims to bust two myths: You need to implement the whole SVG 1.1 Fonts chapter to pass Acid3 SVG Fonts and foreignObject support are both required to pass Acid3 Let&#8217;s be clear here: these two [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://my.opera.com/MacDev_ed/blog/2011/01/25/on-mythbusting-and-the-web-and-why-svg-fonts-are-sometimes-useful">Erik Dahlström felt compeled to respond</a> to limi&#8217;s post about <a href="http://limi.net/articles/firefox-acid3">why Firefox will not pass the ACID3 test</a>.  Erik&#8217;s post claims to bust two myths:</p>
<ol>
<li>You need to implement the whole SVG 1.1 Fonts chapter to pass Acid3</li>
<li>SVG Fonts and foreignObject support are both required to pass Acid3</li>
</ol>
<p>Let&#8217;s be clear here: these two statements were never made by limi, or by bz, <a href="http://developers.slashdot.org/comments.pl?sid=1713004&#038;cid=32847010">whose quote</a> is used in both posts.  Erik used only parts of bz&#8217;s quote that helped his argument, and conveniently left out this bit:</p>
<blockquote><p>We don’t particularly want to do that small subset in Gecko, since it gives no benefits to authors or users over the existing downloadable font support (beyond the brownie points on Acid3).</p>
<p>On the other hand, support for the full specification in a UA that also supports HTML is… very difficult. SVG fonts are just not designed with integration with HTML in mind. Once you put an &lt;iframe&gt; in a glyph, all sorts of issues arise — both in terms of the spec being underdefined and in terms of the behavior being very difficult to implement, no matter what the spec said.</p>
</blockquote>
<p>The astute reader might notice that Erik used a <a href="https://secure.wikimedia.org/wikipedia/en/wiki/Straw_man">straw man argument</a> to disprove limi&#8217;s post.  Luckily, it <a href="http://www.reddit.com/r/programming/comments/f9bi9/on_mythbusting_and_the_web_and_why_svg_fonts_are/c1e9ns8">looks like not everybody on the Internet has fallen for this logical fallacy</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://shawnwilsher.com/archives/493/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Changes to how Places stores data incoming</title>
		<link>http://shawnwilsher.com/archives/473</link>
		<comments>http://shawnwilsher.com/archives/473#comments</comments>
		<pubDate>Thu, 16 Dec 2010 01:05:16 +0000</pubDate>
		<dc:creator>Shawn Wilsher</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[asynchronous]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[location bar]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[places]]></category>
		<category><![CDATA[SQLite]]></category>

		<guid isPermaLink="false">http://shawnwilsher.com/?p=473</guid>
		<description><![CDATA[Sometime soon after the beta 8 code freeze, the Places team will be merging the Places branch into mozilla-central. There are a lot of changes we’ve been working on, the most important of which is some major re-architecting how we store data. The Benefits The work on the Places branch brings us a number of [...]]]></description>
			<content:encoded><![CDATA[<p>Sometime soon <del>after the beta 8 code freeze</del>, the Places team will be merging the Places branch into mozilla-central.  There are a lot of changes we’ve been working on, the most important of which is some major re-architecting how we store data.</p>
<h3>The Benefits</h3>
<p>The work on the Places branch brings us a number of benefits.  In general, we&#8217;ve parallelized work, and made it substantially less likely that we&#8217;ll block on the GUI thread.  Some of the important fixes we have landed are:</p>
<ul>
<li>Faster Location Bar
<div>The location bar is faster because other database work no longer blocks us from searching, and the queries are much simpler.</div>
</li>
<li>Asynchronous Bookmark Notifications
<div>Indicating if the current page is bookmarked in the location bar (with the star) is now an asynchronous operation that does not block the page load.</div>
</li>
<li>Faster Bookmarks &#038; History Management/Searches
<div>Simpler queries and other improvements should make this all work faster.</div>
</li>
<li>Faster Link Coloring
<div>Link coloring is now executed on a separate database connection so it cannot block other database work.</div>
</li>
<li>Expiration Work
<div>Less work at startup, less work at shutdown, and less work when we run expiration.</div>
</li>
<li>Less Data Stored
<div>Embedded pages are now tracked only in memory and never hit the disk.</li>
<li>Better Battery Management
<div>Much less work during idle time, which will improve our power consumption behaviors.</div>
</li>
<li>Fixes <a href="https://bugzilla.mozilla.org/buglist.cgi?quicksearch=fixed-in-places%20blocking2.0%3A%2B">29 blockers</a> and <a href="https://bugzilla.mozilla.org/buglist.cgi?quicksearch=fixed-in-places%20blocking2.0%3A---">18 other issues</a></li>
</ul>
<h3>A bit of History</h3>
<p>Way back in the days leading up to Firefox 3.5, we moved from storing all of our history and location data in disk tables to in-memory tables that we’d flush out to disk every two minutes off of the GUI thread.  The benefit of this was two-fold:</p>
<ol>
<li>No longer performing the vast majority of our disk writes on the GUI thread</li>
<li>No longer performing the vast majority of our fsyncs/Flushes on the GUI thread</li>
</ol>
<p>More details about how we came up with this solution can be found in a <a href="http://shawnwilsher.com/archives/168">series</a> <a href="http://shawnwilsher.com/archives/169">of</a> <a href="http://shawnwilsher.com/archives/170">blog</a> <a href="http://shawnwilsher.com/archives/172">posts</a>.</p>
<h3>The Problem</h3>
<p>This solution has worked out pretty well for us for a while, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=563538">but recently, especially on OS X, it has not been</a>.  The short story is that our architecture did not scale well due to <a href="http://en.wikipedia.org/wiki/Lock_%28computer_science%29#Granularity">lock contention</a> between our GUI thread and our background I/O thread.  While the common case access case may be fine, the failure case (when we hit lock contention) is pretty terrible.  The problem is so terrible that <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=563538#c55">I once described it</a> like this:</p>
<blockquote><p>the failure case makes us fall on our faces, skid about 100 feet, and then fall off a cliff without a parachute.</p></blockquote>
<p>Ultimately, the only way we can avoid this situation is to not do any database work on separate threads with the same database connection.  It was not an issue in the past because we just did not do enough work on the I/O thread, but as we have added to the workload of that thread, we increase the likelihood of it holding the lock, which means there is a higher probability that the GUI thread will not be able to instantly acquire the lock and do whatever it needs to do.  This essentially leaves us with two options:</p>
<ol>
<li>Move the rest of our database work off of the GUI thread.</h3>
<li>Move database work from the I/O thread back to the GUI thread.</h3>
</ol>
<h3>The Solution</h3>
<p>The second choice is not actually a viable option.  Disk I/O completes in a non-deterministic amount of time, which is why we have been moving it from the GUI thread to an I/O thread since Firefox 3.5.  The first choice is not entirely viable either due to schedule constraints either (we have tons of API calls that are not used heavily but still synchronous).  A hybrid solution exists, however.  We can reduce the amount of work we do on the I/O thread by using additional I/O threads.  Additionally, we can move the remaining synchronous operations during browsing to an I/O thread.  In the end, Places ends up with one read/write thread, and multiple read-only threads.</p>
<p>This wasn’t really an option back in the Firefox 3.5 days because in SQLite readers and writers blocked each other.  However, the SQLite developers recently devised a new journaling method called <a href="http://www.sqlite.org/wal.html">WAL</a> that lets readers not block writers, and writers not block readers.  When the Places branch merges into mozilla-central, we will end up with three read-only I/O threads and our original read-write I/O thread.  The three read-only threads are used for location bar searches, visited checks (is a given hyperlink visited), and some bookmark operations.  Each I/O thread has its own connection to the database, allowing operations to happen in parallel (SQLite is only threadsafe because it serializes all access on each connection object, which is why we had the lock contention in the first place).</p>
<h3>Performance Test Issues</h3>
<p>One of the things that made this work especially difficult is seemingly random changes in performance numbers.  We often had regressions suddenly appear (according to talos) on changesets that would have zero impact on performance, and then backing out the change would cause an additional regression.  Other times, when we would merge mozilla-central into Places, we would suddenly get new regressions when comparing to mozilla-central.  This could be indicative of a bad interaction with our code and the changes on mozilla-central, however after looking at the changes on mozilla-central that landed with the merge, that appeared to be highly unlikely.</p>
<p>I&#8217;m also quite certain that some of our performance tests do not actually test/measure what we actually want to test/measure.  I&#8217;ll leave that discussion to a future blog posts, however.</p>
]]></content:encoded>
			<wfw:commentRss>http://shawnwilsher.com/archives/473/feed</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Startup Time in the Wild Take Two</title>
		<link>http://shawnwilsher.com/archives/448</link>
		<comments>http://shawnwilsher.com/archives/448#comments</comments>
		<pubDate>Fri, 13 Aug 2010 19:20:45 +0000</pubDate>
		<dc:creator>Shawn Wilsher</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[add-ons]]></category>
		<category><![CDATA[cookies]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[session restore]]></category>
		<category><![CDATA[startup]]></category>

		<guid isPermaLink="false">http://shawnwilsher.com/?p=448</guid>
		<description><![CDATA[This week, I spent some time looking at some real life profiles that were sent into us by users seeing startup time in the minutes. The tests were ran just like I ran the test on my profile: all add-ons disabled. The results I got are both good and bad, but first the results! Results [...]]]></description>
			<content:encoded><![CDATA[<p>This week, I spent some time looking at some real life profiles that were sent into us by users seeing startup time in the minutes.  The tests were ran just like I ran the test on my profile: all add-ons disabled.  The results I got are both good and bad, but first the results!</p>
<h2>Results</h2>
<p>The first shows the raw test run data (which isn’t terribly interesting). The second compares the reported startup time for each test. You will probably want to click to zoom in.</p>
<div align="center"><a href="http://shawnwilsher.com/wp-content/uploads/2010/08/data.png"><img src="http://shawnwilsher.com/wp-content/uploads/2010/08/data-300x217.png" alt="" title="Raw Data" width="300" height="217" class="aligncenter size-medium wp-image-453" /></a></div>
<p><br/></p>
<div align="center"><a href="http://shawnwilsher.com/wp-content/uploads/2010/08/startup.png"><img src="http://shawnwilsher.com/wp-content/uploads/2010/08/startup-300x217.png" alt="" title="Startup Comparison" width="300" height="217" class="aligncenter size-medium wp-image-454" /></a></div>
<h2>Conclusions</h2>
<p>Like I said, the results are both good and bad.  Good in that I now have a pretty good idea on why people have bad startup times.  Bad in that we don&#8217;t have any way to quickly improve the issues that people are seeing.  What I see from this data is that profiles in the wild, with add-ons disabled aren&#8217;t much slower than a clean profile.  This seems to implicate add-ons being at least part of the problem (which we knew) or possibly all of the problem at this point (for the profiles tested).  The good news is that the add-ons team is already working on solutions to this, and you should expect some blog posts from them about this soon.</p>
<h2>Next Step</h2>
<p>Next week I&#8217;m going to spend some time getting numbers with these profiles on the latest release of Firefox 3.6 with and without add-ons disabled to compare.  This will pretty much confirm or deny my hypothesis of this week&#8217;s results.</p>
<h2>News on the Past</h2>
<p>In my <a href="http://shawnwilsher.com/archives/421">last post</a>, we looked at my profile with various pieces removed to try and figure out why startup might be slow for people.  With those results, I identified two issues that would impact startup the most:</p>
<ol>
<li>Large cookies.sqlite</li>
<li>Many tabs being restored</li>
</ol>
<p>I also have good news about both of these issues!  The <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=572223">cookies.sqlite issue is now fixed</a> and will be a part of beta 4, and <a href="http://zpao.com/">Paul</a> has <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=582005#c10">some good data</a> about session restore and tabs (with more to come).</p>
]]></content:encoded>
			<wfw:commentRss>http://shawnwilsher.com/archives/448/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Perilous Performance Proportions</title>
		<link>http://shawnwilsher.com/archives/410</link>
		<comments>http://shawnwilsher.com/archives/410#comments</comments>
		<pubDate>Sat, 24 Jul 2010 21:09:32 +0000</pubDate>
		<dc:creator>Shawn Wilsher</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[session restore]]></category>
		<category><![CDATA[startup]]></category>

		<guid isPermaLink="false">http://shawnwilsher.com/?p=410</guid>
		<description><![CDATA[Recently, I started working on one of our Q3 goals to reduce &#8220;dirty&#8221; profile startup time to be only 20% of normal startup time. It is a pretty big and scary problem, and is probably the hardest problem I have ever worked on for the Mozilla project (I have had some doozies in the past [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, I started working on one of our Q3 goals <a href="https://wiki.mozilla.org/Firefox/Projects/2010Q3_Dirty_Startup_Reduction">to reduce &#8220;dirty&#8221; profile startup time to be only 20% of normal startup time</a>.  It is a pretty big and scary problem, and is probably the hardest problem I have ever worked on for the Mozilla project (I have had some doozies in the past too&#8230;).  So far I have only spent time trying to get consistent results of startup time with a dirty profile (of the Firefox kind) so I can then compare profiles (of the <a href="http://en.wikipedia.org/wiki/Profiling_%28computer_programming%29">program profile</a> kind) to a clean profile (of the Firefox kind).  For now, I am just using a copy of my own profile to get some data (no, you cannot have a copy of it).</p>
<p>Unfortunately, I immediately hit a bit of a speed bump.  I think a picture best explains this:</p>
<div align="center"><a href="http://shawnwilsher.com/wp-content/uploads/2010/07/startup.png"><img src="http://shawnwilsher.com/wp-content/uploads/2010/07/startup-300x218.png" alt="chart of dirty startup" title="Dirty Startup Chart" width="300" height="218" class="size-medium wp-image-412" /></a></div>
<p>This is a chart of the 20 runs talos does when measuring startup time.  As you can see, the dirty profile kept on increasing each and every run.  After about a day of investigating this, the cause is finally known: tabs.  Turns out, talos tries to quit the browser before calling <code>window.close()</code>, which results in the tabs not closing.  As a result, at the end of the 20 cycles, we were loading 19 more tabs than the first cycle.  I <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=581711" title="goQuitApplication called before window.close()">filed a bug about this behavior against talos</a>.  It does not matter now, but if we ever decide to change the default preference in Firefox to load your windows and tabs from last time this will come back to bite us.</p>
<p>I did learn something useful out of all of this though: startup time scales linearly with the number of tabs session restore has to restore.  I confirmed this by running talos with 200 cycles instead of the normal 20, and it was clearly a linear increase.  We should probably figure out a way to mitigate that, but I have not filed a bug on it (yet!).</p>
]]></content:encoded>
			<wfw:commentRss>http://shawnwilsher.com/archives/410/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Bluetooth Tethering with the N900 and T-Mobile</title>
		<link>http://shawnwilsher.com/archives/380</link>
		<comments>http://shawnwilsher.com/archives/380#comments</comments>
		<pubDate>Tue, 02 Mar 2010 04:36:08 +0000</pubDate>
		<dc:creator>Shawn Wilsher</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[Bluetooth]]></category>
		<category><![CDATA[Dial-Up Networking]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[JoikuSpot]]></category>
		<category><![CDATA[N900]]></category>

		<guid isPermaLink="false">http://shawnwilsher.com/?p=380</guid>
		<description><![CDATA[I&#8217;ve been spending the last few train rides to and from work every day trying to figure out how to tether my N900 to my laptop. While Firefox Mobile is nice, there are some things my desktop does better. I first tried using the PC Suite from Nokia, but that wasn&#8217;t successful (it apparently doesn&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been spending the last few train rides to and from work every day trying to figure out how to tether my N900 to my laptop.  While <a href="http://www.mozilla.com/en-US/mobile/">Firefox Mobile</a> is nice, there are some things my desktop does better.  I first tried using the <a href="http://www.nokiausa.com/get-support-and-software/software/nokia-suites-for-your-pc">PC Suite from Nokia</a>, but that wasn&#8217;t successful (it apparently doesn&#8217;t support the N900).  I then tried <a href="http://www.joiku.com/index.php?action=products&#038;mode=productDetails&#038;product_id=605">JoikuSpot</a>, which is in beta.  Sadly, I encountered the &#8220;phone reboots when clients connect&#8221; bug.  However, if they fix that, that piece of software looks very promising.  I finally went down the road to Bluetooth Networking.</p>
<p>In order to pull this off, you&#8217;ll need to get a handy little application from the Application Manager.  Under the Network section, look for &#8220;Bluetooth Dial-Up Networking&#8221; in the Extras repository.  After you install that, you will want to restart your device.  Next, pair your N900 with you laptop (this varies per operating system.  I used Windows 7 and these instructions will assume that).  After pairing the device, add a new Dial-Up connection on that modem.  The phone number will be <code>*99#</code> and you will leave the user name and password blank.  Save the connection, but cancel it when it tries to dial (it will fail anyway).  Now, launch the device manager, and find the Bluetooth modem that should have been installed when you paired the N900 to your computer.  Open its properties, and go to the Advanced tab and set the Extra initialization commands to <code>at+cgdcont=1,"IP","epc.tmobile.com"</code>.  After this, you should be able to connect to the Internet though your phone.</p>
<p>To prove that it works, I wrote this on the train, and I&#8217;m posting while still on the train. :P</p>
<p><small>I found <a href="http://wiki.howardforums.com/index.php/Tether_with_Windows_XP">this particular wiki page</a> to very useful in setting this up, but I found translating the instructions to Windows 7 to be a bit difficult at times.</small></p>
]]></content:encoded>
			<wfw:commentRss>http://shawnwilsher.com/archives/380/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Swing and a Miss</title>
		<link>http://shawnwilsher.com/archives/305</link>
		<comments>http://shawnwilsher.com/archives/305#comments</comments>
		<pubDate>Wed, 02 Sep 2009 21:48:41 +0000</pubDate>
		<dc:creator>Shawn Wilsher</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[AutoComplete]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[location bar]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://shawnwilsher.com/?p=305</guid>
		<description><![CDATA[When we landed the asynchronous location bar, some people started to see substantially slower results. This was alarming since it was supposed to end up speeding or staying the same for everyone. After some investigation, we realized that the AutoComplete code was doing something very dumb with asynchronous searches. The problem was that the code [...]]]></description>
			<content:encoded><![CDATA[<p>When we landed the <a href="http://shawnwilsher.com/archives/279">asynchronous location bar</a>, some people started to see substantially slower results.  This was alarming since it was supposed to end up speeding or staying the same for everyone.  After some investigation, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=509048">we realized that the AutoComplete code was doing something very dumb</a> with asynchronous searches.  The problem was that the code would not actually handle the user pressing the enter key until the next set of results came in.  Not only did this result in slower processing of the user&#8217;s selection, it also meant that weird race conditions would come up such as up opening a new tab, pasting a url in, press enter, and then switch tabs resulting in the reloading of the page that was just switched to.  In other words, epic fail all around.</p>
<p>Luckily, the fix was trivial.  Now we handle the enter keypress immediately when the user hits it, and not later.  Problem solved :)</p>
]]></content:encoded>
			<wfw:commentRss>http://shawnwilsher.com/archives/305/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Session Restore Now Writes to Disk Off of the Main Thread</title>
		<link>http://shawnwilsher.com/archives/294</link>
		<comments>http://shawnwilsher.com/archives/294#comments</comments>
		<pubDate>Mon, 17 Aug 2009 19:47:28 +0000</pubDate>
		<dc:creator>Shawn Wilsher</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[asynchronous]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[fsync]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[session restore]]></category>
		<category><![CDATA[write]]></category>

		<guid isPermaLink="false">http://shawnwilsher.com/?p=294</guid>
		<description><![CDATA[Last week I landed bug 485976 which moves the writing and subsequent fsync (or flush on windows) call to a background thread. This should benefit all of our users, especially those with slower hard drives. Paul O&#8217;Shannessey has filed another bug that will reduce the amount of disk activity substantially more that will benefit our [...]]]></description>
			<content:encoded><![CDATA[<p>Last week I landed <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=485976" title="Move writing sessionstore.js off the main thread">bug 485976</a> which moves the writing and subsequent fsync (or flush on windows) call to a background thread.  This should benefit all of our users, especially those with slower hard drives.  <a href="http://zpao.com/">Paul O&#8217;Shannessey</a> has <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=508740" title="Use mozStorage for SessionStore">filed another bug</a> that will reduce the amount of disk activity substantially more that will benefit our users even more.</p>
<h3>Background</h3>
<p>Session restore writes out to disk very frequently &#8211; every ten seconds, in fact.  This behavior is controllable by the preference <a href="http://kb.mozillazine.org/Browser.sessionstore.interval"><code>browser.sessionstore.interval</code></a> for those who want to reduce that, but then you run the risk of not having all your data saved if you crash.  We really don&#8217;t want to reduce that time for our users.</p>
<p>The amount of data that is written out to disk by session restore scales linearly with the number of tabs and windows you have open.  The more you have, the more data has to be written out to disk, and the longer it is going to take.</p>
<p>As <a href="http://shawnwilsher.com/archives/168">we learned in the past with Places</a>, writing to disk and calling fsync can be painfully slow.  In session restore code, we are doing this very often <em>and</em> on the main thread.  Clearly, this is a bad thing.</p>
<h3>Process and Solution</h3>
<p>This section is a bit technical, so feel free to skip it. The short answer is “do not block the main thread while writing and flushing data to the hard drive.”</p>
<p>We wanted to address this problem as much as we could for Firefox 3.6.  In order to actually reduce the number of writes and fsync calls, we would have to heavily modify how session restore manages and writes its data.  That is a big change that we were not comfortable doing this late in the 3.6 cycle.  On top of that, we do not really have the manpower to do that change since the people who know that code well are working on other performance improvements for this release.  The simple solution for now then is to move our write and fsync calls off of the main thread.</p>
<p>Luckily, <a href="http://weblogs.mozillazine.org/bz/">Boris Zbarsky</a> had recently <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=482310" title=" Add an API to asynchronously copy data to an output stream">written a new API for JS consumers</a> to asynchronously copy an input stream to an output stream.  This API would work great for session restore!  We had to <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=508605" title="NetUtil.asyncCopy does not handle nsISafeOutputStreams correctly">fix one minor issue with the underlying code</a> not properly handling nsISafeOutputStreams (which make sure we fsync properly), but once that was done, <a href="https://bugzilla.mozilla.org/attachment.cgi?id=393074&#038;action=diff">the fix</a> was incredibly simple.</p>
]]></content:encoded>
			<wfw:commentRss>http://shawnwilsher.com/archives/294/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Asynchronous Location Bar has Landed</title>
		<link>http://shawnwilsher.com/archives/279</link>
		<comments>http://shawnwilsher.com/archives/279#comments</comments>
		<pubDate>Tue, 11 Aug 2009 20:33:07 +0000</pubDate>
		<dc:creator>Shawn Wilsher</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[asynchronous]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[location bar]]></category>
		<category><![CDATA[mozStorage]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[places]]></category>
		<category><![CDATA[SQLite]]></category>

		<guid isPermaLink="false">http://shawnwilsher.com/?p=279</guid>
		<description><![CDATA[About two weeks ago the asynchronous location bar work landed in mozilla-central without much issue. It&#8217;s also in the Firefox 3.6 alpha we just recently released. This has the potential to impact all of our users, but those on slower hard drives will notice this the most. Your location bar searches may not complete any [...]]]></description>
			<content:encoded><![CDATA[<p>About two weeks ago the asynchronous location bar work <a href="http://hg.mozilla.org/mozilla-central/pushloghtml?changeset=8cff4bd2121a">landed in mozilla-central</a> without much issue.  It&#8217;s also in the <a href="https://developer.mozilla.org/devnews/index.php/2009/08/07/firefox-3-6-alpha-1-now-available-for-download/">Firefox 3.6 alpha</a> we just recently released.  This has the potential to impact all of our users, but those on slower hard drives will notice this the most.  Your location bar searches may not complete any faster than before, but they certainly won&#8217;t be hanging your browser and locking up the UI.</p>
<h3>Background</h3>
<p>We&#8217;ve been getting reports for some time about the location bar hanging the application for some users when they are typing in it.  This wasn&#8217;t a problem that was reproducible on every machine, and even on machines that saw it, it wasn&#8217;t always 100% reproducible.  Clearly, this behavior is not desirable, so we set out to fix it.</p>
<p>I had a theory to the cause almost a year ago and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=455555">filed a bug</a> that I was hoping we could work on and fix for Firefox 3.5.  We knew that reading data off a disk can be slow (and certainly would complete in a non-deterministic amount of time).  Since SQLite uses blocking read calls (no more code can execute until the data is read from disk), this could certainly be the cause of the slowdown our users were seeing.  Some simple profiling showed that this was largely the cause of the hanging.  Work began on the project, but it was clear that enough issues were cropping up that we were not going to be able to safely take this change for Firefox 3.5, and resources were diverted elsewhere.</p>
<h3>Process and Solution</h3>
<p>This section is a bit technical, so feel free to skip it.  The short answer is &#8220;do not block the main thread while reading from the hard drive.&#8221;</p>
<p>In order to not block the main thread while reading from disk we either need to make SQLite use non-blocking read system calls, or call into SQLite off of the main thread.  Changing the SQLite code isn&#8217;t something we want to do, so that solution was out of the question.  Luckily, we had solved a similar problem with writes and fsyncs earlier in the Firefox 3.5 development with the <a href="http://shawnwilsher.com/archives/162">asynchronous Storage API</a>.</p>
<p>The first implementation that we tried essentially did the same thing that the old code did.  We would execute a query, but this time asynchronously, and then process the results and see if they match.  There were two issues with this approach, however.  The first issue was that we were filtering every history and bookmark entry on the main thread for a given search.  That could be a lot of work we end up doing, and with the additional overhead of moving data across threads, the common case would see no win.  The second issue was that once we selected a result in the location bar, and a search was not yet complete, there would be a hang as the main thread processed a bunch of events that Storage had posted to it containing results.</p>
<p>At this point, we realized we needed to do the filtering on a thread other than the main thread.  After some thought, we was figured that the easiest way to do that would be to use a SQL function that we define in the WHERE clause of our autocomplete queries.  This way, all the filtering is done on a background thread, and the code that runs on the main thread only deals with results we will actually use.  This solution exposed some things in the Storage backend like lock contention and a few other subtle issues, but nothing major came up.</p>
<p>For more details on how the location bar search results are generated, see <a href="http://stackoverflow.com/questions/540725/how-does-firefoxs-awesome-bar-match-strings/1208458#1208458">my explanation here</a>.</p>
<p>If you weren&#8217;t having a problem before, chances are you won&#8217;t notice any difference at all.</p>
]]></content:encoded>
			<wfw:commentRss>http://shawnwilsher.com/archives/279/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Test Build: Asynchronous Location Bar (Take &gt;2)</title>
		<link>http://shawnwilsher.com/archives/270</link>
		<comments>http://shawnwilsher.com/archives/270#comments</comments>
		<pubDate>Sat, 11 Jul 2009 22:32:40 +0000</pubDate>
		<dc:creator>Shawn Wilsher</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[location bar]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[places]]></category>

		<guid isPermaLink="false">http://shawnwilsher.com/?p=270</guid>
		<description><![CDATA[I have another test build for folks to try out. This fixes a possible error condition that could happen in certain circumstances. This build has two known issues: There is a lot of flickering when new results show up. This is being tracked in bug 393902. Your computer will hang for a period of time [...]]]></description>
			<content:encoded><![CDATA[<p>I have another test build for folks to try out.  This fixes a possible error condition that could happen in <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=455555#c104">certain circumstances</a>.  This build has two known issues:</p>
<ol>
<li>There is a lot of flickering when new results show up.  This is being tracked in <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=393902">bug 393902</a>.</li>
<li>Your computer will hang for a period of time (it will become responsive again) if you continue to type once no results are found.  This is being tracked in <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=503701">bug 503701</a>.</li>
</ol>
<p>This is built off of a &#8220;stable&#8221; point of mozilla-central, so it&#8217;s like using a 3.6 nightly.  All the normal warnings apply about using it.  I&#8217;m told this greatly increases the speed at which results obtained by many people.  If you experience any issues (other than the two listed here), please let me know!  The <a href="http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/latest-places/">builds can be found here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://shawnwilsher.com/archives/270/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

