Live Bookmarking in ANTS Performance Profiler: a killer feature to help you zero in on performance problems fast

Last week I was sat with Simon, one of my client’s managers, as he showed me around their new customer support centre web app highlighting slow-loading pages. Simon, along with a couple of others, has been playing guinea pig using the new support centre in his day to day work.

The main rollout is in a few weeks but the performance problems have to be fixed first so support team members don’t spend a lot more time on calls, forcing customers to wait longer on hold before speaking to someone. Potentially bad for costs, customer satisfaction, and team morale!

Simon gave me a list of about a dozen trouble spots and I remoted into their production box to profile them all. I had to collect the results and get off as quickly as possible to avoid too much disruption; I could analyse them later on my own laptop. This gave me plenty of time to hunt down problems and suggest fixes.

I used Red Gate’s ANTS Performance Profiler throughout. One of the many helpful features it includes is bookmarking. You can mark any arbitrary time period in your performance session, give it a meaningful name (absolutely invaluable!), and use that as a shortcut to come back to it later.

For example, here I’ve selected the “Smart search” bookmark I created whilst profiling the support centre:

Timeline with bookmarked region selected.

The call tree shows me the call stacks that executed during the bookmarked time period. Towards the bottom you can see that SQL queries are using the vast majority of time in this particular stack trace:

Call tree showing call stacks within bookmarked region on timeline.

(Identifying SQL as a problem I took these queries and analysed them in more detail using both their execution plans, and SQL Server’s own SQL Profiler. I then suggested more efficient queries that could be used by NHibernate via repository methods.)

Also note we’re looking at Wall-clock time as opposed to CPU time. I won’t talk about the differences in detail here. What you need to understand is that Wall-clock time represents actual elapsed time. This matters because the queries execute in SQL Server, outside the IIS worker process running the site. Under CPU time measurements, which only include time spent in-process, they therefore wouldn’t appear as significant contributors to overall execution time.

Back on point: bookmarking is great as far as it goes, but you have to click and drag on the timeline after the fact to create them yourself. In the midst of an involved profiling session this is a hassle and can be error prone: what if by mistake you don’t drag out the full region you need to analyse? All too easily done, and as a result you can miss something important in your subsequent analysis.

Step in Live Bookmarks.

Basically, whilst profiling, you hit a button to start the bookmark, do whatever you need to do in your app, then hit a button to save the bookmark. Then you repeat this process as many times as you need. No worries about missing anything.

Here’s how it goes in detail:

  1. Start up a profiling session in ANTS Performance Profiler.
  1. Whilst profiling, click Start Bookmark. (To the right of the timeline.)

Start a live bookmark.

  1. Perform some action in your app – in my case I was clicking links to navigate problem pages, populate data, etc.
  1. Click Stop Bookmark.

Stop (and save) a live bookmark.

  1. The bookmark is added to the list on the right hand side of the timeline. It’s generally a good idea to give your bookmark a meaningful name. To do this just click the pencil icon next on the bookmark and type in the new name.

Rename bookmark.

  1. Rinse and repeat as many times as you need.
  1. When you’ve finished, click Stop in the top-left corner of the timeline to stop profiling.

Stop profiling.

It’s a good idea to save your results for later using File > Save Profiler Results, just in case the worst happens, and of course you can analyse them offline whenever you have time.

And that’s it: nice and easy, and very helpful when it comes to in depth performance analysis across a broad range of functionality within your application.

Any questions/comments, please do post below, or feel free to get in touch with me directly.

Reminder: Demoing Node Tools for Visual Studio 1.0 Beta at NodeJS & JavaScript Cambridge TONIGHT!

Hey everyone, just wanted to put out a quick reminder that I’ll be demoing the latest Node Tools for Visual Studio 1.0 Beta at the NodeJS & JavaScript Cambridge meetup tonight.

It all kicks off at The Fountain on Regent Street from 7.45pm with beer.

I do love events that start off with beer, particularly ones where I’m speaking because it takes the edge off a little. Sign up at:

http://www.meetup.com/NodeJS-Cambridge/events/164845272/

Also speaking is my friend, and former colleague, Forbes Lindsey. He is an active Jade contributor and will be giving a talk entitled The Jade template language, which I would highly recommend.

