CJBlomqvist.com - Blog http://www.cjblomqvist.com/blog/ This web log, also known as blog, is a journal about all forms of development, especially on the web. Components performance http://www.cjblomqvist.com/blog/components-performance/26

Components sucks ass performance wise

straight in there works really good

sub-view works good too

 

Thus, use only components whenever you are not rendering a lot of them, like maybe for a datepicker and such?

26th of March, 2021 http://www.cjblomqvist.com/blog/components-performance/26
Common traps http://www.cjblomqvist.com/blog/common-traps/27

Always have a container for {#each}s

Always have one, and only one, node/element in {#each}

Whitespace = nodes/elements => no good in {#each} (unless my fix is applied)

26th of March, 2017 http://www.cjblomqvist.com/blog/common-traps/27
Project Management: The Idea/Feedback Bucket http://www.cjblomqvist.com/blog/project-management-the-ideafeedback-bucket/30

Things have progressed a lot in the last year and it's been an incredibly busy year. As the projects/companies I'm involved with have moved closer together as well as grown in total size, a larger need for a better way to distribute knowledge has arisen. As an effect, I plan on posting the learnings we make internally here on my blog in order to document as well as easily distribute/transfer knowledge internally.

The negligence of ideas and feedback

With all projects I'm involved with, regardless if consultant work or product projects, there is always a steady stream of ideas, feedback and comments on how to make things different and (hopefully) better. I believe it to be rather similar within many other organizations. In these organizations, at best, there might be the physical suggestion box, or perhaps in one or two forward-thinking big corp's there might be the internal (web) platform for innovation suggestions which seems to be very popular today. A suggestion box might work for gather ideas continuously without becoming a big hassle to use in the common working day, but it is very unstructured and is in experience very seldomly actively taken care of. The internal web platform for innovaiton suggestions is typically quite structured, but is often aimed at larger grander innovation suggestions. Further, it is often not as easy as to just put in a simple suggestion or feedback note - rather you typically have to enter more information around it, at least for the suggestion to be useful and properly reviewed/taken care of.

Simplifying and incorporating a culture of continuous ideas, feedback and comments tracking

Instead of adding another tool to the massive amount of tools every person have within any significant organization we have decided to go down another route. Internally in all the companies I'm currently involved with we use Asana to keep track and manage our projects. We use Asana a lot due to it's flexibility and simple way of fitting different types of projects with different needs, and we use it for basically everything regarding project management. Note, project management is not, and should never be, something only the project manager uses and keeps track of! It should be used by everyone involved. Thus, instead of separating the stream of continuous ideas, feedback and comments tracking from our core tool we've incorporated it. Whenever any person has an idea, feedback or comment that person simply adds it underneath a special 'Idea/feedback bucket'. This way it automatically gets tracked in a structured way (along the specific project). We can add tags if needed or split the idea bucket heading if turns to big - this is all extremely simply done with Asana and something that everyone I work with is extremely comfortable with doing.

Simple note on how to do it

When adding an idea, feedback or comment, it is important to take time to write a clear and concise title and text. The size is not the important part here - that depends rather on the idea/comment itself. However, it is important to be fully inclusive on what the idea/comment entails. It is very easy to just write down a quick note but much better is to write a full explanation of the idea, what problem it solves, alternatives, etcetera. It is so easy when an idea pops up that you assume that everyone will understand what you are writing. If you do it will become useless as most likely nobody will ever take the time to dig into your vague description and try to understand the problem - then I'd argue it's a waste of time to put it down at all and should not be done.

To summerize
  • Continuous improvement is as important as innovation. Ideas, feedback and comments are critical to any organization that wants to achieve a steady level of high quality.
  • It should be easy to add ideas and comments to a project. By incorporating it to Asana, we use a tool which everybody is working with continuously everyday and very comfortable using.
  • By adding it to a separate heading in Asana to the project we are currently working on, we get structure without any significant added bureaucracy or work.
  • When adding an idea, be sure to be clear and consice meanwhile still covering the idea or comment fully.
  • Review your ideas, feedback and comments regularly. At the least, they should be reviewed every sprint or at a similar interval (if needed, this will be a separate post with more details).

Comments and feedback are of course very welcome!

28th of July, 2014 http://www.cjblomqvist.com/blog/project-management-the-ideafeedback-bucket/30
Derby: Enhancements and bugfixes to Racer http://www.cjblomqvist.com/blog/derby-enhancements-and-bugfixes-to-racer/29

Lately, me/B&B Web has put some serious effort into fixing issues and making enhancements to Racer, and in particular filters. Basically we use a fork of Racer in all our projects which we always keep updated with the latest in the original repo from codeparty, but with our additional fixes on top. You can find the repo and our patch branch at: https://github.com/BBWeb/racer/tree/updated.

What is fixed in our branch?

Bugfixes
There are a lot of issues with filters as it stands at the moment in the codeparty-version of Racer. Among them:

  1. Arrays are completely useless as sources to filters. They should work much better in our branch but I still recommend using collections with proper ids instead of arrays due to refLists (which filters relies on a lot) doesn't seem to handle arrays reliably. We've tried to get refLists to work much better with arrays, but after fixing some stuff we basically thought - hey, why not convert our data to collections instead and save us a ton of headache.
  2. We've added a new feature to refLists which is something we call "autoPatchIds". Basically, this patches the list of ids refLists uses when items in the underlying data is added/removed, BEFORE any events are emitted. This is very important when using filters (which breaks otherwise) because Derby uses the events that are emitted from Racer to update things, and when Derby gets the events (and auto-patching isn't enabled), Derby will grab data from the filters after it has already updated itself. The data in Racer will not be in sync with the state Derby assumes things are, and a lot of issues arises. Basically, this fixes a lot of issues.
  3. Another issue that arises in filters is due to faulty assumptions about when things happen och changes and removals. Basically, if one item in a collection is removed, this will trigger a change of value to void 0 (undefined). If anything happens on this removal, such as if there's a blur event in Derby that triggers an update of a value, this will happen after the filter/sort has shuffled things around already. Since Derby triggers this on a ref, and uses an old reference path, which will not most likely point to a different item than intended. Thus, Derby will trigger an update of the wrong item.

Enhancements:

  1. One can now send in a context object into a filter/sort. Basically this object can be used to do comparisons. E.g.
    model.filter('collection', function (item, i, items, ctx) { 
      item.attribute === ctx.attribute; 
    }, {attribute: 'something I want to filter on'});
    In the above scenario, we will get all the items where there's an attribute called 'attribute' that is equal to 'something I want to filter on' (the string passed into the filter function). Why have this? A workaround for using context-objects are to store the data on the model and then get it from there. However, there are downsides to this. In particular, no refiltering will happen automatically if the data in the model is changed. Further, this is a bad design pattern - the filter should be independent from the model/data. If you want to update the context object you've sent in, there is now also a .context(myNewUpdatedContextObject) method that can be triggered on any filter (or sorts - these are the same object in Racer). This will also ensure everything stays updated according to what the filtering should result in - i.e. it ensures the reactiveness is kept proper.
  2. There are two more new methods that can be called on any filter/sort: skip and limit. Skip works like this:
    var myFilter = model.filter(...);
    console.log(myFilter.get()); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
    myFilter.skip(5); 
    console.log(myFilter.get()); // [6, 7, 8, 9, 10] - we've skipped the 5 first 
    
    Limit works like this:
    var myFilter = model.filter(...); 
    console.log(myFilter.get()); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
    myFilter.limit(5); 
    console.log(myFilter.get()); // [1, 2, 3 ,4, 5] - we've limited the result to the 5 first
    They can also be used together. Basically, they make pagination very much simpler. Furthermore, you can also always pass in a limit to a call to skip, and the reverse, in other words, the methods actually look like this: Skip:
    @param {number} skip - the number of items to skip 
    @param {number} limit - the number of items to limit the result to - optional 
    function skip(skip[, limit]) { ... } 
    Limit:
    @param {number} limit - the number of items to limit the result to 
    @param {number} skip - the number of items to skip - optional 
    function limit(limit[, skip]) { ... } 
    A pagination example:
    .skip((page - 1) * itemsPerPage, itemsPerPage); 
    The reason why you'd want to do both skip and limit in the same call is to reduce the amount of updates (refiltering/resorting) that are needed (from two to one).
  3. We've added a new method to model, called .ats([path]). In this method, the combined path of the current model/scoped model + the (optionally) path sent in must point to an array or a collection. This method will return an array consisting of all the items in this array/collection - but only references/scoped models (the same as you would get from doing model.at()). E.g.
    model.set('_page.collection, { 
        'a': { /* ... */ } 
      , 'b': { /* ... */ } 
    }); 
    model.ats('_page.collection') 
      === model.at('_page.collection').ats() 
      === model.at('_page').ats('collection') 
      === [model.at('_page.collection.a'), model.at('_page.collection.b')] // All true
  4. We've added the same functionality to filters - the ats method. This works different depending on the scenario. There are two scenarios, either it's an unref'd filter, or it's a ref'd filter. The unref'd filter will return what is expected, model.ats() but filtered and sorted based upon the filter/sort sent in. However, if ref'd, myFilter.ats() will return a list to all items at the ref-path. In general, .ats() can be useful when one wants to easily loop through a list of items but not get them first (albeit since Racer 0.5, there should be little to no performance penalty doing so, but it looks better)
  5. We've exposed a second argument in model.dereference (forArrayMutator). Basically, dereference doesn't work if it has to go through an array (such as any refList). This functionality already existing internally in Racer, but it was previously not possible to pass this into Racer easily.

Other:

  1. Tests have been converted to pure JS (previously in CoffeeScript)
  2. We've added test-cases to more or less all our new features and bugfixes
  3. Lots of comments regarding each thing fixed can be found in the commits and issues/pull requests opened (in codeparty's repo).
To summarize

The best would of course be if these fixes and enhancements can be accepted into the codeparty repo (a bunch of PRs exists for above). In the meantime however, especially if you want to work with filters (which is one awesome feature in Derby/Racer), I'd recommend using our branch. I hope this will relieve a lot of headache (and stupid workarounds) to people using filters.

How can you know that our fixes are any good and won't break stuff? Well, we can't make you any promises there. We've tried to be very careful when patching Racer, and we've tried to touch as few rows as possible while still fixing the root-cause of issues instead of just patching on top to fix special scenarios. Furthermore, we've tried to make sure we have good test coverage, made sure to not break any other tests on the way, and even further, we're running this branch in production with one project, and will with two more very soon, and they seem quite fine.

Any comments, feedback, issues, etcetera is very welcome!

PS. I can also recommend our tracks repo which basically has existing PRs from the codeparty repo pulled into the updated branch which fixes a few irritating issues like faulty behavior/side-effects of app.exit. 

24th of August, 2013 http://www.cjblomqvist.com/blog/derby-enhancements-and-bugfixes-to-racer/29
Derby: Issue with array-like bindings in the view and workaround http://www.cjblomqvist.com/blog/derby-issue-with-array-like-bindings-in-the-view-and-workaround/28

It's been a busy year and thus, I've not had time to post anything here unfortunately. That has not meant however that I have not been paying close attention to Derby - rather the other way around! At B&B Web we have started using Derby for various projects, and lately we've been struggling with one particular issue; bindings with [].

The issue

The issue is best highlighted with an example. Consider this view (e.g. views/app/index.html - can also be found as gist here):

<body:><ul>{#each _page.unplannedOrder as :row}<li style="{#if _page.selected[:row.id]}background: red;{/}">{:row.id}</li>{/}</ul><ul>{#each _page.unplannedOrder as :row}<li style="{#if multiplePartPath(_page.selected, :row.id)}background: red;{/}">{:row.id}</li>{/}</ul>

And this application code (e.g. lib/app/index.js - can also found as gist here):

var app = require('derby').createApp(module)
    ;

app.get('/*', function(page, model, params) {
  model.set('_page.unplannedOrder', [{"id":"1"}, {"id":"2"}, {"id":"3"}]);
  page.render('');
});

app.enter('/*', function (model) {
  model.remove('_page.unplannedOrder', 0);
  model.set('_page.selected.3', true); // Triggers red backround on wrong li on the top ul (li above - aka #2)
});


app.view.fn({
    /**
     * Alternative to the buggy binding-implementation of myPath[myKey]
     * E.g. where:
     *   myKey = 1
     *   myKey2 = 0
     * {multiplePartPath(myPath, myKey, "property", mySecondKey)}
     * will result in a dynamic version of:
     *   {myPath.1.property.1}
     * @param  {Object}   basePath    The base path already converted to an object (e.g. the path without quotes)
     * @param  {String/Key} leaf     A leaf as a string, either directly or indirectly through a variable (which thus will be converted to a string through Derby)
     * @return {Value}    The returning value
     */
    multiplePartPath: function (basePath) {
        var argumentsLength = arguments.length
            ;

        for(var i = 1; i < argumentsLength && typeof basePath !== 'undefined'; i++) {
          basePath = basePath[arguments[i]]
        }

        return basePath;
    }
});
What will happen when this render is that both lists (uls) of items (lis) should have item #3 (the last li in each list) get a red background. If you run this however, you will realize that only the second ul behave as expected. The issue lies on line #2 in the template - the if-binding on _page.selected[:row.id] will not work as expected but rather get some kind of index miscalculation (I assume - most likely the bindings' indices aren't updated) and update the wrong item (li).
The work around

A simple workaround is to not use these paths, but instead use a view helper to achieve the same effect as _page.selected[:row.id]. I created a quite generic view helper which can be used to avoid this issue. The example (line #3 in the template) as well as the comments highlights how it can be used to replace _page.selected[:row.id].

To summarize

I  hope this can help anyone who stumbles upon the same issue. I have created an issue on GitHub (here) to make sure the issue is known both to the derby team as well as people in general. I was not able to locate where the issue lie and thus not able to create a test (my testing skills are not that great either to be honest...). Anyhow, this should be enough as a "test" in order to fix it.

2nd of July, 2013 http://www.cjblomqvist.com/blog/derby-issue-with-array-like-bindings-in-the-view-and-workaround/28
Derby: Authentication part #1 http://www.cjblomqvist.com/blog/derby-authentication-part-1/23

Long time no post! A lot has happened since my last blog post about Derby - a completely new query system is in place and not long after, support for access control and thus authentication! Because currently Derby/Racer is too buggy but a lot of people have requested and longed for an authentication example, I decided to release a sneak peak of what is to come when it comes to authentication!

Current status of authentication in Derby

Authentication depends on three different parts of Derby: The new session system/middleware, access control and partly, the new query system. The new query system is up and running and seems to be working pretty okay. "Minor" bugs are there but are also expected, so nothing new under the moon there. Access control seems to work similarly well as the query system - some "minor" bugs but nothing not expected. Sessions however, is working quite sketchy at the moment. Access control was introduced in 0.3.12, but since access control is more or less pointless without sessions, sessions were also sneaked in. However, it worked pretty badly. I only managed to get it to work for regular HTTP calls (i.e. not with websockets). A lot of the fixes Nate and Brian have made since the release of 0.3.12 have been related to fixing sessions and I am glad to say it is now working with websockets as well.

So what is the problem? Minor bugs and sessions are working? With sessions, some work is still left with making the session object available to templates. It is currently available as a variable named 'session' (i.e. use it in a fashion like this: '{session}'). The problem is that it is impossible right now to access any properties of the session object - it seems that because the session object is stored as a normal JSON object straight into the special case {session}, any traveling down the hierarchy of the session object does not work like it does with any Racer-based variable. In other words, it is currently not possible to access or do anything like this: {session.userid}, even if {session} looks like this: { ..., userid: 123, ... }. 

There is at least one workaround. You can put the session object in a hidden element on your page and place it as a private path on your model object and then access the model object on that private path. This works as expected, however, when I have been working on my example app, I stumbled upon a bunch of other bugs with Derby, that made me decide I would rather wait for 0.3.13 than try to circumvent all of the bugs (which also lead me to do a very hacky implementation, which is not good as an example app anyway).

My example app

So, basically all parts of authentication works enough to start testing and playing around with it, despite Derby currently being in such a shape that it does not allow for a good implementation of it. I know there are many that have been waiting on authentication and cannot wait another minute until they would like to start playing around with it. So, in order to help you guys get started, I put up my initial work on an example app on GitHub. It is based upon the derby-example GitHub repository, specifically the directory example app. I put in on my GitHub account (cjblomqvist) under the branch authentication and you can find it here.

Note! It requires the very latest version of Derby and Racer in order to work properly, it is currently very few comments and there is currently very little functionality available. Basically you can login with root/root which will correctly log you in and give you access to the rest. If you try to go to :30004/people straight away (before logging in) you will end up with an error. If you do it after logging in, it will work. This currently works both with normal HTTP-requests (has worked since the release of 0.3.12) and with websockets (with the very latest version of Derby/Racer from GitHub). Be aware though that there are a bunch of issues with the rest of the app as well as all of the templates.

To summarize

So, I will not go into more details as I believe it will be a waste of my time right now. When more bugs are fixed and I finish the example app, I will write a better post about how to use and what to think about when using authentication (although my example app will be very trivial).

31st of July, 2012 http://www.cjblomqvist.com/blog/derby-authentication-part-1/23
Michael Nelson: 6 things I'm loving about Derby http://www.cjblomqvist.com/blog/michael-nelson-6-things-im-loving-about-derby/25

Any blog posts about Derby I stumble upon that I find to be of some kind of quality, I will post here. This time it's from Michael Nelson who made a blog post and a short screencast about what he likes about Derby.

You can find Michael Nelson's blog post about the 6 things he likes about Derby here: http://micknelson.wordpress.com/2012/07/27/6-things-im-loving-about-derbyjs/

31st of July, 2012 http://www.cjblomqvist.com/blog/michael-nelson-6-things-im-loving-about-derby/25
CJBlomqvist.com/blog - now with RSS! http://www.cjblomqvist.com/blog/cjblomqvistcomblog---now-with-rss/24
Making it easier to follow my blog - with RSS!

By request, I have now added RSS to my blog so feel free to add it as a feed in your favourite reader! You can simply add any address from my site (e.g. www.cjblomqvist.com or www.cjblomqvist.com/blog) to your reader and it will automatically find my feed. You can also reach it straight from this address: http://cjblomqvist.com/blog.rss

If you encounter any issues with the RSS feed or have any feedback or questions, let me know!

31st of July, 2012 http://www.cjblomqvist.com/blog/cjblomqvistcomblog---now-with-rss/24
Makefile for optimizing css, js and index files http://www.cjblomqvist.com/blog/makefile-for-optimizing-css-js-and-index-files/22

In almost all projects, especially ones without any major framework supporting the backend or simple pure html projects, it's always a hassle with deployment, testing and updating. In order to simplify this process, and to make sure no best practice step in the deployment process is missed, I decided to make a Makefile I can use across all these projects.

Deployment what?

When deploying your web site, it's best practice to concatenate CSS aswell as JS to avoid too many HTTP requests. It's also best practice to minify CSS, JS as well as HTML. Then there's the issue with caching. An optimal solution would be to update the filename everytime the file is updated (but of course never otherwise). Then, an eternal cache time can be set without any worries of non-updated files.  

These are just some steps of the optimizing process of your website project (read more about what you should do for optimizing your website in Google's guide). It's fairly easy to do once, however, almost definitely you will at some point update your website and then this process should be automated. If it's automated you will reduce the time you spend on doing the same steps over and over, you will be sure you did not miss any of the steps and you know it's less likely any errors or mistakes happened.

Makefile what?

Make is a program common on *nix systems. Wikipedia describes it like this:

"In software development, Make is a utility that automatically builds executable programs and libraries from source code by reading files called makefiles which specify how to derive the target program."

Because I very often stumble into the issue and hassle of concatenation, minification, etcetera that one has to do when deploying, I decided to write a Makefile that does all of this for me. After I completed it I put it up on my GitHub-account under my new deploy-scripts repo (where you also will find a nifty little script for uploading a folder to an FTP) so that anyone can utilize it. You will find details of the usage at the repo page / readme, as well as comments in the actual file which you should modify according to your usage.

And some sugar on top of course...

To make the deployment process even smoother, easier and under your full control, I recommend using a deployment tool like TeamCity. You could easily pull down your data from your git repo, add the make step as well as automatic uploading (for example with my FTP-uploading shell script, also in the repo),  and you will have a completely automatic process for deploying your website. You will have full control, be able to do it from the web from any computer and even let less savvy, non-developers do it (yes, you can make it that simple for them). 

As always, I'll happily help out with any issues you may have, so feel free to contact me or write a comment below and I'll try my best!

10th of July, 2012 http://www.cjblomqvist.com/blog/makefile-for-optimizing-css-js-and-index-files/22
DerbyJS: refList-wrapper update http://www.cjblomqvist.com/blog/derbyjs-reflist-wrapper-update/20

A while back ago I created a wrapper for Derby's model.refList method. I felt this was needed because the existing native implementation of refList is cumbersome to use and require a lot of boilerplate code, while usually where ever I used refList I needed the same boilerplate code. Today it's time for an update.

Find the updated version at my GitHub repository here. Note that at it's current state, my refList-wrapper utilizes underscore, which you can find here.

RefList-wrapper what?

One very useful method/function of Derby is refList, which basically turns a model object collection into an array before passing it to the view. This is extremely useful because it is not possible to loop through an collection in a view, while it is possible to loop through an array using {#each}. The smart thing about refList is that it only references the values, so when updating the original model, the array created by refList will automatically be updated and you get all the pleasent DerbyJS magic (synchronization) we all love so much.

So why do we need a wrapper for the Derby-native refList? The docs of refList specifies the following about refList:

fn = model.refList ( path, to, key )

path: The location at which to create a reference list. This must be a private path, since references must be declared per mode

to: The location of an object that has properties to be mapped onto an array. Each property must be an object with a unique id property of the same value. May be a path or scoped model

key: A path whose value is an array of ids that map the to object's properties to a given order. May be a path or scoped model

fn: Returns the function that is stored in the model to represent the reference. This function should not be used directly.

So, basically if we subscribe to or fetch any data from our store and want to create an array of all of the results, but the data is stored as a collection rather than array. We will have to do something like this:

...

// Our data is stored like:
// users: {
//   "1": { -- The id of our user
//     name: "Carl",
//     password: "mysecretpassword"
//   },
//   "2": { -- The id of our user
//     name: "Homer",
//     password: "password"
//   }
// }

... 

// Fetch all users by path 
model.fetch('users', function( err, scoped_users ) { 
    
    var 
      temp_array = []; 
    
    for( key, scoped_users.get() ) {
      
      // Loop through each user and save every id to a temp_array 
      temp_array
        .push( key );
      
    }
    
    model.set(
        '_users_id_list', // A temporary name which becomes 'key' in our refList         temp_array
      );
    
    model.refList(
        '_users', // Must be private path - ie. start with _. This is the object we can use later in our view as an array
        'users',
        '_users_id_list'
      );
    
  }); 

// Then we can do the following in our view. The same result would have been impossible to achieve without introducing a view helper or using refList

...

< h3>List of users
< ul>
  {#each _users}
    < li>{.name}
  {/}
< /ul>

...

While this is useful, because I tend to want to render lists quite a lot with all the objects I subscribe to/fetches, I figured it would be awesome if I could just do something like this:

...

// Our data looks like above

... 

// Fetch all users by path 
model.fetch('users', function( err, scoped_users ) { 
    
    model.refList('users');
    
  }); 

// Then we have the same view as above

...

If I only send in one parameter consisting of the path to the original model data, I simply want refList to create the referenced list as a private version of my parameter path, ie. "_" + parameter. I do not really care much for the array of the ids, so it can be hidden away. This is basically what the refList-wrapper does and I will then end up with above example working. Of course, I still want to be able to access the original refList, so if I send in all three arguments, it will work as the Derby-native refList. Also, If I specify two parameters, I simply want refList to use my first parameter and second parameters as expected, although just hide away the array of ids. In other words, I would prefer if refList worked as follows:

 

fn = model.refList ( [path, ] to [, key] )

path: The location at which to create a reference list. This must be a private path, since references must be declared per mode. Optional. Defaults to the "_" + to parameter.

to: The location of an object that has properties to be mapped onto an array. Each property must be an object with a unique id property of the same value. May be a path or scoped model

key: A path whose value is an array of ids that map the to object's properties to a given order. May be a path or scoped model. Optional. If not specified, a path will be generated consisting of all keys of the object at path to.

fn: Returns the function that is stored in the model to represent the reference. This function should not be used directly.

 

What has changed in my update?

In my original version of refList, it could in certain cases create a circular reference to my wrapper, which whenever called create an eternal loop (not good). This has now been fixed. Bascially what happened was, whenever you would call your routes client-side, refList would add an additional call to itself. Whenever refList was subsequentially called, it would break your page because it would cause an infinite loop (and eventually cause an Uncaught Error: Maximum stack overflow or something similar). 

I hope you will find my refList-wrapper useful and if it causes you any trouble, let me know and I will see what I can do to help. Please also do not forget that my refList-wrapper at moment is dependent upon underscore which you can find here.

27th of June, 2012 http://www.cjblomqvist.com/blog/derbyjs-reflist-wrapper-update/20
DerbyJS: Introducing the <strike>onrender method</strike> render event and its possibilities (Updated!) http://www.cjblomqvist.com/blog/derbyjs-introducing-the-strikeonrender-methodstrike-render-event-and-its-possibilities-updated/18

Although not yet accepted into the master branch of Derby on GitHub, I am confident the onrender method will make it in. I have (very) briefly discussed the issue with Nate (one of two creators) and tried various solutions, gone through their positive and negative sides and I cannot for my life see how a different implementation could be advantageous over the onrender method, without trying to be too much.

Pre-requisites: Basic understanding of Derby and jQuery.

Update: As of 22nd of June, Nate implemented and made a commit to fire a render event upon rendering. It will end up (I assume) in the next version of Derby, meaning 0.3.11. If you can't wait, you can always grab Derby straight from the master branch which contains this fix. I have updated this post to reflect this.

What's the issue?

Using the current version of DerbyJS for development, there is a problem with controlling rendering. Whenever rendering is done, you have no possibility to do any action without having to worry about whether the page has actually been updated already or are still in the midst of it. Below you can find a simplified example of when this can become tedious - I am sure there are a thousand issues all stemming from the same problem.

app.ready(function (model) {
  
  // Bind something just for the sake of it
  $("#button").click(function() {
    
    // Push Derby to render a new page, which will make 
    // Derby go through appropriate routers, etcetera
    // This utilizes the same mechanisms as what is
    // happening whenever you click a link and Derby takes
    // over your click.
    view.history.push('/new-page/');
    
    // Won't work: What I want do after rendering
    $("#new-element-only-on-new-page") // This will return an empty jQuery object
      .css({width: $(window).width() + "px"});
    
  });
  
});
The onrender method render event

In order to cope with this problem, after doing some thorough investigation of the issue (you can find my monologue/rambling on the pertaining github issue), I decided to go ahead and implement an onrender method. I considered implementing an event that would fire upon rendering that the developer using Derby could catch as well as implement a full scale routing system based upon the existing routing system, but after completing. I did actually implement the full scale routing system into Derby, but once completed, I realized that it was overly complex, making it hard to develop further as well as to start develop with. I also realized it had its limitations, and that a much simpler, but yet as elegant, solution would suffice (the onrender method with some added sugar). The event firing solution... erhm... I did not like. Hard to control, a new pattern not seen earlier in Derby (Derby uses surprisingly few, if any, events like that) which would cause a lot of headache. However, later Nate introduced a render event which will be the preferred way to do it from here on forward.

How it works

So, the onrender method works almost exactly the same as similar to the ready method. It belongs to app (which you get after calling createApp) and takes in the same callback function with the same arguments. You are able to to bindings to app (should be done inside the ready method) and attach a callback, which gets The callback is executed right after the ready callback, but also upon any re-rendering. This is quite important to think about - any re-rendering means any time you call page.render from within a router's callback and that router's callback is being executed (due to a match). To sum it up, this callback will fire on any transitional routing back and forth, any normal routing made by clicks, by calling view.history.push, on initialization of your app (and hence, any other normal HTTP requests) and any other way you would be able to trigger the routes mechanisms of Derby. It could be used like this: (note there is an additional way of using the render event; together with namespaces, see Nate's comment on his commit)

app.onrender(function (model) {
  
  alert('This will pop up on any rendering!');
  
});

// Where the ctx parameter is the context object one can send in as a parameter to page.render.
app.on('render', function(ctx) {
  
  alert('This will pop up on any rendering!');
  
});
What to think about when implementing

First of all, my commit has not yet been pushed into the master branch - and much less into a new version. You can find the version of Derby with the onrender method included on my github pages here. Let's hope Nate includes it ASAP into the main branch and updates the version so we can grab it through npm. My version is based upon 0.3.9 including any fixes Nate's done (and actually it looks like he's been quite busy), since up until the 20th of June.

Second of all, the onrender callback should not really contain any rendering of contents. Why? Well, rendering of content belongs in the normal routes and the templates. This way, we will be able to produce the same (or similar) results whether we render first on the server and then send it to the browser/client, or whether we render it purely through browser/client-side processed routes. Note that this is possible, but very much not advisable.

Some sugar: Lightpage

Alright, so going through this process, I started thinking how cool it would be to actually have a proper routing system for browser/client-specific code. I know I have been thinking of a good way to handle what code to execute on what page before, and soon I discovered page.js, made by TJ Holowaychuk who also makes Express. Then it struck me, most of this is already implemented in Derby and what we really need is only the basics, a way to better structure our code based upon routes (in other words, call only certain parts of our code based upon paths matching the current location). Also, to use page.js as is, it would most likely break DerbyJS as they both try to take over any clicks and such. After all, Derby already has a way to do routing browser/client -side (really, that's a major part of the Derby's offering). But, Derby's existing system doesn't allow us to do browser/client -side coding in an efficient, non-hacky manner.

So, I stripped page.js and tuned it to better fit into the Derby style of development, and, voilà(!), lightpage! Basically what lightpages allow you to do is specify routes, which you can process (only) by "manually" invoking a process method. You can read more about how it works in detail on the github pages of lightpage (I also suggest taking a good look again at page.js which really is a nice piece of work).

How to use lightpage with Derby

As a coincidence, (erhm, or not...) it happens to work extremely well with the onrender method render event and Derby! All you have to do is to install it as any other package available in the npm, for example by specifying "lightpage": "*" as a dependency of your app in your package.json file and then do npm install in your app's directory. Then, to use it, you need to require it at the top and then you are ready to go! Note that any routes should be defined in the ready method callback to avoid A: server-side setup of the routes (which will most likely break your app completely) and B: the routes being setup more than once (which will make your callbacks fire more than once... not good). Also, I suggest putting the processing/triggering of the routes in the onrender method render event callback, as they will then be triggered/called on every render, which most likely is your intended behavior. This might sound complicated, but it really is quite easy (this is an example that would fit well with the bundled app that comes whenever you create a new Derby project):

require('lightpage');

... 

// Normal routes and what not

...

app.ready(function (model) {
  
  // Set up your routes, just like normal Express routes.
  // The difference lies in that you cannot specify get/post/...
  // since this is not always known to the browser/client
  // (for example a POST to the server).
  // Also, much like Derby, a params parameter instead of a 
  // context parameter is provided to the callback. Since 
  // app.ready already have the model variable, you could use
  // that one as you would in any other place in your app. 
  // No page parameter is provided since this is not really
  // a relevant place for such a parameter.
  page('/:roomName?', function ( params, next ) {
    
    alert('Just rendered a room with name: ' + params.roomName);
    
  });
  
  app.on('render', function(ctx) {
      
      // Trigger processing of lightpage routes on every render
      page.process(location.pathname)
      
    });
  
});

app.onrender(function (model) {  
    
    // Trigger processing of lightpage routes on every render
    page.process(location.pathname);
  
  });
End notes

These two additions to Derby should severely simplify and better structure any browser/client -specific code you may have/need. If you stumble upon any issues I try to be as much available as possible on the Derby IRC channel on freenode and I am constantly checking the Derby Google group. And of course, feel free to share and comment here and I will answer as soon as I can! I am always happy to help!

For anyone wondering about simpler tutorials how to use and get started with Derby, they will come! Stay tuned!

22nd of June, 2012 http://www.cjblomqvist.com/blog/derbyjs-introducing-the-strikeonrender-methodstrike-render-event-and-its-possibilities-updated/18
Re-launch of Blog! http://www.cjblomqvist.com/blog/re-launch-of-blog/15

Today I decided to re-launch my blog and make some critical updates to the underlying website to better make it work long term. I hope you enjoy it!

The blog

As I have lately been active in the DerbyJS community (a full stack framework for writing NodeJS web pages/applications) and there have been more and more requests to create tutorials and what not about Derby, I decided to re-launch my blog today. To start off, I will try to get the time to write some entries about Derby, so check back for that.  However, the blog will cover anything development related, as development always been a great passion of mine. I will mostly focus on web development, but once in a while you'll be able to find a post about business development, personel development, or whatever runs through my head.

Looking for someone to do work for you?

Then feel free to check out the rest of the site and get a feeling for who I am, what I can do, what I have done, etcetera. I am always open for interesting opportunities, especially in the areas of IT and/or management. You can find my contact information at the bottom of this website or by going to the Contact Me page. In case you are interested in getting help with web development, be sure to also check out B&B Web, my web development firm.

I hope you like the website and enjoy the tile-browsing experience!

19th of June, 2012 http://www.cjblomqvist.com/blog/re-launch-of-blog/15
Effective Usage of Mobile Orientation http://www.cjblomqvist.com/blog/effective-usage-of-mobile-orientation/11

During my development of my first mobile website (see previous post) I discussed the problems with the order of image loading in all (?) browsers today. When it comes to mobile development, another big thing to think about that differs from desktop web development is orientation. Initially, I didn't see much to it except that I had to make sure my site had to look the same regardless if in portrait or landscape orientation. But...

Using orientation to hide/show different content

To me, having developed websites for more than 15 years (crazy how time flies), my natural reaction to different external properties/settings of my users' browsers is to just make it look the same. The big difference from before is that people expected to use, and did not easily, change their setup of their browsers. The property that affects developers the most is probably different screen resolution. However, this is more or less a fixed setting of the user.

With orientation, the user can switch, easily, and it's not at all foreign to the user to rotate to experience something different. With limited space, especially width in the portrait format, the developer really has to think about what to include and not on a mobile version of a desktop website. During my development of a mobile version of an e-commerce site, I discovered that the limited width in the portrait format together with quite long product names made it impossible to include images in any listview.

Example: images on an e-commerce site

The article name is far more important to show than an image of the products, especially because it's going to be quite hard to see the image anyway. I do know though that the customers of the site find images very important too. My solution to the problem was to show images in the landscape format while hiding them in portrait, thus making full use of whatever space is available to me. 

Taking it further

In the above case it's important to have high accessibility of the site, and thus it's not a radical move to show images whenever in landscape mode. It simply provides a neat user experience but nothing more and it was done through CSS3 media queries (max-width/min-width). However, it would be interesting to see implementations where two completely different pages were shown based on orientation. E-mail inbox shown in portrait mode, compose new e-mail in landscape. Not the best idea maybe, but you see my point. I know several apps have implemented this kind of perspective on orientation, but I definitely believe more can be done in the area. Especially on mobile websites.

Orientation creates a new dimension for web developers to use and is definitely an aspect that I will think hard about in my current and next projects!

21st of September, 2011 http://www.cjblomqvist.com/blog/effective-usage-of-mobile-orientation/11
Image Loading in Today's Browsers http://www.cjblomqvist.com/blog/image-loading-in-todays-browsers/10

Update 2012-06-19: Unfortunately. some links from this older post is broken. I have decided to still keep the post though for any one interested.

I have recently gotten hired to develop a mobile version of the e-commerce site tingstad.se. I have chosen to use jQuery Mobile as my framework to ensure cross-browser compatibility and to be able to use PhoneGap to later convert the site into apps. As my first mobile (and jQuery Mobile) project I have been very excited to get it all done but I have also encountered some problems along the way. As loading time is critical in a mobile environment, I discovered a dilemma with how browsers work today.

What's the problem?

On any e-commerce site, images are always an important aspect, even on a strict B2B site. I believe however that loading time is more critical and a site definitely needs to be optimized for both. On tingstad.se, there are pages with more than 500 products, and hence images, which makes this tricky. A common way of presenting a lot of products on the same page is through hiding elements, i.e. you have 500 div-elements, but 480 has display: none as their style and then you apply JavaScript to provide pagination and filters (example).

Here comes the tricky part. Browsers today fetch the html, looks up all links (please correct me if I'm wrong) and then queues them based on in which order they occur in the html-document. Usually, 1-8 items (including CSS, JavaScript and other external files) are fetched simultaneously. A problem that occur when you combine this browser behavior with the above technique is that when the 20 products that doesn't have display: none; set (the 20 visible ones) aren't the 20 top div-elements in your page the browser will load all the other images first, which will cause significant time in between the user gets to see the 20 images s/he wants to see.

A test

In order to be sure about this I wanted verify this and test whether it was a mobile browser problem or a general problem. I came up the following script that should be pretty self-explaining: http://test.kaffesump.kodingen.com/image-test.php. Basically, it shows browser name/version/platform and the order in which the images were loaded. An optimal order would be 1-8. Please visit, it automatically saves your test and add it to the database.

Conclusion

No browsers today, neither desktop nor mobile, loads images in an optimal way based on CSS. I do understand that this might be largely due to the added time it would take to compute whether an image is shown or not, but I believe this could be a great feature if implemented properly in browsers. Another hot related topic is lazy loading (I did some quick googling on this issue when I tested it) but it's a completely different thing which will make the user wait for loading of images multiple times (whenever scrolling). A smart order of image loading could definitely help this problem, but pure lazy-loading, in my opinion, would not be a good thing to implement by default.

Workarounds

A workaround would be to not include the 480 products that are not displayed and add them later as needed, for example using jQuery Tmpl. A problem that occur is however that this will not be very SEO-friendly, as only the first 20 products will be visible to search engines. I can image a workaround around that would be to show all products and then remove the 480 that are not supposed to be visible through JavaScript. I'm a little bit uncertain though if that would help since the browser might have already gotten all the links/images before running any JavaScript. Something to investigate for another day. I can also imagine that this would hit the rendering performance of the browsers, especially mobile browsers that are known to have a very limited amount of memory available to them.

You can find the full code (except the DB structure) at: https://github.com/cjblomqvist/image-test

7th of September, 2011 http://www.cjblomqvist.com/blog/image-loading-in-todays-browsers/10