Top Performing Automotive Dealer Websites

Recently, I was asked to recommend a website platform to a client of ours whose website is currently on CDK’s platform. (As you’re probably well aware, CDK will soon no longer host dealer websites.)

I’m glad our client asked because 1) working with a website that’s optimized for a mobile, search-driven world makes our job as a digital marketing agency so much easier, and 2) I had literally no idea which platform performed the best. Here was an opportunity to learn something valuable. And that’s exciting!

For this project, I analyzed the websites of 124 dealerships. The points of analysis included:

  • Google Lighthouse audit
    • Speed performance score
    • Speed index
    • Accessibility
    • Best practices
    • SEO
  • Fundamental search engine optimization (SEO) factors
    • Unique title tags for each search results page (SRP)
    • Unique title tags for each vehicle details page (VDP)
    • Unique indexable URLs for SRPs
    • Unique indexable URLs for VDPs
    • Unique indexable content and links on SRPs
    • Unique indexable content on VDPs

From these data points, I calculated a total score for each content management system (CMS), i.e. website platform. This total score gives us a relatively objective basis for ranking and perhaps choosing one CMS over another. Bear in mind, of course, that this analysis looks only at those factors that would help the website rank well organically in Google and provide a positive experience to your website’s visitors. 

And let me just say… the results surprised me. Some of the best performing website platforms are used by relatively few dealers. And other significantly more popular platforms showed only mediocre performance.

One last word about this research… Neither Mudd nor I have any affiliation with any of the businesses whose products I’ve analyzed. Like you, I simply wanted to know which website platform would deliver the best results. For my part, I wanted to be able to make a confident recommendation to our clients based on objective data.

Anyway, without further ado…


Results of the website performance analysis

Explanation of the Results

Top Performing Website

As you can see, the top performing website was fusionZONE. fusionZONE was the second fastest website and had the third-highest speed performance score. Google’s Lighthouse audit ranked them about average for accessibility, best practices, and SEO. Finally, fusionZONE checked all the boxes on the three fundamental on-page elements for search engine optimization (unique title tags, unique indexable URLs, and unique indexable content and links).

Although fusionZONE topped the list, coming in a close second was Dealer eProcess. Dealer eProcess’ platform actually scored better than fusionZONE on the Lighthouse Speed Performance Score. However, their accessibility and best practice scores were among the lowest, leaving them ranked #2.

Fastest Website

Outside of the content of a web page, speed is perhaps the most critical element to your online presence. The majority of your website’s visitors are on mobile devices, and they’re often not on WiFi. So, if your website doesn’t load almost immediately, customers will quickly give up and take their attention (and business) elsewhere.

The fastest website by far was the obscure Spinutech, who happens to be local to Mudd’s home town of Cedar Falls. Unfortunately for Spinutech, their website lacked four out of six of the critical search engine optimization elements. And because they scored only average in the other areas of Google’s Lighthouse audit, they found themselves ranked last overall. If they were to improve the content and indexation side of their platform, their CMS could potentially become a great option for dealers.

Most Accessible Website

Web accessibility means that websites, tools, and technologies are designed and developed so that people with disabilities can use them.

Most websites, unfortunately, scored in the 60% to 69% range. However, one underdog website platform has clearly made accessibility a priority, scoring 81%. This inclusive, disability-conscious CMS was ProMax. Unfortunately, it was also the slowest website, taking nearly 15 seconds to load. But if accessibility is a major concern, check out ProMax.

Have questions or want to learn more?

Leave me a comment below.

Related Posts