It should be a fun and interesting evening, with plenty of time for questions and discussion, so do come along if you can. I’ll certainly be happy to receive any feedback or suggestions you have for Node Tools for Visual Studio, and will pass it along to the team.

Look forward to seeing some of you there!

Node Tools for Visual Studio 1.0 Beta has landed

Those of you lucky enough to be at BUILD last week will no doubt be aware that Node Tools for Visual Studio 1.0 Beta has just been released.

Here are some of the headline improvements:

It’s also worth calling out the extensive Azure support in the suite, offering the ability to create, deploy, and debug Node apps on Azure (including on Linux) – exciting stuff!

Rather than have me talk too much about it, take a look at the videos the team have put together and see it in action for yourselves:

  • Installation walkthrough from Pavel. There’s something very exciting in this video: you may not be aware, but Visual Studio 2013 is available for FREE for both startups, via BizSpark, and students, via DreamSpark.

See the full announcement on Soma Somasegar’s blog.

As ever, please have a play. We’d love to hear your feedback so please get involved in the discussion. Also, do please let us know about any bugs you find.

Video blog: Getting started with relational databases using IntelliJ IDEA 13

Recently I’ve been reacquainting myself with technologies I haven’t had to use in anger for a while. One of these is Java. This has been great because I’ve been able to get back into using my favourite Java IDE: IntelliJ IDEA from JetBrains.

I’ve also started playing around with video blogging, which I’ve been meaning to do for a while. Nowadays tools like the excellent (and free!) Expression Encoder from Microsoft (sadly no longer under active development) make very easy.

Here are the firstfruits of my labours – a quick video on getting started with relational databases using the Database Tools in IntelliJ IDEA 13 Ultimate Edition.

In this video I show you how to use IDEA to work with SQL Server as a data source. On the face of it this might seem like an odd thing to do. That is unless you’re used to working in environments with fairly diverse infrastructure, in which case it’ll seem like an everyday and fairly pedestrian occurrence.

Topics covered:

  • Creating and configuring your SQL Server data source,
  • Installing the appropriate JDBC driver – a process which IDEA automates to make it as easy as possible,
  • The database pane, which is similar to SQL Server Management Studio’s (SSMS) Object Explorer View,
  • The query editor, which provides intellisense/auto-complete, and knows the different SQL dialects of all the RDBMS’s for which IDEA provides explicit support,
  • The results pane; again very similar to SSMS’s.

What you end up with is an experience that offers much of the functionality you’d most commonly use within SSMS, but without having to step outside of the IDE.

If you develop on Windows and you’re used to SSMS you may not find yourself using this particularly often. If, however, you develop on another OS, you don’t have the SQL Server client tools installed, or you don’t want the hassle and overhead of stepping out of your IDE (SSMS is based on Visual Studio so can take a while to start), you should find the functionality in IDEA provides a convenient shortcut for working with SQL Server databases.

Enjoy!

How to stop feeling bad about charging your clients lots of money for consultancy

UPDATE: I’ve since done more reading about pricing and, whilst I think the approach outlined below is certainly a lot better than no approach at all (otherwise known as picking a figure out of the air), I don’t think it’s the best approach. I’ll write on this topic again when I’ve had more opportunities to try out different approaches. In the meantime you could do a lot worse than read Alan Weiss on value-based pricing.

“How much will this cost us?”

The question’s come up quite a bit recently and, every time it does, my heart leaps into my mouth and I want to go and hide under a rock. It seems so innocuous. It’s just business, after all, and I mean: I ought to know the answer, right?

But I feel terrible about charging people lots of money, even when they can blatantly afford it. And this despite the obvious fact that one of the multitude of reasons I left my job at Red Gate was that I wanted to earn more money.

(Nothing against Red Gate: it was just time. Those of you who’ve been through a similar thing will know exactly what I mean. By the way: if you’re a consultant you should be earning more. You are in an inherently riskier and more precarious situation, and your income will be lumpier. If you’re not earning more then what’s the point? Why take the risk? You may as well go back to working for somebody else.)

Some of you will be mercenary as hell and won’t identify with this at all. You’re probably sat there thinking, “What is this guy on?” and, honestly, you can safely move on. I don’t think you’re going to have any problems at all, and I wish I was more like you.

