This issue has been created
There is 1 update, 1 comment.
 
 
XWiki Platform / cid:jira-generated-image-avatar-4e09a3b6-1eea-4566-a4a4-5e0333b4d599 XWIKI-23254 Open

Page loads are slow for users with many watched pages

 
View issue   ยท   Add comment
 

Issue created

 
cid:jira-generated-image-avatar-19adfd93-f1e0-468a-bfe8-0736d1dbeded Michael Hamann created this issue on 28/May/25 14:38
 
Summary: Page loads are slow for users with many watched pages
Issue Type: cid:jira-generated-image-avatar-4e09a3b6-1eea-4566-a4a4-5e0333b4d599 Bug
Affects Versions: 16.10.0
Assignee: Unassigned
Attachments: image-2025-05-28-14-30-38-913.png, image-2025-05-28-14-31-37-149.png
Components: Notifications
Created: 28/May/25 14:38
Labels: performance
Priority: cid:jira-generated-image-static-major-bc120531-2e6c-4628-89e1-80646a64b055 Major
Reporter: Michael Hamann
Description:

Steps to reproduce:

  1. Watch a lot of pages (thousands?)
  2. Load a page.

Expected result:

The page loads fast.

Actual result:

Loading the page takes long, like 15 seconds. The flame graph in Glowroot suggest that a lot of time is spent loading the watch status:

43692_image-2025-05-28-14-30-38-913.png

All of those traces end in one location - then constructor of ScopeNotificationFilterPreferencesHierarchy:

43691_image-2025-05-28-14-31-37-149.png

Checking the code shows that this is quadratic loop over scope notification preferences. The flame graph suggests that this is called several times per request, meaning that caching should bring quick benefits. Further, the code of isParent suggests that in addition to caching, there could be significant potential for optimizing this loop: only preferences that are exclusive can be parents, only preferences that are inclusive can be children. As it is very likely that a user won't have thousands of preferences of both types, a simple optimization should be to first filter the preferences by type and then only to compute parent-child relationships between those of different type.

 
 

1 update

 
cid:jira-generated-image-avatar-19adfd93-f1e0-468a-bfe8-0736d1dbeded Changes by Michael Hamann on 28/May/25 14:41
 
Description: *Steps to reproduce:*

# Watch a lot of pages (thousands?)
# Load a page.

*Expected result:*

The page loads fast.

*Actual result:*

Loading the page takes long, like 15 seconds. The flame graph in Glowroot suggest that a lot of time is spent loading the watch status:

!image-2025-05-28-14-30-38-913.png!

All of those traces end in one location -
then the constructor of {{ScopeNotificationFilterPreferencesHierarchy}}:

!image-2025-05-28-14-31-37-149.png!

Checking the [code|https://github.com/xwiki/xwiki-platform/blob/0497717cc64ab488520859e6fc70bbd2c50a0b9c/xwiki-platform-core/xwiki-platform-notifications/xwiki-platform-notifications-filters/xwiki-platform-notifications-filters-api/src/main/java/org/xwiki/notifications/filters/internal/scope/ScopeNotificationFilterPreferencesHierarchy.java#L44-L60] shows that this is quadratic loop over scope notification preferences. The flame graph suggests that this is called several times per request, meaning that caching should bring quick benefits. Further, the [code of {{isParent}}|https://github.com/xwiki/xwiki-platform/blob/b30ff5fa89e3ebaf0df17cfc3013a7c3bda1632c/xwiki-platform-core/xwiki-platform-notifications/xwiki-platform-notifications-filters/xwiki-platform-notifications-filters-api/src/main/java/org/xwiki/notifications/filters/internal/scope/ScopeNotificationFilterPreference.java#L115-L127] suggests that in addition to caching, there could be significant potential for optimizing this loop: only preferences that are exclusive can be parents, only preferences that are inclusive can be children. As it is very likely that a user won't have thousands of preferences of both types, a simple optimization should be to first filter the preferences by type and then only to compute parent-child relationships between those of different type.
 
 

1 comment

 
cid:jira-generated-image-avatar-acbd3027-44c2-44ec-97f5-a9e6404c14d1 Simon Urli on 28/May/25 14:46
 

, meaning that caching should bring quick benefits

Apparently I put a TODO here for caching the info but never implemented it