diff --git a/aleksis/apps/alsijil/managers.py b/aleksis/apps/alsijil/managers.py
index 4c7741d3b89620b1682532192acf7fb9ad1c0196..ab9daaa7ebb171b9979fa8893fc7eaa0c598a31d 100644
--- a/aleksis/apps/alsijil/managers.py
+++ b/aleksis/apps/alsijil/managers.py
@@ -89,6 +89,9 @@ class PersonalNoteManager(CurrentSiteManagerWithoutMigrations):
                 "lesson_period__period",
                 "lesson_period__lesson__validity",
                 "lesson_period__lesson__validity__school_term",
+                "event",
+                "extra_lesson",
+                "extra_lesson__subject",
             )
             .prefetch_related("extra_marks")
         )
diff --git a/aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html b/aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html
index 8c83accaf9b7cfc9e07a2b05c16961d3f959fd75..07d65508b31f8d6faad586a88f54bb8a30b78f3c 100644
--- a/aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html
+++ b/aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html
@@ -318,12 +318,7 @@
             </span>
             {% for person in persons %}
               <h5 class="card-title">
-                {% has_perm "alsijil.view_person_overview" user person.person as can_view_person_overview %}
-                {% if can_view_person_overview %}
-                  <a href="{% url "overview_person" person.person.pk %}">{{ person.person.full_name }}</a>
-                {% else %}
-                  {{ person.person.full_name }}
-                {% endif %}
+                <a href="{% url "overview_person" person.person.pk %}">{{ person.person.full_name }}</a>
                 {% has_perm "alsijil.register_absence" user person.person as can_register_absence %}
                 {% if can_register_absence %}
                   <a class="btn primary-color waves-effect waves-light right"
@@ -335,7 +330,7 @@
               </h5>
               {% if group_roles %}
                 <p>
-                  {% for assignment in person.person.group_roles.all %}
+                  {% for assignment in person.group_roles %}
                     {% include "alsijil/group_role/chip.html" with role=assignment.role small=assignment.date_range %}
                   {% endfor %}
                 </p>
@@ -356,17 +351,15 @@
                 </p>
               {% endfor %}
               {% for note in person.personal_notes %}
-                {% if note.remarks %}
-                  <blockquote>
-                    {{ note.remarks }}
-                    {% weekday_to_date week note.register_object.period.weekday as note_date %}
-                    <em class="right">
-                      <a href="{{ note.register_object.alsijil_url }}">
-                        {{ note.date }}, {{ note.register_object.get_subject.name }}
-                      </a>
-                    </em>
-                  </blockquote>
-                {% endif %}
+                <blockquote>
+                  {{ note.remarks }}
+                  {% weekday_to_date week note.register_object.period.weekday as note_date %}
+                  <em class="right">
+                    <a href="{{ note.register_object.alsijil_url }}">
+                      {{ note.date }}, {{ note.register_object.get_subject.name }}
+                    </a>
+                  </em>
+                </blockquote>
               {% endfor %}
             {% endfor %}
           </div>
diff --git a/aleksis/apps/alsijil/util/predicates.py b/aleksis/apps/alsijil/util/predicates.py
index 628ae7ae5e0079fe402df9e44c84ef9c07a36877..1759a5446d204d61c87f5bd1cbe9e3e031d95be2 100644
--- a/aleksis/apps/alsijil/util/predicates.py
+++ b/aleksis/apps/alsijil/util/predicates.py
@@ -98,13 +98,20 @@ def is_person_group_owner(user: User, obj: Person) -> bool:
     the owner of any group of the given person.
     """
     if obj:
-        for group in obj.member_of.all():
-            if user.person in list(group.owners.all()):
+        for group in use_prefetched(obj, "member_of"):
+            if user.person in use_prefetched(group, "owners"):
                 return True
         return False
     return False
 
 
+def use_prefetched(obj, attr):
+    prefetched_attr = f"{attr}_prefetched"
+    if hasattr(obj, prefetched_attr):
+        return getattr(obj, prefetched_attr)
+    return getattr(obj, attr).all()
+
+
 @predicate
 def is_person_primary_group_owner(user: User, obj: Person) -> bool:
     """