Unfortunately I’m not, and this lead to the inevitable situation where the first job that came my way, via a friend working for a local company, I underquoted for. He asked me how much and I agonised. I looked at contractor rates for the local area, and added about half again on, then submitted a quote including a justification of why the fee was so “high” and heard nothing for a couple of days. Then he sent back an email saying, “yes, that’s absolutely fine,” with no hint of a quibble, and I thought: “Oh balls, I should have quoted more.”*

Well, yes, I should have done, but that’s not exactly very scientific, is it?

To the list of unscientific methods of setting your consultancy rates I’d also add asking your friends what sounds reasonable when you’re next down the pub with them even if – especially if – they work in the same domain. They’ll probably underquote because (a) most of them aren’t consultants, (b) they’re already appalled (and secretly jealous) of how much they perceive consultants to earn, (c) they might confuse consultancy with contracting, and (d) they probably haven’t sat down and worked through the calculations I’m about to lay out for you below.

Also, despite all my artsy tendencies, I’m a programmer with a science education and there are a lot of questions where I just feel a lot more comfortable and confident when I know the “right” answer and, more importantly, can follow the route that led to that answer. This is true even where the answer has some element of error/uncertainty associated with it.

So what is the “right” answer to the question of how much you should charge?

OK, so I’m not going to give you a figure. Nobody will because the answer depends very much on your situation. What I can do is map out the route by which you can arrive at that answer, and feel comfortable that the answer is reasonable. As with many seemingly intractable questions, it involves breaking the problem down into more manageable chunks.

The first thing you need to do is answer a few simple questions:

  1. On average, how many billable hours will I work each week? This will be less – most likely significantly less – than the total number of hours you work.
  2. How much do I want to earn? For the sake of argument we’ll call this your salary, although the exact mechanics of how the money finds its way into your pocket are best discussed with an accountant.
  3. What are my costs? Strictly, costs include your salary (2), but here I’m really talking about all the other things that you need to spend money on. The combination of (2) (before tax) and (3), taking into account (1), will allow you to calculate your consulting fees.

Let’s deal with each of these questions in turn…

1. On average, how many billable hours will I work each week?

As I said, this will most likely be a lot less than the total number of hours you’ll work.

Why?

Because you need to spend time on business development (marketing, wooing clients, actively searching for work, developing other revenue streams) and admin (finance, etc.).

For example, I reckon I’ll average around 24 billable hours/week, giving me 16 hours (2 days) to work on everything else. In reality I’ve accepted that the “everything else” bit will take more than 16 hours, meaning I’ll work more than the 40-hour work week that’s become standard in the UK, in order to pursue other business opportunities whilst still meeting my financial goals.

2. How much do I want to earn?

As I said, let’s call this your salary. You need to work out what you want this to be before tax.

Say you want to earn £100k/year, and take 5 weeks holiday. You’ll work 47 weeks and, since you only earn when you’re working, your salary for those weeks will be £2130.

If you’re trying to think about what a reasonable salary might be, here are some issues you should consider. Some of these are domestic expenses, whilst others are things that might be provided as employee benefits were you working for a larger company:

  • How much money do you need to survive for 6 months if, for some reason, you can’t work?
  • How much is your mortgage/rent?
  • How much do you need to pay for childcare?
  • How much is income protection insurance going to cost? Think about at least being able to cover your bills (NOT live the life of riley, unless you can afford to pay a lot),
  • How much time do you want to take as holiday each year? Remember: when you’re on holiday, you’re not earning, so treat it as a cost. (IMPORTANT NOTE: don’t forget to buy travel insurance, including medical cover!)
  • What about healthcare? The UK has the NHS and you can get free hospital care throughout the EU with a valid EHIC card but, in some instances, private healthcare can ensure you receive treatment more quickly for non-emergency conditions.

3. What are my costs?

Salary is obviously a cost, but as I said before, this is exclusive of salary.

