diff options
author | Fatih Acet <acetfatih@gmail.com> | 2017-09-22 09:49:00 +0000 |
---|---|---|
committer | Fatih Acet <acetfatih@gmail.com> | 2017-09-22 09:49:00 +0000 |
commit | 3446262169c08565ce68962a0138fb58dcecbb51 (patch) | |
tree | f32b295dfb08620ffd2f548e0250e05cd6d5b169 /app | |
parent | c8e60d6301bf725c94cac062c05e8abd4d1b7111 (diff) | |
parent | 014bbe6562d7feb374f7c1eaa14846bb56f7c2a6 (diff) | |
download | gitlab-ce-3446262169c08565ce68962a0138fb58dcecbb51.tar.gz |
Merge branch 'emoji-dom-size' into 'master'
Improve emoji menu rendering performance
Closes #36949
See merge request gitlab-org/gitlab-ce!14233
Diffstat (limited to 'app')
-rw-r--r-- | app/assets/javascripts/awards_handler.js | 44 | ||||
-rw-r--r-- | app/assets/stylesheets/framework/awards.scss | 5 |
2 files changed, 43 insertions, 6 deletions
diff --git a/app/assets/javascripts/awards_handler.js b/app/assets/javascripts/awards_handler.js index ec5be8664b2..4f01345ee3b 100644 --- a/app/assets/javascripts/awards_handler.js +++ b/app/assets/javascripts/awards_handler.js @@ -24,6 +24,9 @@ const categoryLabelMap = { flags: 'Flags', }; +const IS_VISIBLE = 'is-visible'; +const IS_RENDERED = 'is-rendered'; + class AwardsHandler { constructor(emoji) { this.emoji = emoji; @@ -51,7 +54,7 @@ class AwardsHandler { if (!$target.closest('.emoji-menu').length) { if ($('.emoji-menu').is(':visible')) { $('.js-add-award.is-active').removeClass('is-active'); - $('.emoji-menu').removeClass('is-visible'); + this.hideMenuElement($('.emoji-menu')); } } }); @@ -88,12 +91,12 @@ class AwardsHandler { if ($menu.length) { if ($menu.is('.is-visible')) { $addBtn.removeClass('is-active'); - $menu.removeClass('is-visible'); + this.hideMenuElement($menu); $('.js-emoji-menu-search').blur(); } else { $addBtn.addClass('is-active'); this.positionMenu($menu, $addBtn); - $menu.addClass('is-visible'); + this.showMenuElement($menu); $('.js-emoji-menu-search').focus(); } } else { @@ -103,7 +106,7 @@ class AwardsHandler { $addBtn.removeClass('is-loading'); this.positionMenu($createdMenu, $addBtn); return setTimeout(() => { - $createdMenu.addClass('is-visible'); + this.showMenuElement($createdMenu); $('.js-emoji-menu-search').focus(); }, 200); }); @@ -241,7 +244,8 @@ class AwardsHandler { if (isInIssuePage() && !isMainAwardsBlock) { const id = votesBlock.attr('id').replace('note_', ''); - $('.emoji-menu').removeClass('is-visible'); + this.hideMenuElement($('.emoji-menu')); + $('.js-add-award.is-active').removeClass('is-active'); const toggleAwardEvent = new CustomEvent('toggleAward', { detail: { @@ -261,7 +265,8 @@ class AwardsHandler { return typeof callback === 'function' ? callback() : undefined; }); - $('.emoji-menu').removeClass('is-visible'); + this.hideMenuElement($('.emoji-menu')); + return $('.js-add-award.is-active').removeClass('is-active'); } @@ -529,6 +534,33 @@ class AwardsHandler { return $matchingElements.closest('li').clone(); } + /* showMenuElement and hideMenuElement are performance optimizations. We use + * opacity to show/hide the emoji menu, because we can animate it. But opacity + * leaves hidden elements in the render tree, which is unacceptable given the number + * of emoji elements in the emoji menu (5k+). To get the best of both worlds, we separately + * apply IS_RENDERED to add/remove the menu from the render tree and IS_VISIBLE to animate + * the menu being opened and closed. */ + + showMenuElement($emojiMenu) { + $emojiMenu.addClass(IS_RENDERED); + + // enqueues animation as a microtask, so it begins ASAP once IS_RENDERED added + return Promise.resolve() + .then(() => $emojiMenu.addClass(IS_VISIBLE)); + } + + hideMenuElement($emojiMenu) { + $emojiMenu.on(transitionEndEventString, (e) => { + if (e.currentTarget === e.target) { + $emojiMenu + .removeClass(IS_RENDERED) + .off(transitionEndEventString); + } + }); + + $emojiMenu.removeClass(IS_VISIBLE); + } + destroy() { this.eventListeners.forEach((entry) => { entry.element.off.call(entry.element, ...entry.args); diff --git a/app/assets/stylesheets/framework/awards.scss b/app/assets/stylesheets/framework/awards.scss index bb30da4f4b2..e0d2ed80de5 100644 --- a/app/assets/stylesheets/framework/awards.scss +++ b/app/assets/stylesheets/framework/awards.scss @@ -9,6 +9,7 @@ } .emoji-menu { + display: none; position: absolute; top: 0; margin-top: 3px; @@ -27,6 +28,10 @@ transition: .3s cubic-bezier(.67, .06, .19, 1.44); transition-property: transform, opacity; + &.is-rendered { + display: block; + } + &.is-aligned-right { transform-origin: 100% -45px; } |