-
Suggestion
-
Resolution: Unresolved
-
None
-
None
Problem Definition
Files can be rendered in a Confluence page using different macros, such as the view-file or an internal link as described in Display Files and Images.
Rendering files within Confluence may be an expensive task specially depending on how many files a page needs to render. Confluence needs to run some tasks on the background before displaying the file in the UI.
Since these tasks are performed on the same thread that is loading the page, tasks associated to attachments may negatively contribute to the total time a page takes to load.
Suggested Solution
If we could perform all the backend processes from these macros asynchronously to the page loading, then it could decrease the time it takes to load the page.
Note that this would not decrease the total time to load the entire page, but would at least load the content and release the browser to the user while more heavy loading is occurring on the backend.
This is already in place for the Jira Issues macro and something similar could be implemented here.
Workaround
As a workaround, the Future Macro could be used, where available, to asynchronously load heavy content.
As an example, loading a sample page with 50 view-file macros took 997 ms on a vanilla instance:
2019-08-19 17:06:00,865 DEBUG [http-nio2-26154-exec-15] [atlassian.util.profiling.UtilTimerStack] log [997ms] - /localhost/display/TS/Target+Page [21ms] - UserAccessor.getExistingUserByKey() [3ms] - UserAccessor.getUserByName() [2ms] - CrowdService.getUser() [0ms] - ApplicationDAO.findByName() [1ms] - UserDao.findByName() [25ms] - PermissionManager.isSystemAdministrator() [0ms] - UserAccessor.isDeactivated() [15ms] - CrowdService.isUserMemberOfGroup() [0ms] - ApplicationDAO.findByName() [15ms] - MembershipDao.isUserDirectMember() [0ms] - UserAccessor.isDeactivated() [0ms] - CrowdService.isUserMemberOfGroup() [0ms] - ApplicationDAO.findByName() [0ms] - MembershipDao.isUserDirectMember() [0ms] - CrowdService.isUserMemberOfGroup() [0ms] - ApplicationDAO.findByName() [0ms] - MembershipDao.isUserDirectMember() [1ms] - DefaultSpacePermissionManager.hasPermissionNoExemptions(SYSTEMADMINISTRATOR, user001, global) [0ms] - CrowdService.isUserMemberOfGroup() [0ms] - ApplicationDAO.findByName() [0ms] - MembershipDao.isUserDirectMember() [1ms] - UserAccessor.getExistingUserByKey() [0ms] - UserAccessor.getUserByName() [0ms] - CrowdService.getUser() [0ms] - ApplicationDAO.findByName() [0ms] - UserDao.findByName() [0ms] - PermissionManager.isSystemAdministrator() [749ms] - XW Interceptor: Before defaultStack: /pages/viewpage.action (ViewPageAction.execute()) [0ms] - UserAccessor.exists() [0ms] - CrowdService.getUser() [0ms] - ApplicationDAO.findByName() [0ms] - UserDao.findByName() [0ms] - UserAccessor.getPropertySet() [0ms] - SpaceAwareInterceptor.intercept() [739ms] - PageAwareInterceptor.intercept() [30ms] - PageManager.getPageWithComments() [2ms] - PermissionManager.hasPermission() [2ms] - DefaultSpacePermissionManager.hasPermissionNoExemptions(VIEWSPACE, user001, TS) [0ms] - CrowdService.isUserMemberOfGroup() [0ms] - ApplicationDAO.findByName() [0ms] - MembershipDao.isUserDirectMember() [13ms] - PermissionManager.hasPermission() [0ms] - PermissionManager.hasPermission() [0ms] - CommentAwareInterceptor.intercept() [0ms] - UserAwareInterceptor.intercept() [0ms] - BootstrapAwareInterceptor.intercept() [0ms] - PermissionManager.hasPermission() [691ms] - XW Interceptor: After defaultStack: /pages/viewpage.action (ViewPageAction.execute()) [691ms] - XW Interceptor: After validatingStack: /pages/viewpage.action (ViewPageAction.execute()) [0ms] - UserAccessor.getPropertySet() [445ms] - DefaultRenderer.render [445ms] - DefaultRenderer.renderWithResult [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [1ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [2ms] - PageManager.getPage() [4ms] - PermissionManager.hasPermission() [2ms] - CommentManager.countUnresolvedComments() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - PageManager.getPage() [0ms] - PermissionManager.hasPermission() [2ms] - CommentManager.countUnresolvedComments() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - PageManager.getPage() [0ms] - PermissionManager.hasPermission() [2ms] - CommentManager.countUnresolvedComments() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - PageManager.getPage() [0ms] - PermissionManager.hasPermission() [2ms] - CommentManager.countUnresolvedComments() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [1ms] - PageManager.getPage() [0ms] - PermissionManager.hasPermission() [2ms] - CommentManager.countUnresolvedComments() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - PageManager.getPage() [0ms] - PermissionManager.hasPermission() [3ms] - CommentManager.countUnresolvedComments() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - PageManager.getPage() (...)
The same page took 412 ms to load when all the files are loaded from a single Future macro, giving the user a feeling the page is loading faster while another background job loads the files.
2019-08-19 17:10:14,634 DEBUG [http-nio2-26154-exec-20] [atlassian.util.profiling.UtilTimerStack] log [412ms] - /localhost/display/TS/Target+Page [0ms] - UserAccessor.getExistingUserByKey() [0ms] - UserAccessor.getUserByName() [0ms] - CrowdService.getUser() [0ms] - ApplicationDAO.findByName() [0ms] - UserDao.findByName() [0ms] - PermissionManager.isSystemAdministrator() [0ms] - UserAccessor.isDeactivated() [0ms] - CrowdService.isUserMemberOfGroup() [0ms] - ApplicationDAO.findByName() [0ms] - MembershipDao.isUserDirectMember() (...) 2019-08-19 17:10:16,382 DEBUG [http-nio2-26154-exec-15] [atlassian.util.profiling.UtilTimerStack] log [502ms] - /localhost/plugins/servlet/futureRenderer [1ms] - UserAccessor.getExistingUserByKey() [0ms] - PermissionManager.isSystemAdministrator() [0ms] - UserAccessor.isDeactivated() [0ms] - CrowdService.getUser() [0ms] - ApplicationDAO.findByName() [0ms] - UserDao.findByName() [0ms] - CrowdService.isUserMemberOfGroup() [0ms] - ApplicationDAO.findByName() [0ms] - MembershipDao.isUserDirectMember() [0ms] - UserAccessor.isDeactivated() [0ms] - CrowdService.isUserMemberOfGroup() [0ms] - ApplicationDAO.findByName() [0ms] - MembershipDao.isUserDirectMember() [0ms] - CrowdService.isUserMemberOfGroup() [0ms] - ApplicationDAO.findByName() [0ms] - MembershipDao.isUserDirectMember() [0ms] - DefaultSpacePermissionManager.hasPermissionNoExemptions(SYSTEMADMINISTRATOR, user001, global) [0ms] - CrowdService.isUserMemberOfGroup() [0ms] - ApplicationDAO.findByName() [0ms] - MembershipDao.isUserDirectMember() [4ms] - ContentEntityManager.getById() [1ms] - PermissionManager.hasPermission() [0ms] - DefaultSpacePermissionManager.hasPermissionNoExemptions(VIEWSPACE, user001, TS) [0ms] - CrowdService.isUserMemberOfGroup() [0ms] - ApplicationDAO.findByName() [0ms] - MembershipDao.isUserDirectMember() [466ms] - DefaultRenderer.render [466ms] - DefaultRenderer.renderWithResult [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [2ms] - PageManager.getPage() [12ms] - PermissionManager.hasPermission() [3ms] - CommentManager.countUnresolvedComments() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - PageManager.getPage() [0ms] - PermissionManager.hasPermission() [5ms] - CommentManager.countUnresolvedComments() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - UserAccessor.getPropertySet() [0ms] - PageManager.getPage() (...)
- relates to
-
CONFSERVER-58733 Loading a page with links to multiple attachments from the same source page makes Confluence to check for permissions on every link instead of just once
- Gathering Impact