So, here is a non-exhaustive list of business expenses you need to take into account when calculating your costs:

  • Travel
    • Car (or other vehicle)
      • Purchase or finance costs
      • Insurance – expect this to go up (social, domestic, leisure and commuting use won’t cover you if you spend a lot of time on the road visiting different clients)
      • Tax (known as Vehicle Excise Duty in the UK)
      • Annual roadworthiness test (known as MOT in the UK)
      • Servicing/repairs
      • Fuel
    • Rail (also metro/underground, and bus for large cities)
    • Air
  • Insurance
    • Professional indemnity
    • Travel (make sure it covers both business, personal, and medical expenses!)
    • Health (optional: depends on where you live)
  • Domain names and hosting
  • Equipment (including software licenses, and SaaS subscriptions)
  • Administrative services (accountancy, legal, company registration, etc.)
  • VAT (depends on how much you earn/anticipate you’ll earn)
  • Electricity
  • Heating
  • Water
  • Property/council tax
  • Food (especially if you’ve previously worked somewhere with a subsidised or free canteen)
  • Pension (you contribute to this from your salary but your employer would also normally make a contribution so I think it’s worth highlighting as a cost)

(It’s non-exhaustive because I keep thinking of things that need to be added to it.)

You need to work out how much these will cost you per annum. Do NOT underestimate them…

Business Expense Example 1

I have a pretty good bead on my car costs, as they stand right now, but I anticipate they’ll change significantly over the next 12-18 months. For starters, I may buy a newer car since my current car is getting a bit tired. I’m also not exactly sure how much of my mileage will be business mileage, or how many miles I’ll drive, so I’m assuming the “worst case” scenario: most miles will be for business, and I’ll have to drive longer distances (albeit perhaps less often) than I was simply commuting to and from my old job. Thus I’ve budgeted to be able to cover any increase in car costs.

Business Expense Example 2

Right now I’m paying next to nothing for hosting and domain names. My hosting (on Azure) is covered by the MSDN subscription Microsoft have kindly given me so I can continue working on NTVS, whilst my domain names currently cost well under £100/year. However, over the next 12 months I have plans that I anticipate could increase my hosting and domain costs to as much as £200/month which, in my cost breakdown, I’ve rounded up to a convenient £2500/year. They may go higher (in fact, I sort of hope they do, because that would indicate success… or possibly terribly inefficient code, but hopefully the former) and, if so, I’ll need to adjust. I anticipate a gradual ramp up though, so £2500 should be sufficient for the first year.

You might also be able to consider a portion of your mortgage or rent as a business expense if you work from home but BE CAREFUL. If you get this wrong you can run into hot water with the Inland Revenue, so make sure you know the rules for your jurisdiction.

Once you’ve worked out what your business expenses are per annum, divide by the number of weeks you’ll be working (NOT by 52) to work out what they’ll be for the average week. You’ll probably be surprised by how much they are. In fact, I’d go as far as to say that if they’re running at much less than £500/week you should be suspicious that you’ve miscalculated. Depending on your exact circumstances you may find they’re much higher – maybe closer to £1000. For the purposes of the calculation below I’m going to split the difference and say £750/week.

So, how much should I charge?

So, we want to pay ourselves £2130/week and our costs are £750 week, which means we need to earn £2880/week.

BUT we’re only billing for 24 hours, which means we need to charge out at £2880/24 = £120 per hour.

Or £960 per day.

And, of course, at that level over the course of a year (unless you’re particularly lazy) you’ll easily hit the VAT registration threshold, which means in that your fees are in fact £960 + VAT per day, which is basically £1200 per day.

Sounds like a lot, doesn’t it? But in consultancy terms it’s actually still pretty cheap. That in itself may be a problem – I don’t pretend to have figured that out yet. It also gives you some idea of why large consultancy firms are so eye-wateringly expensive: they have to pay for all that glitzy marketing, aggressive recruitment, graduate training, and those fancy offices somehow.

Because you’re worth it

I’m sure you can see how I’ve landed on those figures which, by the way, are a ballpark (and also chosen to make the sums easy for this example!). You might still have nagging doubts though. You might be wondering, am I really worth it?

This is tricky, and is really something you can only answer for yourself. What you need to think about is the value you’re offering to clients. Here’s a concrete example from my own experience.

Scenario

Potential client comes to me looking for help with some serious performance and scalability problems – even at minimal loads – with a website and set of associated services they’re planning to roll out in four weeks’ time. Technologies are .NET, ASP.NET MVC, and SQL Server. They want a specialist, with a background in .NET and SQL Server performance optimisation to come in and help them fix their performance problems.

My Background

