The Maestro
The Maestro

Reputation: 689

Improving performance

I am new in AngularJS. I developed a list that can be filtered when typing in a search box. the filter takes many fields from a database object and search through all of these fields (such as: name, id, comments ... etc). The problem appears when I load all of the queryset and fill the list in the angular method using the (push) command. since I have a considerable amount of records in the database, loading the page takes around 12 seconds, and the database is increasing so this time is going to grow! I tested the performance using the time line and as expected, the scripts are taking a very long time!

Here is a piece of my code:

Template

<script type="text/javascript">

    ngApp.controller('FilterCtrl', function ($scope) {


        $scope.lines = [];

        {% for line in lines %}

            $scope.lines.push
            ({
                id:{{ line.id }},
                name: '{{ line.name }}',
                alias: '{{ line.alias }}',
                owners: '{{ line.print_owners }}',
                interested_in: '{{ line.print_interested_in }}',
                crosses_count: '{{ line.related_crosses_count }}',
                area: '{{ line.expressions }}',
            });

        {% endfor %}    
  });

</script>

views:

def browse_lines(request):
     lines = Line.objects.filter(deleted=False).order_by('name')

     return render_to_response('Browse_Lines.html',
                          {'lines': lines },
                          context_instance=RequestContext(request))

Any way to improve the performance and speed up filling the list? Thank you very much.

Upvotes: 2

Views: 195

Answers (2)

Sayse
Sayse

Reputation: 43300

A quick win would be to stop pushing things to the array one by one

$scope.lines = [
{% for line in lines %}
   {
        id:{{ line.id }},
        name: '{{ line.name }}',
        alias: '{{ line.alias }}',
        owners: '{{ line.print_owners }}',
        interested_in: '{{ line.print_interested_in }}',
        crosses_count: '{{ line.related_crosses_count }}',
        area: '{{ line.expressions }}',
    },
{% endfor %}    
];

</EndUglyCode>

Now the correct way would be to make a separate get request to fetch the data as you require it (for which there are plenty of angular examples around including on the angular homepage).

Pagination would definitely be a good idea but at the very least you can splice the initial results so you're not returning N objects all the time

 lines = Line.objects.filter(deleted=False).order_by('name')[:10]

If you really feel that you need to return all lines then you should consider if ordering them is required since this is likely to make up a hefty chunk of the time.

Upvotes: 2

Tarun Dugar
Tarun Dugar

Reputation: 8971

There's no way of 'speeding up'.

The best way would be to paginate your table such that initially the data would be loaded only for the first page. Say, you have 1000 items, divide it into pages of say 100 items each. So, initially only the first 100 items will be fetched. When you go to a different page the next 100 items and so on.

Also, for filtering you will to write an api endpoint which would accept the filter query and return items from the database. Then show these items in your table. As for when to hit this api, use the combination of ngChange, ngModel and ngModelOptions(for debounce) like this:

<input type="text" ng-model="search.query" ng-change="getItems()" ng-model-options="{debounce: 1000}" />

Here, getItems() will be called when the user types in something and waits for 1s (handled by debouce). In that function, send search.query to the api.

Upvotes: 2

Related Questions