The Tesco Mobile Website and The Importance of Device Testing

A constant passion of mine is efficiency: not being wasteful, repeating something until the process has been refined to the most effective, efficient, economical, form of the activity that is realistically achievable.

I’m not saying I always get it right, just that it’s frustrating when I see this not being done. Especially so when the opposite seems to be true, as if people are actively trying to make things as bad as possible.

Which brings me on the the current Tesco mobile website, the subject of this article, and of my dislike of the misuse of a particular form of web technology: client side rendering.

What follows is a mixture of web perf analysis and my own opinions and preferences. And you know what they say about opinions…

Client Side Rendering; What is it good for?

client side rendering frameworks

No, it’s not “absolutely nothing”! Angular, React, Vue; they all have their uses. They do a job, and in the most part they do it well.

The problem comes when developers treat every problem like something that can be solved with client side rendering.

Are you building a single page application? Something that has a significant “chrome”, or surrounding area, that is constant throughout most operations, making the website feel more like an application?

Do you have two way data binding, where the user can change the state of an object, whose state can also be changed by another process or event?

Is a lot of your page made of lots of little dynamic elements, differing in content between users or environment state over time?

If you answered yes to any of these, then whoopee! You may as well go and play with the new fangled front end tech of your choice!

However, if you’re working on a blog, an article based content site, a brochure site, then you probably don’t need such powerful goodness.

No doubt some clever person has created a handy, cartoony, flow chart to help you decide if you should use client side rendering; if you find one please let me know!

Unfortunately these are all quite subjective comparisons, so I doubt I’ve managed to convince anyone who wasn’t sure which way to go. Also, there are a huge number of sites that fall between those two extremes; one of which is “e-commerce”.

The E-commerce Site

Having worked on e-commerce sites for over a decade (most of which was spent building from a classic asp site to the next few .net iterations) is where I gained a significant amount of my web development experience.

At its core, the e-commerce site inevitably consists of two core sections: browse and buy.

The “Buy” Section (Checkout)

The buy section is quite dynamic, containing your basket contents, your delivery and payment details, your order history perhaps; changing a delivery method may change other values and options, likewise for delivery address, or payment method.

ecommerce buy section

Lots potentially going on, especially if you’re trying to adhere to checkout “best practices” in terms of offering whatever is currently the most favourable user experience, such as keeping everything on one page instead of multiple checkout steps.

Given that on average an e-commerce site will generally get around 5-10% of the traffic converting from the browse section to the buy section (i.e., checking out), reducing how many calls a single page makes for optimisation purposes isn’t as big a concern as the browse section.

The browse section isn’t so obvious. It will probably consist of three page types: landing, listing, and detail:

The Landing Page

Also called the category page, this is the shop department window (e.g. “men’s”, “women’s”, “festival store”, “Adidas”, etc), where certain brands, products, and product types are displayed and promoted.

ecommerce browse section: landing page

Dynamic? Not usually. These could probably be static pages generated from a site generator or a CMS and pushed to a CDN; often they’re more content than products (i.e., more CMS than PIM).

You might display some basket content, but since pages these will likely get a lot of traffic from search bots and paid ads (PPC) due to their content and promotional objectives you’ll want to keep them as static as possible.

I’d suggest only loading dynamic basket content on a user event, like a click or mouse-over, and use your robots.txt to block those URLs from crawlers; keep your servers as cool as a cucumber.

The Listing Page

Once you’ve chosen a product type from some sort of menu, you’ll not be surprised to see a product listing page.

ecommerce browse section: listing page

Dynamic? Possibly; dynamic visual merchandising based on current user data and preferences can certainly result in better business metrics (average order value, lower bounce rate, higher conversion, etc) but for the sake of argument let’s assume everyone sees the same product listing for a given URL.

Again, basket info would be dynamic but could be loaded on a user event.

One thing Tesco, and many other e-commerce sites, do is to allow you to add items to your basket from the listing page. Tesco also highlight the added item, and show how many you currently have in your basket.

tesco browse section: listing page

Maybe you want to hide items as they go out of stock, but this is a performance/user experience trade-off you’ll have to make yourself; I’d suggest saving stock level info for later in the journey.

The Product Detail Page

You found something wonderful on the listing page and now you want to know more; it’s the product detail page!

ecommerce browse section: detail page

Dynamic? Getting there, sure. Should probably have stock availability here (though you could even save that until the checkout, if you value performance over user experience that much), and the ability to select from the product options: size, colour, fit, whatever, which could change other options on the page.

There’s a lot of scope for dynamism and personalisation on this page, especially around upsell and cross sell of related products: however none of these are in the critical path of getting the user to add the current product to their basket. As such, most of this page could be static, from a site generator, and pushed to a CDN.