I’m a software engineer with 14 years professional experience across a wide range of projects on various platforms. Of that, I spent nearly 10 years building tools to solve common problems encountered by .NET developers and SQL Server developers and DBAs. That includes the award winning ANTS Performance Profiler, which allow developers to quickly isolate performance problems in .NET code, and will highlight long-running/inefficient queries in SQL Server. I’ve done a lot of user testing, helping people find performance issues in their code, I’ve written about .NET performance, and I’ve spoken at .NET user groups on the topic.

What value do I bring?

The client has already spent a lot of time (and therefore money) trying to fix the problems they’re having, but with only limited success. They therefore want a specialist. With my background clearly I am something of a specialist. This is not a situation in which any .NET developer will do.

I can go in and help them fix their performance problems much more quickly than they might otherwise be able to. Although my day rate may seem high, they will actually spend less overall, and can be much more confident of a successful launch. This means they won’t lose money due to the site being unable to handle the load placed on it.

So, am I worth it?

In this case: yes. (But that doesn’t guarantee that they’ll be willing to pay – that’s a separate issue.)

You too are a professional (I assume). That being the case people should (and will) be willing to pay professional rates for your services. There will obviously be some element of negotiation for at least some jobs, and that’s OK: it’s just business. It’s part of your clients’ jobs to negotiate, and therefore part of yours.

Your fees might vary a bit anyway, depending on the client and the nature of the job. For example, for longer jobs with more billable hours per week you may negotiate a lower fee, because it’s guaranteed work for a longer period of time. I drew a distinction between consultancy and contracting earlier, and this is really what I’d describe as contracting. Consultancy I tend to think of as more being pulled in to advise on a specific issue or to help fix specific problems. It’s all obviously open to interpretation, and is something of a sliding scale.

Not everyone will be willing or able to pay your fees. For example, not many one- or two-man outfits would pay £800-1000 (or more) per day for consultancy, and that’s fine: those are not your customers. But many larger companies will.

What do I mean by larger?

Well, Red Gate regularly paid those kinds of fees (and more) for consultants and trainers from at least the time when I joined the company as employee number 17 back in 2004, and continues to do so. So, by larger, I really don’t mean that large.

I mentioned negotiation in passing a few paragraphs back. There’s an important point here: once you’ve gone through the process I’ve outlined above you’re in a much better position to negotiate. You know how much money you need to earn. You know where you can afford to compromise, and where you can’t.

You know, I hate negotiating, particularly when it comes to money, but it becomes a heck of a lot easier when you take the emotion out of the equation, and can back it up with facts and figures. You probably wouldn’t share those with your clients, because it’s none of their business, but knowing in your own mind what’s reasonable and what’s not will give you a lot more confidence.

Going back to people won’t be willing to pay for your services: that’s OK. They are not your customers. Think about the opportunity cost of cutting your fees to work for them: you may end up turning down a better paying job later on as a result, or you may gain a reputation for being cheap/easy to exploit that is hard to shake. If that happens people will undervalue you and your work, and you really don’t want that.

I’m going to stop now before this completely degenerates into a random stream of unconnected thoughts, but I hope it’s proven helpful for you. And if you have any comments or advice of your own please do come back at me – I’d certainly love to hear it.

Now go forth and charge lots of money**!

*Only half a days’ work so not a disaster.

**By which I mean a reasonable hourly/daily rate that allows you to cover all your costs and earn a decent living on top!

(Oh: one more tale of schoolboy error for your amusement. I recently sent out a quote to a potential client that I calculated using the above, but I still reckon he might think he’s getting a real bargain. Why? Because, like a muppet, I forgot to take VAT into account. Fortunately a short job again so not the end of the world.)

EDIT: Thanks to my friend Claire Taylor for pointing out that I’d forgotten to include a pension in my list of costs.

Detect mobile browsers in server-side code

Last week I found myself needing to detect mobile browsers on the server-side and ran across this extremely useful site:

http://detectmobilebrowsers.com/

It offers open source code for doing just that. Many languages are available: C#, Ruby, JavaScript & node.js, PHP, Python, and more. Even Perl!

Often you’d use this code to redirect the user to a mobile version of your site. However, my site uses the responsive Twenty Twelve WordPress theme. This works well on mobile browsers. Thus, I don’t really want or need to redirect the user.

