Improve performance of Projects::IssuesController#show so it's not terribly slow
Viewing issues is incredibly slow. Merge request !3855 (merged) finally moves the remaining use of Issue#referenced_merge_requests
/ Issue#related_branches
to a separate request meaning these methods are no longer used when IssuesController#show
itself is called. An early investigation shows quite a bit of time is spent in Issuable#subscribed_without_subscriptions?
which in turn triggers the Markdown pipeline to gather user references.
TODO
-
Find out what parts of the Markdown pipeline exactly are used when viewing issues (when applying the changes from !3855 (merged)) -
Find out how these parts perform on GitLab.com
This issue is mostly meant as a "journal" of what I'm working on so people can actually see that I'm working on this (instead of there suddenly being a patch after 5 days of silence). I'll be posting my thoughts/findings as comments as I go along.
Grafana dashboard for the controller in question (only available to GitLab employees): http://performance.gitlab.net/dashboard/db/rails-controllers?var-action=Projects%3A%3AIssuesController%23show
Banzai Filters
The following filters appear to run on my test issue:
Banzai::Filter::AbstractReferenceFilter
Banzai::Filter::AutolinkFilter
Banzai::Filter::EmojiFilter
Banzai::Filter::ExternalLinkFilter
Banzai::Filter::ImageLinkFilter
Banzai::Filter::RedactorFilter
Banzai::Filter::ReferenceFilter
Banzai::Filter::ReferenceGathererFilter
Banzai::Filter::RelativeLinkFilter
Banzai::Filter::SyntaxHighlightFilter
Banzai::Filter::TableOfContentsFilter
Banzai::Filter::UploadLinkFilter
Banzai::Filter::UserReferenceFilter
Since gathering references triggers a full render of every object (if not done so and cached already) this is not entirely surprising. This won't be a huge problem when we cache rendered HTML on database level and build these documents incrementally.
GitLab.com Timings
On GitLab.com the timings (in milliseconds) for the various Banzai classes/methods used in this controller are as following (in the last hour):
Method | Mean | 95th percentile | 99th percentile |
---|---|---|---|
Banzai::Filter::ReferenceFilter#ignore_ancestor_query |
56.56 | 223.53 | 297.87 |
Banzai::Filter::CommitRangeReferenceFilter.references_in |
98.65 | 221.78 | 221.78 |
Banzai::Querying.css |
42.68 | 197.27 | 303.27 |
Banzai::Filter::AbstractReferenceFilter#object_sym |
151.01 | 151.01 | 151.01 |
Banzai::Filter::AbstractReferenceFilter.object_sym |
81.0 | 150.99 | 150.99 |
Banzai::Filter::AbstractReferenceFilter.object_name |
150.92 | 150.92 | 150.92 |
Banzai::Filter::SyntaxHighlightFilter#highlight_node |
37.66 | 142.73 | 142.73 |
Banzai::Filter::LabelReferenceFilter.object_class |
139.35 | 139.35 | 139.35 |
Banzai::Filter::ReferenceFilter#project |
53.7 | 132.71 | 132.71 |
Banzai::Filter::UserReferenceFilter#call |
32.52 | 126.48 | 218.95 |
Banzai::Filter::UserReferenceFilter.referenced_by |
49.55 | 123.49 | 139.32 |
Banzai::Filter::ExternalLinkFilter#call |
28.85 | 117.69 | 228.62 |
Banzai::Filter::ReferenceFilter#replace_link_node_with_text |
39.66 | 113.89 | 115.82 |
Banzai::Filter::ReferenceGathererFilter#call |
40.15 | 112.67 | 254.58 |
Banzai::Filter::CommitReferenceFilter.references_in |
46.23 | 105.25 | 273.05 |
Banzai::Filter::CommitReferenceFilter#find_object |
44.68 | 103.93 | 272.9 |
Banzai::Filter::RedactorFilter#call |
34.11 | 102.02 | 376.81 |
Banzai::Filter::UploadLinkFilter#call |
46.74 | 101.68 | 491.8 |
Banzai::Filter::ReferenceFilter.user_can_see_reference? |
41.5 | 96.2 | 150.61 |
Banzai::Renderer.render_result |
33.01 | 93.21 | 227.11 |
Banzai::Filter::ReferenceFilter#each_node |
34.15 | 91.03 | 243.18 |
Banzai::Filter::CommitReferenceFilter.referenced_by |
38.68 | 90.87 | 195.13 |
Banzai::Filter::LabelReferenceFilter#references_in |
40.63 | 90.22 | 158.05 |
Banzai::Filter::CommitReferenceFilter.find_object |
37.93 | 89.12 | 174.42 |
Banzai::Filter::SyntaxHighlightFilter#call |
38.7 | 88.5 | 247.74 |
Banzai::Filter::AbstractReferenceFilter#project_from_ref_cache |
25.89 | 86.68 | 86.68 |
Banzai::Filter::ReferenceFilter#validate |
38.7 | 85.98 | 178.85 |
Banzai::Filter::AbstractReferenceFilter#call |
33.04 | 85.08 | 243.24 |
Banzai::Renderer.pre_process |
29.22 | 83.95 | 214.85 |
Banzai::Filter::AbstractReferenceFilter#object_link_filter |
38.52 | 83.79 | 256.19 |
Banzai::Filter::ExternalIssueReferenceFilter#default_issues_tracker? |
33.38 | 83.41 | 83.41 |
Banzai::Filter::AbstractReferenceFilter#find_object_cached |
36.45 | 83.38 | 256.06 |
Banzai::Filter::ReferenceFilter#replace_text_when_pattern_matches |
36.92 | 82.55 | 240.74 |
Banzai::Filter::AbstractReferenceFilter#references_in |
37.89 | 82.39 | 256.17 |
Banzai::Filter::ExternalIssueReferenceFilter#call |
29.99 | 80.24 | 83.45 |
Banzai::Renderer.cacheless_render |
29.57 | 76.52 | 208.2 |
Banzai::Filter::IssueReferenceFilter.user_can_see_reference? |
28.2 | 75.1 | 220.79 |
Banzai::Filter::UserReferenceFilter#user_link_filter |
23.4 | 71.26 | 79.87 |
Banzai::Filter::UserReferenceFilter.references_in |
23.3 | 71.21 | 79.8 |
Banzai::Renderer.render |
26.23 | 71.21 | 179.74 |
Banzai::Filter::ReferenceFilter#yield_valid_link |
31.73 | 71.08 | 222.42 |
Banzai::Renderer.post_process |
27.98 | 70.2 | 235.22 |
Banzai::Filter::AutolinkFilter#call |
31.64 | 66.44 | 347.83 |
Banzai::Filter::LabelReferenceFilter#find_label |
33.73 | 66.09 | 142.1 |
Banzai::Filter::AbstractReferenceFilter.references_in |
31.76 | 65.07 | 114.62 |
Banzai::Filter::UserReferenceFilter.user_can_see_reference? |
28.46 | 65.03 | 65.03 |
Banzai::Filter::CommitRangeReferenceFilter#find_object |
43.32 | 60.56 | 60.56 |
Banzai::Filter::CommitRangeReferenceFilter.find_object |
43.29 | 60.54 | 60.54 |
Banzai::Filter::IssueReferenceFilter#find_object |
21.2 | 60.41 | 118.38 |
Banzai::Renderer.full_cache_key |
31.17 | 59.81 | 59.81 |
Banzai::Filter::SnippetReferenceFilter#find_object |
22.85 | 59.35 | 112.27 |
Banzai::Filter::TableOfContentsFilter#call |
28.1 | 57.04 | 216.2 |
Banzai::Filter::ReferenceFilter#replace_link_node_with_href |
33.92 | 55.93 | 222.09 |
Banzai::Filter::RelativeLinkFilter#call |
23.83 | 53.52 | 145.46 |
Banzai::Filter::AbstractReferenceFilter#url_for_object_cached |
23.26 | 51.54 | 140.2 |
Banzai::Filter::MergeRequestReferenceFilter#find_object |
33.47 | 51.25 | 83.22 |
Banzai::Filter::IssueReferenceFilter#url_for_object |
24.13 | 51.09 | 140.12 |
Banzai::Filter::MilestoneReferenceFilter#find_object |
26.73 | 47.55 | 57.84 |
Banzai::Filter::UserReferenceFilter.user_can_reference? |
22.69 | 44.66 | 60.97 |
Banzai::Filter::EmojiFilter#call |
20.82 | 43.07 | 110.48 |
Banzai::Filter::EmojiFilter.emoji_pattern |
20.17 | 42.46 | 109.52 |
Banzai::Filter::EmojiFilter#emoji_image_filter |
18.29 | 37.99 | 77.11 |
Banzai::Filter::AbstractReferenceFilter#object_link_text |
24.16 | 32.3 | 105.52 |
Banzai::Filter::AbstractReferenceFilter.referenced_by |
17.17 | 29.29 | 29.29 |
Banzai::Filter::YamlFrontMatterFilter#call |
18.99 | 28.61 | 28.72 |
Banzai::Filter::AbstractReferenceFilter#object_class |
21.03 | 28.51 | 139.46 |
Banzai::Filter::CommitRangeReferenceFilter.object_class |
19.86 | 28.43 | 28.43 |
Banzai::Filter::MergeRequestReferenceFilter.object_class |
20.39 | 24.76 | 24.76 |
Banzai::Filter::ReferenceFilter#text_node? |
17.58 | 23.84 | 52.79 |
Banzai::Filter::LabelReferenceFilter#url_for_object |
14.46 | 20.67 | 20.67 |
Banzai::Filter::LabelReferenceFilter#find_object |
15.07 | 19.32 | 19.32 |
Banzai::Filter::SnippetReferenceFilter.object_class |
16.15 | 19.28 | 19.28 |
Banzai::Filter::SanitizationFilter#whitelist |
13.62 | 16.83 | 16.83 |
Banzai::Filter::ReferenceFilter#escape_once |
12.06 | 12.06 | 12.06 |
Banzai::Filter::MarkdownFilter#call |
11.48 | 11.48 | 11.48 |
Banzai::Filter::MarkdownFilter.renderer |
11.38 | 11.38 | 11.38 |