I appreciate I’m being pedantic with a lot of this (and perhaps not very realistic) but beyond trying to prove a point I’m hoping you’ll take a moment and think about your own site; how much of it really needs to be dynamic? How much of it could exist in a static site generator, pushed to a CDN, avoiding your web server entirely? Hmmmmmm….. :)?

Where the magic happens

You know what’s reasonably reliable and consistent? Your web server and your Content Delivery Network’s hardware and (to a degree) the network immediately surrounding it.

You know what isn’t reliable and consistent? The end user’s device. The incredible diversity of different web capable devices is staggering, as is the variety of their hardware and capabilities.

What else? The network the end user is using. The applications that effect the traffic paying through their device. The space available on the device for temporary data persistence. The memory available.

All things that are pretty important when it comes to reliably creating a website.

You know what’s built for rendering HTML by binding data to layout? Your web server.

You know what isn’t (explicitly) built for rendering HTML by binding data to layout? The end user’s device.

This always brings to mind the Geoff Goldblum quote from Jurassic Park:

[They] were so preoccupied with whether or not they could that they didn’t stop to think if they should.

Yes, you can turn your user’s device into a web server; but should you?

What are you doing, Tesco??

This all brings me on to the subject of my ranting; the new Tesco groceries mobile website.

I do like a good mobile web site. Something fast to load and easy to use on a smaller, touch enabled, screen. Something that can handle flaky connections, as are all but guaranteed on a mobile device.

The current Tesco mobile website is not one of these, and it frustrates me so much, given that their previous site was at least functional, if not perfect.

It was recently updated with something that looks nicer and has larger, more thumb friendly, tap targets.

However, actually using it on a mobile device gave rise to some real usability issues; a listing page could hang and completely freeze, while still displaying the page “chrome”, adding an item to your basket would hang, meaning you’d tap again since you had no action confirmation, resulting in multiple items added. Attempting to view a basket containing more than a small number of items? Good luck with that! You’d be met with the page “chrome” and a loading spinner that never stops spinning.

Likewise, scrolling would halt and a drag to scroll would be interpreted as multiple taps, either adding unexpected items to your basket, or resulting in loading a random product detail page unintentionally.

Performance breakdown

Remind yourself of the page in question:

tesco browse section: listing page

Most of these headline scores don’t look completely awful until you check the Speed Index and various Time To numbers.

Google pagespeed insights

tesco pagespeed insights

58 is Poor, but not utterly woeful; I’ve seen much worse.

Web Page Test

This is based on the mobile site, simulating a mobile device on a 3G network:

Web Page Test

The poor Lighthouse score is to be expected; it’s not a Progressive Web App, nor does it pretend to be. Caching is a reasonably quick fix, so let’s not get hung up on that. The remaining “FAAA” rating isn’t too shabby.


  • Load time: 28 seconds
  • Fully loaded: 32 seconds
  • Start render: 9.7 seconds
  • Speed index 9781 (remember that lower is better and >2000 is the holy grail)
  • Time to first interactive: 20 seconds (ouch!)

So what’s going on here? A page weight of 1.2MB is below average (currently the average – AVERAGE – page size is OVER 3MB), so well done there; especially with an image heavy listing page. Where did these other nasty figures come from?

More on the stats

Let’s dig into the page a bit more; what is it made of? Bear in mind that, according to the HttpArchive, the average web page make up hovers around 60% images

67% JavaScript

Wow: 67% JavaScript? That’s a red flag right there. If you’re loading that much script onto your device, surely there will be an impact on usability. Let’s find out…

Breakdown of processing

The main thread of your browser is spending an awful lot of time processing JavaScript:

devtools processing

Yikes. That helps to explain the significant “jank”. Your device is having to do a lot of unnecessary work to get this page to the screen.

Behind the scenes

I actually have nothing against React (other than the weird HTML-JavaScript syntax), but this is concerning:

Tesco view source

You won’t be able to read that since it’s zoomed way way wayyyyy out, but the key takeaway is the scroll bar; the body tag doesn’t even appear until you scroll almost all the way to the bottom.

Over 70% of the page weight is data-props in the HTML tag. Then there’s another 10% of JSON config before we reach the body element.

Just think about how many round trips to the web server are needed in order to just get these packets of data over the network (a reliably unreliable 3 or 4G network, resulting in multiple “sorry, I don’t think I got that last packet quite right, can you resend it? Thanks!” TCP network chatter). All before the browser even sees a body tag. Ouch!

This is like someone kicking sand in the face of web performance nerds who like to aim for a critical path on that first load (i.e., squeezing “above the fold” content into the first one or two network packets).

The moral of this story: The importance of device testing

I’m not having a go at React/Angular/Vue in this article (I’ll save that for another one); here I’m pointing out what can happen when you focus on potentially the wrong goal.

