Hey all!
As you continue to work with Wix Code you might end up on larger and larger Data Collections to work with. This will be a deal breaker for the visitors on your sites, if they get slower and slower or keep being fast.
I started out this morning in doing a test by importing 1000 records into a DummyData Data Collection and used a Dataset and connected that Dataset to a table.
Then listing all the records, making it possible for the user to search a column, filter by two different dropdowns and also filtered one dropdown when selecting countries in one to just show the cities belonging to that country.
Site url: https://andreaskviby.wixsite.com/speedtesting
The first version loaded quite slow as you see below from GTMetrix.
Very little coding on that version and also using the setFilter on the Dataset when searching and filtering.
So after this I decided to make this page ultra fast and as speedy as my knowledge can and I am not a pro in any ways so bare with me on this.
I moved code to backend when getting the data. I also made all data available in a single call to the backend dividing the data into sub arrays of one larger array from backend. Bare that I still get 1000 records. If I would make this super fast I would load less and then have a Load more.
After I recoded the page to use backend modules instead of a Dataset and made some tweaks to the filters the page load time is down to 5.1 seconds fully loaded. The standard loading time according to GTMetrix for fully loaded pages is around 7 seconds. So this is ultra fast.
I have got results as low as 4.8 seconds as well so I am pretty happy with the results.
So here is my code for you to look at and take whatever you like.
Page Code:
// Code by Andreas Kviby
// GTMetrix Fully loaded page 5.1 seconds
import {getAllData, filterCityDropdownByCountry} from 'backend/dataService';
let unfilteredRecords = [];
$w.onReady(async function () {
$w("#table").rows = [];
getAllData().then((allObjects) => {
let allRecords = allObjects.allRecords;
unfilteredRecords = allRecords;
$w("#table").rows = allRecords;
$w("#cityDropdown").options = allObjects.citiesList;
$w("#countryDropdown").options = allObjects.countriesList;
})
});
export async function searchButton_click(event) {
let searchWord = $w("#searchInput").value;
let searchResults = unfilteredRecords.filter(obj => obj.first_name === searchWord);
$w("#table").rows = searchResults;
}
export async function cityDropdown_change(event) {
let searchWord = $w("#cityDropdown").value;
let searchResults = unfilteredRecords.filter(obj => obj.city === searchWord);
$w("#table").rows = searchResults;
}
export async function countryDropdown_change(event) {
let searchWord = $w("#countryDropdown").value;
let searchResults = unfilteredRecords.filter(obj => obj.country === searchWord);
$w("#table").rows = searchResults;
let filteredCities = await filterCityDropdownByCountry(searchWord, unfilteredRecords);
$w("#cityDropdown").options = filteredCities;
}
Backend module dataService.jsw:
import wixData from 'wix-data';
let returnedObjects = {
allRecords: [],
citiesList: [],
countriesList: []
};
export function getAllData() {
return wixData.query("DummyData")
.limit(1000)
.find()
.then(async(results) => {
if (results.totalCount > 0) {
returnedObjects.allRecords = results.items;
returnedObjects.citiesList = await createOptions(getUniqueByField("city", results.items.sort(sortArray("city"))));
returnedObjects.countriesList = await createOptions(getUniqueByField("country", results.items.sort(sortArray("country"))));
return returnedObjects;
}
return returnedObjects;
})
}
export function searchData(field, fieldValue) {
return wixData.query("DummyData")
.contains(field, fieldValue)
.limit(1000)
.find()
.then((results) => {
if (results.totalCount > 0){
return results.items;
}
return null;
})
}
export async function filterCityDropdownByCountry(countryName, items) {
let newCityList = items.filter(obj => obj.country === countryName);
let sortedCities = newCityList.sort(sortArray("city"));
let uniqueCities = await getUniqueByField("city", sortedCities);
return await createOptions(uniqueCities);
}
export function uniquerecords(a) {
var seen = {};
var out = [];
var len = a.length;
var j = 0;
for(var i = 0; i < len; i++) {
var item = a[i];
if(seen[item] !== 1) {
seen[item] = 1;
out[j++] = item;
}
}
return out;
}
function sortArray(property) {
var sortOrder = 1;
if(property[0] === "-") {
sortOrder = -1;
property = property.substr(1);
}
return function (a,b) {
var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
return result * sortOrder;
}
}
export function getUniqueByField(fieldName,items) {
const uniqueOnly = items.map(item => item[fieldName]);
return [...new Set(uniqueOnly)];
}
export function createOptions(uniqueList) {
return uniqueList.map(curr => {
return {label:curr, value:curr};
});
}
I hope you will enjoy this code and the performance change that is huge from using Dataset to using a backend module. I have no idea what the recommendations are but I have tried and now I share my thoughts and results with you.
If you would like to make the fastest page using Wix Code you should make the query only return like 25 records and then when moving down or clicking Load More get another 25 records and show that. That would mean a even faster page and who doesn’t need a fast page, right?
When I did only return 25 records per query my page load speed is down to 4.2 seconds fully loaded and I can’t imagine having a faster page. It is more than 3 seconds faster than the average fully loaded page speed and that is impressive I think.
And with Cache Engine Turned on and 1,000 records in the query!!!
Happy Wix Coding!
#performance #dataset #backend #wixData