I am new to Javascript and have decent experience with Django. I built a charting platform for my company to track metrics -- it started as a hobby project to learn Javascript but evolved into something more.
The site loads and displays data correctly, but it is unbelievably slow on mobile. All of the calculations are being done on the client-side is JS. There are a lot of metrics to calculate, so the thought process was "Send the client all the Django queries in Object format, and process them there in order to not slow down the server." I also did not want to have a huge block of code processing each metric on the server (am I wrong to do this?).
Some questions here:
For example, I want to display a chart showing the number of page views over a month period with the x-axis being the date, and the y-axis being count. In order to do this, I run a nested for loop to iterate over the query, then to count the number of page views for that date.
This is extremely slow when I run this function for three different metrics.
The data is received in an ajax call (is this optimal?). Here is the Javascript code that counts the number of hits for that day:
var endpoint = "/my/url/";
var opt_ins = [];
var schedules = [];
var page_views = [];
$.ajax({
method: "GET",
url: endpoint,
success: function (data) {
opt_ins = data.opt_ins;
schedules = data.audit_calls;
page_views = data.page_views;
},
error: function (error) { console.log("ERROR --> " + error); },
async: false
});
async function getDateCounts(data) {
dates = [];
count_dates = [];
let i = 0;
for (const element of data) {
let date = new Date(element.date_created).toLocaleDateString("en-US");
if (!dates.includes(date)) {
dates.push(date);
let count = 0;
for (const item of data) {
let check_date = new Date(item.date_created).toLocaleDateString("en-US");
if (check_date === date) {
count++;
}
}
count_dates.push(count);
count = 0;
}
}
return [dates, count_dates];
Here is the Django view:
class ChartData(APIView):
authentication_classes = []
permission_classes = []
now = pendulum.now()
time_period = now.subtract(months=1)
def get(self, request, format=None):
page_views = (
models.AgentPageViews.objects.filter(date_created__gt=self.time_period)
.order_by("date_created")
.values()
)
opt_ins = (
models.Client.objects.filter(date_created__gte=self.time_period)
.order_by("date_created")
.values()
)
audit_calls = (
models.ScheduledCalls.objects.filter(date_created__gte=self.time_period)
.filter(event__contains="Audit")
.order_by("date_created")
.values()
)
data = {
"page_views": list(page_views),
"opt_ins": list(opt_ins),
"audit_calls": list(audit_calls),
}
return Response(data)
Each of these queries returns an object of a different length.
Here is an example of what the final chart looks like with sample data
The database is a great place to aggregate this data and will reduce the amount of data needed to be passed around.
The aggregate()
method will let you get a data set like:
[{'date':COUNT},{'date':COUNT},...]
TruncDate()
allows group by day if you have a datetime.
from django.db.models import Sum
from django.db.models.functions import TruncDate
models.AgentPageViews.objects.filter(date_created__gt=self.time_period).
values(date=TruncDate('date_created')).
order_by("date_created").annotate(Sum('views')
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.