By creating a fancy new website with probably completely reusable components, nicely packaged for consistent development, and probably well tested, no doubt with consistent coding conventions, Tesco dropped the ball on usability.

It’s obvious that Tesco didn’t do extensive device testing; on my wife’s reasonably decent iPhone 6, the same pages (with the same basket) on the same WiFi network are almost acceptable, in terms of interaction speed. On my Android Nexus 5X, it’s completely unusable. On a laptop running Chrome with developer tools set to pretend to be a Nexus 5X, everything seems completely fine. But my laptop is significantly more powerful, with way more memory, than the real device.

If you’re as big as Tesco, you can afford to buy, rent, or make a device lab. The Etsy team are an example of people who can show you how, and the fantastic Lara Hogan has co-authored a FREE book – Building a Device Lab which you should definitely check out.

Etsy device lab

If you can’t build one, then device labs are available to rent. Failing that, utilise WebPageTest device emulation and export the results to understand how much work is being done by the device.


I buy groceries regularly, like everyone else. I’m not in any way locked to one provider. I’ve used Tesco for years in spite of the mobile app being so bad that I had no option but to use the mobile site. But just releasing a bad version of a previously usable site is enough for me to change to one of the numerous competitors; I can’t imagine I’m alone in this – I wonder what effect this updated site has had on their business metrics?

If you take anything away from this rant, please let it be these two points:

  1. Don’t use new tech for the sake of using new tech; sometimes old and boring is the right answer, if not the popular one,
  2. If you’re building a web site for mobile devices, automate testing on real mobile devices.

Agree? Disagree? Meh? Opinions? Hit me up in the comments and over on Twitter.

Work for the Tesco dev team? I’d honestly love to chat with you! I’m sure you were doing the best you could with the tools you had in the time available.

Building your first Botframework based Cortana Skill

Hi. I'm Cortana.

At //BUILD 2017 Microsoft announced support for Cortana Skills and connecting a Cortana Skill into a Bot Framework chatbot; given the number of chatbots out there using Microsoft Bot Framework, this is an extremely exciting move.

In this article I’ll show you how to create your first Cortana Skill from a Bot Framework chatbot and make it talk!


If you’re not already familiar with Cortana, this is Microsoft’s “personal assistant” and is available on Windows 10 (version 1607 and above) and a couple of Windows phones (Lumia 950/950 XL), a standalone speaker – like an Amazon Echo – and a plethora of devices that can run the Cortana app, including iOS and Android and plenty of laptops.

Cortana all the things, Derrick.

You’re going to be seeing a lot more of this little box of tricks (“Bot” of tricks? Box of bots?.. hmm…), so you might as well get in on the act right now!

Continue reading

Involved in a startup? Read this!

Having been the VP of Engineering at a startup, I understand a lot of the challenges. The technical ones relating to the solution you think you need to build, more technical ones relating to the solutions the investors want you to build, the development process to best fit a rapidly changing product, team, requirements, and priorities, as well as managing the team through uncertain terrain.

They’re the fun ones. The easy ones! Especially given how talented my dev team was.

The founder had the difficult challenges; define a product that could be a success, iterate that idea based on extensive user testing, and most importantly, ensure there was funding.

Luckily, our founder was as talented at soliciting funds as we were at building epic tech!

If you are involved in a startup, perhaps Just Eat’s Accelerator programme can help with both types of challenge!

Continue reading

Receiving Images to Your Skype Botframework Bot (v2!)

If you’re getting a “403” HTTP error when attempting to receive an image sent to your Skype bot, and the previous use of message.ServiceUrl to create a ConnectorClient didn’t work, try this more verbose version which explicitly sets the authorization header:

byte[] data;

if (image.ContentUrl != null)
    using (var connectorClient 
        = new ConnectorClient(new Uri(message.ServiceUrl)))
        var token = 
            await (connectorClient.Credentials as MicrosoftAppCredentials)

        var uri = new Uri(image.ContentUrl);

        using (var httpClient = new HttpClient())
            if (uri.Host.EndsWith("") 
                && uri.Scheme == Uri.UriSchemeHttps)
                    .Authorization = 
                        new AuthenticationHeaderValue("Bearer", token);

                    .Add(new MediaTypeWithQualityHeaderValue("application/octet-stream"));

            // Get the image in a byte[] variable
            data = await httpClient.GetByteArrayAsync(uri);

Generating Image Hashtags using Microsoft’s Computer Vision API

Whatever your social media tool of choice is these days, it’s almost guaranteed to be filled with images and their associated hashtags #sorrynotsorry #lovelife #sunnyday

Sometimes coming up with those tags is more work than perfectly framing your latest #flatlay shot.

In the age of amazing image recognition tech, it must be possible to create something that can help us out and give us more time to move that light source around to cast the right shadow over your meal.