Unfortunately, there’s one particular piece of content that was banjaxxing the page width on mobile devices. It needed to be replaced. Normally I’d do this on the client-side, which is what the theme does. In this cases the content’s Ts & Cs meant I wasn’t allowed to. But I could do it on the server.

You probably know that you can’t get the client’s screen resolution or browser window dimensions on the server. However, you can use the user-agent string to detect mobile browsers. This is exactly what the code at detectmobilebrowsers.com does. They’ve written and tested code that will reliably detect mobile browsers across most devices. That isn’t something I wanted to attempt myself (how would I test it?), and neither should you.

WordPress runs on PHP so I now have this particularly minging, but highly functional, lump of code in one of my template scripts:

<?php
$useragent=$_SERVER['HTTP_USER_AGENT'];
if(preg_match('/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i',$useragent)||preg_match('/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i',substr($useragent,0,4))) : ?>

    <div style="padding-bottom: 16px; margin-left: -24px; margin-top: -24px;">
        <!-- Content displayed on mobile (but not tablet) browsers here -->
    </div>

<?php else : ?>

    <span style="float: right; clear: right; padding-bottom: 8px;">
        <!-- Content displayed on all other browsers here -->
    </span>

<?php endif; ?>

DO NOT copy this code. New devices are being released all the time so make sure you grab the latest version from detectmobilebrowsers.com. That way your code will work with the most recent generation of devices.

To edit your WordPress templates just open up your dashboard and click Appearance > Editor:

Edit WordPress templates.

(Oh, and if I ever need that check in more than one place I’ll refactor it into a method. For now I can live with it sitting in the one template where I need it.)

As my comment in the code suggests, this won’t work for tablets. If you need special support for them, add the code snippet under the Tablets section here to the first regex. You can also separate the checks for mobiles and tablets, or even different models of mobile/tablet, if you need more fine-grained control over site behaviour.

How to take a screenshot of your iPhone or iPad in iOS 7

Taking a screenshot/screengrab of your phone in iOS 7 is really easy, and it works in all apps. Just follow these simple steps.

  1. Press and hold the Power/Sleep button (see image below).
  2. Click the Home button (see image below).
  3. Release the Power/Sleep button.

Location of iPhone 5S Power/Sleep and Home buttons.

(Note: it also works the other way around: press and hold Home and then click Power/Sleep. Use whichever you prefer.)

If it works the screen should flash briefly to indicate that a screenshot has been taken. If your iPhone isn’t on silent you’ll also hear the camera shutter sound. Make sure you don’t hold Power/Sleep for too long or you’ll switch your iDevice off!

Your screenshot will be saved to the camera role so open up the Photos app to take a look at it. You can see here that I’ve taken several screen grabs today:

Screenshots in Photos app.

Been getting screenshot snap-happy today.

Tap on the screengrab you’ve just taken to view it full size.

Viewing individual screenshot in Photos app.

Looking at an individual screenshot: note the sharing button in the bottom-left corner.

You can get to sharing options by tapping the button in the bottom left corner (the one that looks like a square with an arrow pointing upwards out of it).

Sharing options for screenshot in Photos app.

Here I can share the screenshot or, more likely, send it to myself.

From here you can share the photo or send it to specific people via MMS or email. Just tap the appropriate icon and iOS will walk you through the rest.

Node.js apps: what’s the difference between installing npm packages locally and globally?

You don’t need to spend too much time with Google to realise that there’s some amount of confusion about the purpose of global packages. Local packages people seem to grasp easily. Global packages… well, confusion. And if you’re one of those confuse people, don’t feel alone: I was confused too.

Ironic, considering I’m working on the npm support in Node Tools for Visual Studio. But, up until recently, global packages really weren’t that important in the implementation. We gave you a way to install and uninstall them in the alpha, but that was about it. Not much further thought given really:

Managing global packages in NTVS's npm Package Management dialog.

More recently I’ve been improving the way you interact with npm packages, and global packages are back in the frame. And the question is, what are they for? When (and how) should you use them? And when shouldn’t you?

Let’s take a step back. You might already be familiar with the outline structure of a node.js app:

Structure of a node.js app