@@ -114,7 +121,7 @@ def is_person_primary_group_owner(user: User, obj: Person) -> bool:
     the owner of the primary group of the given person.
     """
     if obj.primary_group:
-        return user.person in obj.primary_group.owners.all()
+        return user.person in use_prefetched(obj.primary_group, "owners")
     return False
 
 
@@ -127,7 +134,7 @@ def has_person_group_object_perm(perm: str):
 
     @predicate(name)
     def fn(user: User, obj: Person) -> bool:
-        groups = obj.member_of.all()
+        groups = use_prefetched(obj, "member_of")
         for group in groups:
             if check_object_permission(user, perm, group, checker_obj=obj):
                 return True
diff --git a/aleksis/apps/alsijil/views.py b/aleksis/apps/alsijil/views.py
index 77e593943e10d7100ba2cf3b90c804c5ae8d957c..76608cda46699bf8e2f99f3d8fcbb0f0af4e74eb 100644
--- a/aleksis/apps/alsijil/views.py
+++ b/aleksis/apps/alsijil/views.py
@@ -1,3 +1,4 @@
+import time
 from contextlib import nullcontext
 from copy import deepcopy
 from datetime import date, datetime, timedelta
@@ -280,6 +281,16 @@ def register_object(
     return render(request, "alsijil/class_register/lesson.html", context)
 
 
+class catchtime(object):
+    def __enter__(self):
+        self.t = time.time()
+        return self
+
+    def __exit__(self, type_, value, traceback):
+        self.t = time.time() - self.t
+        print(self.t)
+
+
 @permission_required("alsijil.view_week", fn=get_timetable_instance_by_pk)
 def week_view(
     request: HttpRequest,
@@ -373,6 +384,7 @@ def week_view(
     if show_group_roles:
         group_roles = GroupRole.objects.with_assignments(wanted_week, [group])
         context["group_roles"] = group_roles
+        group_roles_persons = GroupRoleAssignment.objects.in_week(wanted_week).for_group(group)
 
     extra_marks = ExtraMark.objects.all()
 
@@ -380,11 +392,16 @@ def week_view(
         lesson_periods_pk = list(lesson_periods.values_list("pk", flat=True))
         lesson_periods = annotate_documentations(LessonPeriod, wanted_week, lesson_periods_pk)
 
-        events_pk = list(events.values_list("pk", flat=True))
+        events_pk = [event.pk for event in events]
         events = annotate_documentations(Event, wanted_week, events_pk)
 
         extra_lessons_pk = list(extra_lessons.values_list("pk", flat=True))
         extra_lessons = annotate_documentations(ExtraLesson, wanted_week, extra_lessons_pk)
+        groups = Group.objects.filter(
+            Q(lessons__lesson_periods__in=lesson_periods_pk)
+            | Q(events__in=events_pk)
+            | Q(extra_lessons__in=extra_lessons_pk)
+        )
     else:
         lesson_periods_pk = []
         events_pk = []
@@ -399,22 +416,39 @@ def week_view(
         elif group:
             persons_qs = persons_qs.filter(member_of=group)
         else:
-            persons_qs = persons_qs.filter(
-                Q(member_of__lessons__lesson_periods__in=lesson_periods_pk)
-                | Q(member_of__events__in=events_pk)
-                | Q(member_of__extra_lessons__in=extra_lessons_pk)
-            )
+            persons_qs = persons_qs.filter(member_of__in=groups)
 
         # Prefetch object permissions for persons and groups the persons are members of
         # because the object permissions are checked for both persons and groups
         checker = ObjectPermissionChecker(request.user)
-        checker.prefetch_perms(persons_qs)
-        checker.prefetch_perms(Group.objects.filter(members__in=persons_qs))
-
+        with catchtime():
+            print("Prefetch checker")
+            checker.prefetch_perms(persons_qs.prefetch_related(None))
+            checker.prefetch_perms(groups)
+
+        with catchtime():
+            print("personal notes")
+            prefetched_personal_notes = list(
+                PersonalNote.objects.filter(  #
+                    Q(event__in=events_pk)
+                    | Q(
+                        week=wanted_week.week,
+                        year=wanted_week.year,
+                        lesson_period__in=lesson_periods_pk,
+                    )
+                    | Q(extra_lesson__in=extra_lessons_pk)
+                ).filter(~Q(remarks=""))
+            )
         persons_qs = (
-            Person.objects.filter(pk__in=persons_qs)
-            .select_related("primary_group")
-            .prefetch_related("primary_group__owners")
+            persons_qs.select_related("primary_group")
+            .prefetch_related(
+                Prefetch(
+                    "primary_group__owners",
+                    queryset=Person.objects.filter(pk=request.user.person.pk),
+                    to_attr="owners_prefetched",
+                ),
+                Prefetch("member_of", queryset=groups, to_attr="member_of_prefetched"),
+            )
             .annotate(
                 filtered_personal_notes=FilteredRelation(
                     "personal_notes",
@@ -429,31 +463,8 @@ def week_view(
                     ),
                 )
             )
-            .prefetch_related(
-                Prefetch(
-                    "personal_notes",
-                    queryset=PersonalNote.objects.filter(
-                        Q(event__in=events_pk)
-                        | Q(
-                            week=wanted_week.week,
-                            year=wanted_week.year,
-                            lesson_period__in=lesson_periods_pk,
-                        )
-                        | Q(extra_lesson__in=extra_lessons_pk)
-                    ),
-                ),
-                "member_of__owners",
-            )
         )
 
-        # Annotate group roles
-        if show_group_roles:
-            persons_qs = persons_qs.prefetch_related(
-                Prefetch(
-                    "group_roles",
-                    queryset=GroupRoleAssignment.objects.in_week(wanted_week).for_group(group),
-                ),
-            )
         persons_qs = persons_qs.annotate(
             absences_count=Count(
                 "filtered_personal_notes", filter=Q(filtered_personal_notes__absent=True),
@@ -481,14 +492,22 @@ def week_view(
             )
 
         persons = []
+        with catchtime():
+            print("Persons")
+            persons_test = list(persons_qs)
         for person in persons_qs:
             personal_notes = []
-            for note in person.personal_notes.all():
+            for note in filter(lambda note: note.person_id == person.pk, prefetched_personal_notes):
                 if note.lesson_period:
                     note.lesson_period.annotate_week(wanted_week)
                 personal_notes.append(note)
             person.set_object_permission_checker(checker)
-            persons.append({"person": person, "personal_notes": personal_notes})
+            person_dict = {"person": person, "personal_notes": personal_notes}
+            if show_group_roles:
+                person_dict["group_roles"] = filter(
+                    lambda role: role.person_id == person.pk, group_roles_persons
+                )
+            persons.append(person_dict)
     else:
         persons = None
 
@@ -508,23 +527,27 @@ def week_view(
 
     regrouped_objects = {}
 
-    for register_object in list(lesson_periods) + list(extra_lessons):
-        register_object.weekday = register_object.period.weekday
-        regrouped_objects.setdefault(register_object.period.weekday, [])
-        regrouped_objects[register_object.period.weekday].append(register_object)
-
-    for event in events:
-        weekday_from = event.get_start_weekday(wanted_week)
-        weekday_to = event.get_end_weekday(wanted_week)
-
-        for weekday in range(weekday_from, weekday_to + 1):
-            # Make a copy in order to keep the annotation only on this weekday
-            event_copy = deepcopy(event)
-            event_copy.annotate_day(wanted_week[weekday])
-            event_copy.weekday = weekday
-
-            regrouped_objects.setdefault(weekday, [])
-            regrouped_objects[weekday].append(event_copy)
+    with catchtime():
+        print("Register objects")
+        for register_object in list(lesson_periods) + list(extra_lessons):
+            register_object.weekday = register_object.period.weekday
+            regrouped_objects.setdefault(register_object.period.weekday, [])
+            regrouped_objects[register_object.period.weekday].append(register_object)
+
+    with catchtime():
+        print("events")
+        for event in events:
+            weekday_from = event.get_start_weekday(wanted_week)
+            weekday_to = event.get_end_weekday(wanted_week)
+
+            for weekday in range(weekday_from, weekday_to + 1):
+                # Make a copy in order to keep the annotation only on this weekday
+                event_copy = deepcopy(event)
+                event_copy.annotate_day(wanted_week[weekday])
+                event_copy.weekday = weekday
+
+                regrouped_objects.setdefault(weekday, [])
+                regrouped_objects[weekday].append(event_copy)
 
     # Sort register objects
     for weekday in regrouped_objects.keys():