Turns out, it is possible! Yay! (of course..)

In this article I’ll show you how to automatically generate image hashtags via a chatbot using Microsoft’s Computer Vision API.

Continue reading

Sentiment Analysis using Microsoft’s Cognitive Services

Now that we are making more conversational interfaces thanks to technology like botframework, interaction with the user is no longer limited to a tap on a link or a button.

Having written language as the primary form of interaction with our systems gives significant difficulties in terms of intent understanding, but also gives great opportunities for further understanding of the user.

Intent understanding has already been tackled by the likes of LUIS; what about the user’s sentiment?

In this article I’m going to introduce Microsoft’s Text Analysis API and show you how to easily get sentiment analysis for a message coming in to your bot.

Continue reading

MVP led TechDays Online: Videos!

As part of Microsoft’s recent Tech Days Online, I was very pleased to be able to record a couple of short videos about botframework, LUIS, the QnA Maker, and how I have been working with JustEat to use these technologies in their Customer Help chatbot solution.

Unfortunately I wasn’t able to attend the live TechDays sessions, so instead of an hour or two of my dulcet tones you only have the pleasure of ten minutes; feel free to replay those minutes as many times as you like!

First up, a ten minute session on the JustEat Customer Care chatbot implementation:

Continue reading

5 Cool Chatbots: Feb 2017 Edition

ChristopherBot (Facebook)

Never forget your homework again

I have to include this bot first; it’s received a lot of press over the past few weeks, and rightly so. A great little concept from a 14 year old schoolboy who was forever forgetting about his homework. He created a Facebook messenger chatbot in Ruby and hosted on Heroku to help him (and you!) keep track of work that’s pending.


Read more about ChristopherBot on the BBC and try it out over at You can view the code (mainly Ruby) over on GitHub – annoyingly good code from someone so young! He puts me to shame..

Continue reading

Virtual Shop Assistant Chatbot with Amazing Image Recognition

There has been some significant progress in “deep learning”, AI, and image recognition over the past couple of years; Google, Microsoft, and Amazon each have their own service offering. But what is the service like? How useful is it?

Everyone’s having a go at making a chatbot this year (and if you’re not, perhaps you should contact me for consultancy or training!) – and although there are some great examples out there, I’ve not seen much in the e-commerce sector worth talking about.

In this article I’m going to show you a cool use case for an image recognition e-commerce chatbot via a couple of clever APIs wired together by botframework.

Continue reading

MVP led TechDays Online

MVP led TechDays Online

On February 20th to 22nd you’ll be able to join MVPs like me at the 3 day online conference UK Tech Days Online.

This is a chance for MVPs to talk about some of the cool new MS tech that’s out there, show you how to use it yourself, and give a few case studies. This year it’s all about AI, Bots, Data Science, and Azure OSS – awesome stuff!

Since I’m not able to attend this on the day of the event, my fellow Bot MVP, Gary Pretty, will be accompanied by the talented James Mann (no doubt a Bot MVP in the next round of awards!) for a couple of sessions on Day 1 all about BotFramework, LUIS, and the various features and tooling around that ecosystem.

So that you don’t miss out on my handsome visage (!), I’m pre-recording a short session at Microsoft over the next couple of weeks, which will hopefully be played here and there throughout the conference, where I give a very brief case study for the JustEat Help chatbot; it’ll be a tasty Bot infomercial snack – don’t miss out!

Full Schedule

20 February 2017

  • 10.00am: Data, data, data – How and where to store it on Azure?
  • 11.00pm: Conversational UI using the Microsoft BOT Framework
  • 12.00pm: Microsoft Bot Framework and Cognitive Services: Make your BOT smarter!
  • 1.00pm: The best kept secret, Document DB.
  • 2.00pm: Let’s discuss Server-less.
  • 3.00pm: Keynote: Dr Mike Rys What is an Azure Data Lake?

21 February 2017

  • 10.00am: Creating a PHP-MySQL web app in Azure App Service and deploying using FTP.
  • 11.00am: Gain profit from Azure app service tooling as an OSS developer.
  • 12.00pm: Dockerizing Your Cross-Plat .NET Development.
  • 1.00pm: Communication Driven Development.
  • 2.00pm: Monitoring Linux in Azure with Microsoft Operations Management Suite Log Analytics.
  • 3.00pm: The Open Source World of Xamarin.

22 February 2017

  • 10.00am: Bootstrapping blockchain.
  • 11.00am: How IOT and data is changing lives.
  • 12.00pm: An introduction to Quantum Computing.
  • 1.00pm: Social Scientist Professor Bradley Love from University College London and the Alan Turing Institute
  • 2.00pm: Microsoft Regional Directors panel.

If this whets your appetite for nerd knowledge, pre register now at