On the left we’ve got the Explorer tree, and I’ve highlighted the root ExpressApp2 folder of my app (I was just using this for testing). The ExpressApp2 folder you can see above that is the Visual Studio solution folder.

On the right you can see the contents of my Node.js app, which is pretty sparse, along with the Visual Studio ExpressApp2.njsproj project file.

We also have the node_modules folder, where locally installed npm packages are stored. You can see that I’ve got angular, express, jade, and stylus installed locally.

If I want to use one of these modules in my code, I’d write something like:

var express = require('express');

No surprises so far. But what if express wasn’t there, but was instead installed globally? Could I still use it?

Well, yes, and no.

You see the global package installation folder (for such it is) is not just a big bucket of miscellaneous stuff that’s visible and accessible to all your node applications. There’s no way you can say in package.json, “please get this from (or install it to) the globally installed packages”. And if you try to require it in your code, well, that won’t work either.

And this makes sense, right? I mean you could have anything in your global packages so you probably don’t want all of them visible in all your node.js apps. The potential for problems would be significant.

So, back on point, what are global packages for?

Global packages are for anything that you need to access from the shell. By contrast local packages are for using within your apps.

So you’ll often find yourself installing frameworky or infrastructurey things in your global packages. Installed globally they’ll be on your PATH so you can use them anywhere.

A good example is Yeoman and its generators. You’ll use yo from the command line to scaffold out projects in a variety of places, so both Yeoman and the generators you want to use must be globally accessible.

Going back to express, this is an example of a package that you’ll often want to use in your node apps, so you’d normally install it locally. Except that it also has a command line interface… so you’ll want to install it globally?

Well, you can actually do both, and this might be the easiest option.

But, as I said earlier, you can use that global install in your apps. Maybe you have a lot of apps and you want to use the same version of express in all of them. That way, when you upgrade express, you only have to upgrade it globally and all your apps will get the upgrade. Nice, right?

If you wanted to do this, you’d need to link express into your node apps. To try this out, execute the commands below from the shell in a convenient folder. Couple of points:

  • On Windows you’ll need to run the Command Prompt as administrator, or you won’t be able to create the link,
  • For the npm init command, which will scaffold out a basic package.json for you, just accept all the default suggestions.
mkdir linktest
cd linktest
npm init
npm install express -g
npm link express

Unfortunately, unlike the npm install command, there’s no way to save express into your package.json dependencies list. You’ll need to edit the file and add it yourself. However, you should find that your linktest folder now contains a node_modules folder. Within that, you’ll find a symbolic link to your global express install. You can obviously drill into that folder just as if it were really in the linktest folder.

Now, as I said, if you update your global install of express your linktest node app will also get the update.

Hopefully that clears up the differences between local and global packages.

TAKE-HOME MESSAGE: always try to use local packages unless there’s a very good reason not to! (I.e., you need to use the package from the command line.)

 

Speaking on Node Tools for Visual Studio at Node.js & JavaScript Cambridge Meetup

I’m pleased to say I’ll be speaking at the Node.js & JavaScript Cambridge meetup on Tuesday 8th April. It’s upstairs at the Fountain Inn on Regent Street in Cambridge (UK), starting at 7.45PM.

I’ll be talking about and demoing Node Tools for Visual Studio. If you want to learn how to develop for Node on Windows, and you’re in the local area, please do come along. You can already sign up at:

http://www.meetup.com/NodeJS-Cambridge/events/164845272/

There will be two talks during the evening. I’m not sure what the other one is yet, but I’ll post as soon as I know. The usual format is 20 minute talks with 10 minutes at the end of each for questions.

I’m going to try to cover:

  • The different project templates
  • npm
  • Editing
  • Debugging
  • Profiling
  • Azure deployment

That’ll probably more than fill 20 minutes without too much difficulty. Being Cambridge, people love to ask questions so we’ll see if I can get through it all or not!

As I say, if you’re in the area that night, please do come along. They’re a sociable crowd and there’s plenty of time for drinking and chatting afterwards.

The iOS 7 Keyboard: Un-Damn Your AutoCorrect

I used to suspect that most of the posts on damnyouautocorrect.com were faked. That was until last month, when I finally upgraded my aged iPhone 3GS to an iPhone 5S and, with it, iOS7.

