#include"asserts.h"The design follows the KISS principle and I think it is a nice fit to the simplicity of C. While there is not much to it, I wrote numerous tests using it over the past couple of months and all of that testing certainly paid off.
int main(void)
{
c7e3_assert(1 == 1, "1 should equal 1");
c7e3_assert(2 == 2, "2 should equal 2");
c7e3_report();
return 0;
}
Imposterrific
Coding can be fun!
Tuesday, June 22, 2010
A Simple Testing Library for C
To prepare for a recent post graduate computer science class, I wrote a small library in C which aids in the creation of lightweight, unit-test-like programs. The code can be found here, and using it looks a bit like this:
Friday, June 18, 2010
JavaScript Tricks to Speed up Your Site
One of the techniques which makes the web so powerful is the ability to load code, images, and other resources from all over the Internet. So often though, the process of loading these resources and ensuring that all of the required pieces are in place leads to a slow experience for visitors. With the ability to include so much code from across the web, visiting a site could potentially be like installing a new program when it comes to the amount of stuff that needs to be downloaded.
With this in mind, there are a couple of nifty tricks that can help make your app more responsive and I've written up an example site and testing server that shows some ideas for speeding up the user experience when you need to wait for the DOM to load or for additional JavaScript to be fetched and run. We'll begin with document operations.
Often the JavaScript running on a page manipulates the DOM, using
There is a another way, we could request that resources be loaded in parallel and start executing our code before the page is fully loaded. Chances are, your code doesn't need the complete page to be loaded before it starts running, and running before
Lets say you have a web page, a little HTML which includes five JavaScript files. One may be a library used to do animation, another one for loading the users data. In any case, all of these files need to be loaded and some of them depend on others.
The biggest bottleneck for your users is almost certainly having all of these resources load. Network latency is a killer, and something that is often overlooked during development. To create a simulated network environment which can give a more realistic (or even pessimistic) view of the cost of loading these resources, I wrote a "slow server" which can introduce a delay to the file requested. Here is the code for my testing server (designed to run on App Engine):
If you look at this loading process in a profiler you might see something like this:
Now for our first nifty trick. One way to check to see if the necessary prerequisites are present, is by polling the DOM or the JavaScript environment, to see if conditions are right for the code to run. Here is an example of how this code might be rewritten when using some polling helper functions:
With these changes, we shave several seconds off of the user perceived loading time. Specifically we no longer need to wait for the duplicate load (of the
Now that we've seen a way to work around the need for an onload callback, lets look at another place we can tweak the browser's behavior to make a web page more responsive: dynamic script loading.
The most straightforward way to include new code in your page is to use a script tag, something like:
There are a few parts to this trick. The first is to not put all of script includes in the HTML, you could have JavaScript add new script elements to the page which will cause new code to be loaded as needed. In this way, you could load only the resources that are needed at the moment, perhaps some resources would not end up being requested at all. Including a new script could be done in two ways:
Instead you can perform a check to see if
There is one more trick we can add to this loader. Some browsers will interpret the JavaScript in the order in which the scripts were requested, not the order in which they finished loading. That means that a fast loading script further down the list won't be run until a slower script, which appears above it, is loaded. One way we could defeat this delay, is to break the script includes out of linear execution in the JavaScript. If you use setTimeout to introduce a delay in adding the script include to the page, then the code which sets up the script requests can finish quickly and the browser will get back to the script requests later without the same linear constraints. In our code, we wrap the section of
Through the course of this post, I've written a small library for using these tricks when loading JavaScript dynamically in the page as well as a server for trying it out. These are available here as open source code. There are some improvements that could be made here. Off the top of my head, the checkWaiting function could eventually time out if a condition continues to not be met. Also the loader could do more to check to see if a requested script has already been loaded. Any more ideas?
With this in mind, there are a couple of nifty tricks that can help make your app more responsive and I've written up an example site and testing server that shows some ideas for speeding up the user experience when you need to wait for the DOM to load or for additional JavaScript to be fetched and run. We'll begin with document operations.
Often the JavaScript running on a page manipulates the DOM, using
document.getElementById here and document.createElement there. In order to ensure that all the pieces of the page are in place, web programmers often take advantage of the onload callback. It might be used like this<body onload="runMyCodeNow()">Using this technique ensures that all of the things your code might want to read and write from the page are in place. All images have been downloaded, CSS rules have been applied, the layout is all there. However, all of this comes with a cost, your code doesn't run until every last resource has been fetched and rendered. Even the little footer at the bottom of the page, for example, that your code doesn't care about.
There is a another way, we could request that resources be loaded in parallel and start executing our code before the page is fully loaded. Chances are, your code doesn't need the complete page to be loaded before it starts running, and running before
onload will reduce the delay for your users. Before I dive into how this can be accomplished, lets look at an example which uses the old fashioned way.Lets say you have a web page, a little HTML which includes five JavaScript files. One may be a library used to do animation, another one for loading the users data. In any case, all of these files need to be loaded and some of them depend on others.
The biggest bottleneck for your users is almost certainly having all of these resources load. Network latency is a killer, and something that is often overlooked during development. To create a simulated network environment which can give a more realistic (or even pessimistic) view of the cost of loading these resources, I wrote a "slow server" which can introduce a delay to the file requested. Here is the code for my testing server (designed to run on App Engine):
def FilePath(path):With the above code we can introduce a delay on each individual file. To see this in action with our example, here is some HTML which shows a traditional approach, include script includes and an onload callback when everything has loaded.
"""The requested path into a local file path."""
return os.path.join(os.path.dirname(__file__), 'files', path[1:])
class SleepyRenderer(webapp.RequestHandler):
"""Serves the requested page with a client configured delay.
Delay is given as a URL parameter in hundredths of a second to delay.
For example, 200 means wait 2 seconds before responding.
Example request:
http://localhost:8080/hi.html?delay=300&contenttype=text/html
"""
def get(self):
path = self.request.path
delay = self.request.get('delay')
content_type = self.request.get('contenttype') or 'text/html'
if delay:
time.sleep(int(delay)/100)
http_status = 200
requested_file = None
try:
requested_file = open(FilePath(path))
self.response.out.write(requested_file.read())
requested_file.close()
except IOError:
http_status = 404
self.response.set_status(http_status)
self.response.headers['Content-Type'] = content_type
def main():
application = webapp.WSGIApplication([('/.*', SleepyRenderer)],
debug=True)
util.run_wsgi_app(application)
if __name__ == '__main__':
main()
<html>With the above, the page takes several seconds to load and when the very last script has loaded, the 'output' div gets its contents. In many cases, the code really doesn't need to wait for all resources to load, only the ones that are necessary for the code to run. In this case, since the information is added to the output div, we need the output div to exist in the DOM, but we may not need the entire page to load.
<head>
<script src="/testa.js?delay=500&contenttype=text/javascript"></script>
<script src="/testb.js?delay=400&contenttype=text/javascript"></script>
<script>
function init() {
document.getElementById('output');
output.innerHTML = [
'a is ' + a,
'b is ' + b,
'c is ' + c,
'd is ' + d,
'e is ' + e
].join('<br>');
}
</script>
<script src="/testc.js?delay=300&contenttype=text/javascript"></script>
</head>
<body onload="init()">
<script src="/testd.js?delay=200&contenttype=text/javascript"></script>
<div id="output"></div>
<script src="/teste.js?delay=100&contenttype=text/javascript"></script>
<script src="/testa.js?delay=500&contenttype=text/javascript"></script>
</body>
</html>
If you look at this loading process in a profiler you might see something like this:
Now for our first nifty trick. One way to check to see if the necessary prerequisites are present, is by polling the DOM or the JavaScript environment, to see if conditions are right for the code to run. Here is an example of how this code might be rewritten when using some polling helper functions:<script>The code to track the prerequisites and poll is quite simple:
loader.whenNodePresent('output',
function() {
var output = document.getElementById('output');
loader.whenReady(function() {return window['a'];},
function() {
output.innerHTML += 'a is ' + a + '<br>';
});
loader.whenReady(function() {return window['b'];},
function() {
output.innerHTML += 'b is ' + b + '<br>';
});
loader.whenReady(function() {return window['c'];},
function() {
output.innerHTML += 'c is ' + c + '<br>';
});
loader.whenReady(function() {return window['d'];},
function() {
output.innerHTML += 'd is ' + d + '<br>';
});
loader.whenReady(function() {return window['e'];},
function() {
output.innerHTML += 'e is ' + e + '<br>';
});
})
</script>
loader.waiting = [];In the above we use the
loader.whenReady = function(testFunction, callback) {
if (testFunction()) {
callback();
} else {
loader.waiting.push([testFunction, callback]);
window.setTimeout(loader.checkWaiting, 200);
}
};
loader.checkWaiting = function() {
var oldWaiting = loader.waiting;
var numWaiting = oldWaiting.length;
loader.waiting = [];
for (var i = 0; i < numWaiting; i++) {
if (oldWaiting[i][0]()) {
oldWaiting[i][1]();
} else {
loader.waiting.push(oldWaiting[i]);
}
}
if (loader.waiting.length > 0) {
window.setTimeout(loader.checkWaiting, 200);
}
};
loader.whenNodePresent = function(nodeId, callback) {
loader.whenReady(function () {
return document.getElementById(nodeId);
}, callback);
};
whenReady function which takes a couple of functions, one to return a truthy or a falsey value, and one to call back when the first function evaluates to true. If the condition function isn't true when this first call is made, we check back every so often to see if it is ready.With these changes, we shave several seconds off of the user perceived loading time. Specifically we no longer need to wait for the duplicate load (of the
testa script) at the end of the body. The page also appears to be more responsive because the later script's messages appear just after they load but before the page is complete.Now that we've seen a way to work around the need for an onload callback, lets look at another place we can tweak the browser's behavior to make a web page more responsive: dynamic script loading.
The most straightforward way to include new code in your page is to use a script tag, something like:
<html>When the browser's JavaScript interpreter encounters this script src, it stops whatever it's doing and fetches that resource. It doesn't do any more rendering or executing of code until it's finished. This behavior varies a bit in different browsers and is likely an artifact of an old design in which this kind of single threaded behavior was the only option. Since some sites might depend on this linear behavior to get a script's dependencies all in order, this quirk might be with us for a long time. Most of this time, waiting like this is a really silly idea. How often do the scripts that you include depend on one another?
<head>
<script src="some_great_sites_javascript">
...
There are a few parts to this trick. The first is to not put all of script includes in the HTML, you could have JavaScript add new script elements to the page which will cause new code to be loaded as needed. In this way, you could load only the resources that are needed at the moment, perhaps some resources would not end up being requested at all. Including a new script could be done in two ways:
document.write('<script src="somefile.js"></script>');orvar newScript = document.createElement('script');
newScript.src = 'somefile.js';
document.body.appendChild(newScript);Each of the above is appropriate in different situations. Document write adds HTML directly into the page at the point where the page is being loaded, it should only be used for script tag inclusion if the page is not yet loaded. If that page is loaded, using document.write to add the script tag will wipe out the existing body entirely. I've seen this issue in the wild, if you assume document.write is always safe, you'll be bitten when using it after the page has loaded.Instead you can perform a check to see if
document.body exists, if it does then use document.body.appendChild. If it does not yet exist, use document.write. The code for this loader logic might look something like this:loader.loadScript = function(url) {
if (document.body) {
var newScript = document.createElement('script');
newScript.type = 'text/javascript';
newScript.src = url;
document.body.appendChild(newScript);
} else {
document.write('<scr' + 'ipt type="text\/javascript" src="' +
url + '"><\/scr' + 'ipt>');
}
};Now we can request that new JavaScript code be loaded on the fly and it works when the page has not yet finished loaded as well as after it has. There is one more trick we can add to this loader. Some browsers will interpret the JavaScript in the order in which the scripts were requested, not the order in which they finished loading. That means that a fast loading script further down the list won't be run until a slower script, which appears above it, is loaded. One way we could defeat this delay, is to break the script includes out of linear execution in the JavaScript. If you use setTimeout to introduce a delay in adding the script include to the page, then the code which sets up the script requests can finish quickly and the browser will get back to the script requests later without the same linear constraints. In our code, we wrap the section of
loader.loadScript in a short timeout as follows:loader.loadScript = function(url) {
window.setTimeout(function() {
if (document.body) {
var newScript = document.createElement('script');
newScript.type = 'text/javascript';
newScript.src = url;
document.body.appendChild(newScript);
} else {
document.write('<scr' + 'ipt type="text/javascript" src="' +
url + '"><\/scr' + 'ipt>');
}
}, 1);
};With the above changes in place, our example page from before now loads like this when profiled (note that the messages appear in the order that the scripts were loaded, we don't have to wait for everything before we edit the page):
Through the course of this post, I've written a small library for using these tricks when loading JavaScript dynamically in the page as well as a server for trying it out. These are available here as open source code. There are some improvements that could be made here. Off the top of my head, the checkWaiting function could eventually time out if a condition continues to not be met. Also the loader could do more to check to see if a requested script has already been loaded. Any more ideas?
Labels:
app engine,
JavaScript,
open source,
programming
Friday, March 12, 2010
Quite a View
I recently had the privilege of working out of an office near the beach. The sun, the ocean breeze, the pounding of the surf. Laptop makers should really come up with a way to sand-proof these machines.I fully expect that this will draw some inside jokes from a few of you in the #googleajaxapis IRC channel.
Monday, February 08, 2010
New Blog Template
With the growing popularity of mobile phones and lower resolution netbooks, a fixed width blog format is looking less and less appealing. I decided to work on a new look for this blog. The main feature I was looking for was a set of CSS rules that would allow the main content to scale with the viewer's browser window width. If the window is too narrow, the less important content on the sidebar should flow down below the main content.
I began with an existing theme for Blogger, Tekka, that pushes the right sidebar down beneath the main content when the window is narrow. I then made some CSS changes to tweak the look to fit my tastes.
First things first, the default fonts must go! I drew much of my inspiration from Nick Johnson's blog, specifically the way that serif fonts are used in some places for accent while sans-serif is used for most of the content. This is a technique that I experimented with a bit in a graphic design class in college.
For titles I added:
We're nearing the end! The sidebar wasn't quite to my liking so I changed the border style. Lastly, in order to get the sidebar to flow down beneath the main content I set a minimum width. Here is the final style for the sidebar:
I began with an existing theme for Blogger, Tekka, that pushes the right sidebar down beneath the main content when the window is narrow. I then made some CSS changes to tweak the look to fit my tastes.
First things first, the default fonts must go! I drew much of my inspiration from Nick Johnson's blog, specifically the way that serif fonts are used in some places for accent while sans-serif is used for most of the content. This is a technique that I experimented with a bit in a graphic design class in college.
For titles I added:
h1, h2 {
...
font-family: Georgia, 'Times New Roman', Times, serif;
}
h3 {
...
font-family: Trebuchet MS, Verdana, Sans-serif;
}To change the font used for the main text in the page, I set a template variable as follows:<Variable name="bodyFont" description="Text Font"Next I set about changing the style of the title link. You see, when someone is viewing a single post, the blog title becomes a link to the main blog page. So, the blog's title is styled like a link and I found the default link styles a bit jarring. This might seem like a minor change but so often it's the little things that matter. I set this style using
type="font"
default="normal normal 100% 'Lucida Grande',
Verdana, Helvetica, sans-serif"
value="normal normal 100% 'Lucida Grande',
Verdana, Helvetica, sans-serif">
h1 a:visited {
...
color: #505050;
}Now that the text styling is done, the layout could use a bit of adjustment. I changed the margins on the main content to the following:#content-wrapper {
margin-top: 20px;
margin-$endSide: 30px;
margin-bottom: 30;
margin-$startSide: 35px;
}I removed the padding from the h1 title style and the date header. I also removed the style rule entirely for the description.We're nearing the end! The sidebar wasn't quite to my liking so I changed the border style. Lastly, in order to get the sidebar to flow down beneath the main content I set a minimum width. Here is the final style for the sidebar:
#sidebar {
text-transform:none;
background-color: $sidebarBgColor;
color: $sidebarTextColor;
padding-$startSide: 20px;
width: 30%;
min-width: 215px;
float: $endSide;
font: $bodyFont;
border-$startSide:1px solid $mainTextColor;
word-wrap: break-word;
overflow: hidden;
}I debated about posting the whole template here, but I'm not sure that it would be very readable. If you would like the whole thing, leave a comment and I can email it to you.
Wednesday, January 13, 2010
DOM Manipulation in JavaScript, a Utility
In my latest addition to the q12 JavaScript library, I have added a simple function to construct a nested document structure. I grew tired of writing repetitive and difficult to follow code like this
On a realted note, if you're interested in a more powerful templating system, you might want to try Closure Templates which were recently open sourced.
var div = document.createElement('div');
div['id'] = 'outer-div';
var link = document.createElement('a');
link.href = 'http://blog.jeffscudder.com';
link.appendChild(document.createTextNode('my blog'));
div.appendChild(link);Using the new tree function this would become:var div = tree([In the process of writing this utility function, I came across another small oddity in editing HTML using JavaScript related to the style attribute. Most HTML attributes are simple text properties, however when editing the CSS style of a node, you cannot set the full content of the style attribute.
'div', {
id: 'outer-div'}, [
'a', {
href: 'http://blog.jeffscudder.com'}, [
'my blog']]]);
// You cannot do this:Instead, you set each sub item in the style attribute:
div.style = "color:red; font-weight:bold";
// This works:The tree function that I've written handles this nested style structure as well. Here's an example:
div.style.color = 'red';
div.style['font-weight'] = 'bold';
['div', {
'id': 'foo',
'style': {'color': 'red', 'font-weight': 'bold'}},
'This works too!']Now that you have an idea of how to use this utility, here's the code. Minus the comments it's only about twenty-one lines./**What do you think, is there anything you would add?
* Creates a DOM tree from a simple list.
* The structure of the tree passed in is as follows:
* ['elementTag',
* {attribute1: value,
* attribute2: value,
* style: {property1: value,
* property2: value}},
* 'child text node',
* ['elementTag',
* {property: value},
* 'grandchild text node'],
* 'third node']
* The above will result in a DOM node which has three child nodes, the
* first and third will be text nodes because the values were strings.
* The second child node will be a DOM node as well.
*
* @param {Array} t The tree's structure as a collection of strings, lists,
* and simple objects. The structure is as follows
* ['elementTag', {attributes}, child, child, child, ...]
* @return {Element} Returns a new DOM element.
*/
function tree(t) {
// Create the node using the tag which is first in the list.
var domNode = document.createElement(t[0]);
// Add all HTML attributes to the node.
for (var key in t[1]) {
// The style attributes get special treatment.
if (key == 'style') {
for (var styleAttribute in t[1].style) {
domNode.style[styleAttribute] = t[1].style[styleAttribute];
}
} else {
domNode[key] = t[1][key];
}
}
// Iterate over all child nodes, converting them to either text or HTML
// nodes.
for (var index = 2, child; child = t[index]; index++) {
if (typeof(child) == 'string') {
domNode.appendChild(document.createTextNode(child));
} else {
// Buid recursively.
domNode.appendChild(tree(child));
}
}
return domNode;
}
On a realted note, if you're interested in a more powerful templating system, you might want to try Closure Templates which were recently open sourced.
Thursday, October 22, 2009
The joys of onKeyDown
I recently found myself in need of a way to detect when a user presses enter when typing in a text input box and happened upon one of the quirkiest of browser features, key press detection in JavaScript. Searching the Internet provided a few ideas but nothing that quite fit what I was looking for, so I thought maybe I should get the word out about what I've learned.
Lets assume that we have a form with an input box and we want to perform some special action when the user presses the enter key while focus is on the text input box. We begin by adding an onKeyDown event to the input box (you might also consider onKeyUp, but onKeyPress seems like it might be somewhat quirkier).
There are a few ways to prevent the key presses from also triggering the default behavior and do only our behavior. One of the simplest ways is to return false from the
Lets assume that we have a form with an input box and we want to perform some special action when the user presses the enter key while focus is on the text input box. We begin by adding an onKeyDown event to the input box (you might also consider onKeyUp, but onKeyPress seems like it might be somewhat quirkier).
<form>Now the first hurdle is that in IE, Safari, and Chrome you can access the ASCII character code for the key which was pressed in
<input type="text" id="my-input">
</form>
<div id="output"></div>
<script>
document.getElementById('my-input').onkeydown = function(e) {};
<script>
window.event.keyCode but in FireFox you'll need to get the event object and look at the which member.<script>Now there is one gotcha with what we've written so far. Each key that we press when focus is on the desired input causes our code to be run, but the browser also performs the default behavior for that key. If our input is a simple text box, the characters pressed will show up in the text box. If the input is part of a form with a submit button, pressing enter will cause the form to be submitted. If the form is submitted then the browser is sent to a different page which in this case is not what we want.
document.getElementById('my-input').onkeydown = function(e) {
var keyCode = 0;
if (window && window.event && window.event.keyCode) {
keyCode = window.event.keyCode;
} else if (e && e.which) {
keyCode = e.which;
} else {
alert('fail');
}
document.getElementById('output').innerHTML = 'You pressed ' + keyCode;
};
<script>
There are a few ways to prevent the key presses from also triggering the default behavior and do only our behavior. One of the simplest ways is to return false from the
onKeyDown function. If we change our handler to the below, characters will not show up in a text input box because our handler consumes them. document.getElementById('my-input').onkeydown = function(e) {
var keyCode = 0;
if (window && window.event && window.event.keyCode) {
keyCode = window.event.keyCode;
} else if (e && e.which) {
keyCode = e.which;
} else {
alert('fail');
}
document.getElementById('output').innerHTML = 'You pressed ' + keyCode;
return false;
};With the above, the last key press is displayed in the output, but in most cases we probably do want the user to see the chracters they've typed showing up in the input box. We just want to prevent the form submit when the user presses the enter key. To accomplish this behavior, we can return false when we don't want the key press to propoage and return true when the default behavior should also be performed. document.getElementById('my-input').onkeydown = function(e) {
var keyCode = 0;
if (window && window.event && window.event.keyCode) {
keyCode = window.event.keyCode;
} else if (e && e.which) {
keyCode = e.which;
} else {
alert('fail');
}
document.getElementById('output').innerHTML = 'You pressed ' + keyCode;
if (keyCode == 13) { // 13 is the key code for the enter key.
return false;
} else {
return true;
}
};There you have it, a way to detect when the enter key is pressed in our input box while also preventing the form from being submitted.
Monday, September 28, 2009
Journaling
This evening I found my long lost journal. In dusting it off and cracking it open I learned that my last entry had been over a year ago. With the exception of this last year long hiatus, I've regularly kept a journal since sometime in 1999 or 2000. I've found writing my thoughts helps me crystallize them and I tend to deal with thoughts and emotions internally, mulling them for hours or days. This is one of the reasons I think I've stuck with blogging.
Keeping a private journal is a completely different feeling than keeping a blog. When I write here I'm intensely (sometimes even paralyzingly) conscious of my audience. Not that it's a large one. Here I tend to focus on software related discoveries and creations. It is one creative outlet, but one decidedly different from when I journal.
It was refreshing to scratch blank pages with pen, writing for an audience which understands me better than most.
Okay now how many of you, when you saw the title, thought that I was going to talk about a file system or database? :-) How about you, do you keep a private journal?
Keeping a private journal is a completely different feeling than keeping a blog. When I write here I'm intensely (sometimes even paralyzingly) conscious of my audience. Not that it's a large one. Here I tend to focus on software related discoveries and creations. It is one creative outlet, but one decidedly different from when I journal.
It was refreshing to scratch blank pages with pen, writing for an audience which understands me better than most.
Okay now how many of you, when you saw the title, thought that I was going to talk about a file system or database? :-) How about you, do you keep a private journal?
Subscribe to:
Posts (Atom)