26 Responses
  1. Joe

    Any thoughts on how to do this with an importrange?

  2. Dave Meindl

    Import the data into your “data” sheet with importrange. Effectively, there’s no difference between static data and imported data.

  3. David Stirlng

    Thank you very much for writing this. Using your example made it really easy to create a “Sort by: [Column name]” dropdown menu.

  4. Dave Meindl

    David, I’m glad to hear that this post was of use to you.

  5. Dave Meindl

    You’re welcome.

  6. Rodolpho Brock


    function columnToLetter(column)
    var temp, letter = ”;
    while (column > 0)
    temp = (column – 1) % 26;
    letter = String.fromCharCode(temp + 65) + letter;
    column = (column – temp – 1) / 26;
    return letter;

    function columnOf(columnName, sheetName, headerRow){
    var ss = SpreadsheetApp.getActiveSpreadsheet();
    var sheet = ss.getSheetByName(sheetName);
    headerRow = (headerRow?headerRow:1);

    var headerAddress = “A” + headerRow + “:” + columnToLetter(sheet.getLastColumn()) + headerRow;
    var range = sheet.getRange(headerAddress);
    var values = range.getValues();

    for( var column = 0; column <= values[0].length; column++ ) {
    if( values[0][column] == columnName ) return columnToLetter(column+1);

    throw ("ERROR: NOT FOUND!");

    =QUERY(data!A:C;CONCATENATE("SELECT ";columnOf("Year";"data")))

  7. Dave Meindl

    Nicely done, man. Thanks!

  8. Wanderley Oliveira

    Thank you so much for sharing this awesome way to get things working out in a easy way. Your exemplos made it clear!

    Hugs from Brasil

  9. Elaine

    Thank you for posting this! I spent a ridiculous amount of time searching for a way to deal with my variable column locations. It seemed like such a small problem when I created the spreadsheet, yet it was incredibly difficult to find a working solution. This worked a treat AND provided to ability to match a cell reference instead of a string. I ended up creating a column of drop down menus to choose my desired headers:

    ‘DataSheet’ contains the data with variable columns
    ‘QuerySheet’ is where you choose the headers you’d like
    “DataHeaders” is a named range for your data’s headers, ie ‘DataSheet’!1:1
    ‘QuerySheet’!A2 and down are each Data Validated with a dropdown list for the named range “DataHeaders”

    &”, “&SUBSTITUTE(ADDRESS(1,MATCH(‘QuerySheet’!$A$3,DataHeaders,0),4),1,””)
    &”, “&SUBSTITUTE(ADDRESS(1,MATCH(‘QuerySheet’!$A$4,DataHeaders,0),4),1,””)
    &”, “&SUBSTITUTE(ADDRESS(1,MATCH(‘QuerySheet’!$A$5,DataHeaders,0),4),1,””))

    My data set has over 60 columns, and I use this to grab over 30 of them with no problems. The formula is absurdly long, but it works. I’m sure it could be condensed to be more efficient, but I’ve spent far too much time already on such a small issue! It would be great if Google could make selecting headers in a Query more intuitive.

    Thanks again!

  10. Dave Meindl

    Elaine, I’m so glad to hear that you found success with this.

  11. Elaine this looks awesome, do you have a working spreadsheet example of this?

  12. This was a TREMENDOUSLY valuable set of guidance around how to accomplish exactly what I wanted to accomplish. Very nicely done.

  13. Arun Kumar Nair

    This Is close to what I was searching. Thank you. Can you help me with my exact problem. It is as below:
    I have a sheet with sales data of salesman selling two products x and y arranged over a period of time. Like x jan’17 y jan’17 x feb’17 y feb’17 and so on till x dec’18 y dec’18. I want to find all columns which has sales of x in 17. Is it possible?

  14. Narendra

    hi expert, I have done code in MS XLS but this does not work for Google Sheets can you please help me create a macro for Google sheet, which will find certain text in a in given column and copy entire row and paste in given sheet name after Last entry.

    For an example I have a sheet which content verius fruites data on date 13-1-2018, if I run macro then it should find mango and apple in the given column refrence and copy entire row and add it to “mango” sheet after 12-1-2018 entry and same thing with apple too

  15. You can create macros in Google Sheets. However, in this case, it sounds like a macro might be unnecessary (and inefficient).

    For example, you could use QUERY. Suppose that your “fruit” is in column C.
    =QUERY(product_sales!A:Z,"SELECT * WHERE C = 'mango'")
    If you want to show only records from yesterday, you’d do something like the following. (Suppose that the dates are in column A.)
    =QUERY(product_sales!A:Z,"SELECT * WHERE C = 'mango' AND A = DATE '"&TEXT(DATEVALUE(TODAY()-1),"yyyy-mm-dd")&"'")

    Alternatively, you could use the FILTER function to pull in only the desired rows.

    However, easiest of all, you could skip all the extra sheets and formulas and simply create filtered views of the original sheet.

  16. Narendra

    Thanks sir for your reply. Actually I don’t want to filter data , what I want to do is, find given text here is “mango” in given column specified and copy entire row than it should add in next empty row in named “mangos inventory” sheet.

    I have searched a lot on net and taking some bits and pieces from verius code I came up with this code ,

    function givenmodi() {
    var ss = SpreadsheetApp.getActiveSpreadsheet();
    var s = ss.getSheetByName(‘Sheet1’);
    var r = s.getDataRange();
    var v = r.getValues();
    var arr = new Array();
    for(var i=0;i<v.length;i++) {
    if(v[i][0]==='Table') {
    var t = ss.getSheetByName('Table');

    Now this code finding and copying properly but problem is it's not adding in next empty row in " mangos inventory'" sheet. In fact it's easiering sheet and than pasting..

    Hope you understood my problem.

    Thanks & regards

  17. Please share your sheet as well as an example of what you want the end result to look like.

  18. Niranjan

    Hi, Thanks for the Query.
    How to arrange the same in ascending or descending order of a particular column value

  19. DP

    Is it possible to add Arithmetic, Grouping, Etc?

    I tried things like sum(“&SUBSTITUTE(ADDRESS(1,MATCH(“Year”,data!A1:C1,0),4),1,””)&” ), but kept getting errors.

  20. Yep. SUM, GROUP BY, etc. will all work so long as the their conditions are met. For example, SUM requires that all rows in the column be numeric. Anyway, here’s an example that works:

    =QUERY(data!A:C,"SELECT SUM("&SUBSTITUTE(ADDRESS(1,MATCH("Year",data!A1:C1,0),4),1,"")&")")

  21. Eléonore Breton

    Dave, thanks a million for your post, extremely useful. Would you by chance have a trick to select multiple columns with the same header? For example, I have 3 columns ‘Components’ but using SUBSTITUTE(ADDRESS(1;MATCH(“Components”;’Import’!A1:EE1;0);4);”1″;””) will always give me the first one…

  22. Eléonore, I’d recommend not having multiple columns with exactly the same header name. You can think of your spreadsheets like a database, especially when using QUERY. And think of each individual sheet like a table in your database. The first row is the header row in your table, and each column has a unique name. Having a unique name is how SQL and your database work together to identify what column you want. For example, if you have multiple columns named “Components” in a single table, writing a query like “SELECT `Components` FROM my_database” would be ambiguous. It’s unclear which “Components” column is desired.

    The quick and dirty solution is to add a sequential numeric value to each “Components” header name (e.g. Components_1, Components_2, Components_3).

  23. Eléonore Breton

    Dave, yes I totally agree this isn’t a database format for my sheet but it’s the format I export from the tool I use (Jira). Yes I’ll think I’ll have to resort to your quick & dirty solution.
    Thanks a lot again!

Leave a Reply