Overall, it’s been a great experience, but the autocorrect… oh, how I hated the autocorrect. Every time I wrote an email, replied to an SMS, I felt like I was fighting with it. It would even correct correctly spelled words. For example, “were” became “we’re” and, with a bizarre nod to either Shakespeare or Schiller, “passcode” became “pass ode”.

Really annoying.

I don’t know if this is because iOS 7’s autocorrect different from iOS 5’s. Maybe it was just the cumulative effect of 4 years of typos combined with that putatively tweaked algorithm. Whatever, it become intolerable.

Fortunately there is some relief to be had with a bit of tweaking. Let’s take a look at the options, starting with the least intrusive and working our way up from there.

Option 1 – The Nutcracker: teach the dictionary one word at a time

Next time you enter a word that it wants to wrongly auto-correct and the suggestion pops up, hit the little X you can see on the right of the suggestion:

Incorrect suggestion when writing an SMS.

Dammit, no! “Were” is a completely valid word.

OK, now delete the word and try to type it in again. When the suggestion pops up again, hit the X to dismiss it. Now delete the word and enter it again, etc. Keep doing this until the incorrect suggestions stops appearing: it’ll probably take about 5 attempts. Once that happens it should mean the dictionary has forgotten the old correction and will instead use the word you’ve entered as the new correction in future, if it makes any suggestion at all.

That’s fine, obviously, but if it’s wrongly correcting loads of words this process could become quite arduous. Which brings us round to…

Option 2 – The Sledgehammer: reset the keyboard dictionary

For me the situation was so bad I had to go down this route. Before you follow me though, understand that there is a downside. Resetting the dictionary will remove all the words it’s learned from you, so it’ll have to learn them all over again. Whilst it’s doing that it’ll probably suggest all manner of humorous and possible highly inappropriate or career-limiting alternatives.

(Just thought I should warn you.)

To reset your keyboard dictionary, open up Settings, and then drill down to General > Reset. Now tap Reset Keyboard Dictionary.

Settings page for resetting various aspects of iOS.

Reset your keyboard dictionary from here.

You’ll be asked to enter your unlock passcode:

Reset keyboard dictionary passcode confirmation screen.

Enter your normal unlock passcode here.

Once you’ve done that you’ll be asked to confirm that you want to reset the dictionary (with a warning about losing all your custom words, as I mentioned):

Reset keyboard dictionary final confirmation.

No going back after this.

And you’re done.

You might still find the vanilla dictionary a bit annoying to start off with, but at least now you have a clean slate. You should find it suggesting a lot fewer spurious autocorrections.

But, if this still doesn’t satisfy you, there’s always… 

Option 3 – Nuke autocorrect from orbit: it’s the only way to be sure

It’s a bit extreme, but you can just disable autocorrect, and it’ll never bother you again.

You need to do this via the keyboard settings, which you’ll find in Settings > General > Keyboard. They look like this:

Keyboard settings.

If you can’t find joy any other way, these settings give you access to the thermonuclear option.

You just need to switch off Auto-Correction. If it annoys you, you can also switch off Auto-Capitalization.

It’s also worth checking your shortcuts to make sure none of them is causing any annoying autocorrections.

Note: the Check Spelling setting is nothing to do with autocorrect. All it does is highlight what it thinks are misspelled words when it’s switched on. It does not try to correct them for you.

Final Thoughts

Things have definitely been better since I reset the keyboard dictionary, but there’s still the odd noticeable difference in iOS 7 autocorrect behaviour as compared to previous versions. For me the most noticeable is that in general it seems to suggest corrections/autocompletions much less often than did previous versions. This is sort of OK but it does mean you feel like you’re having to type a lot more.

Another comment I’d make is that with the form factor of the iPhone 5/5C/5S being longer and thinner than the 3GS and 4/4S, I don’t think Apple’s vanilla keyboard works quite as well because you have to stretch further to hit the keys in the centre. For me, at any rate, this seems to result in a few more typos.

There’s a lot of innovation around mobile and tablet on-screen keyboard design on both Android and Windows 8.1/Windows Phone 8. A good chunk of this is from third parties. Unfortunately this isn’t an option with iOS. I can see why Apple would be unwilling to open up the keyboard implementation to third parties, but it would be good to see them revisit it.

Hope this has been useful for you! And please let me know if you’re aware of anything else that might help.