Performance improvements due to using chatElement instead of $('#chat'). (#4576) * Performance improvements due to using chatElement instead of $('#chat'). * Reverts change `hideSwipeButtons()` change. https://github.com/SillyTavern/SillyTavern/pull/4576#discussion_r2394996102 --------- Co-authored-by: user <user@exmaple.com>
Signed| @@ -1345,7 +1345,7 @@ export async function replaceCurrentChat() { | ||
| 1345 | 1345 | } |
| 1346 | 1346 | |
| 1347 | 1347 | export async function showMoreMessages(messagesToLoad = null) { |
| 1348 | 1348 | const firstDisplayedMesId = $('#chat')chatElement.children('.mes').first().attr('mesid'); |
| 1349 | 1349 | let messageId = Number(firstDisplayedMesId); |
| 1350 | 1350 | let count = messagesToLoad || power_user.chat_truncation || Number.MAX_SAFE_INTEGER; |
| 1351 | 1351 | |
| @@ -1356,7 +1356,7 @@ export async function showMoreMessages(messagesToLoad = null) { | ||
| 1356 | 1356 | } |
| 1357 | 1357 | |
| 1358 | 1358 | console.debug('Inserting messages before', messageId, 'count', count, 'chat length', chat.length); |
| 1359 | 1359 | const prevHeight = $('#chat')chatElement.prop('scrollHeight'); |
| 1360 | 1360 | const isButtonInView = isElementInViewport($('#show_more_messages')[0]); |
| 1361 | 1361 | |
| 1362 | 1362 | while (messageId > 0 && count > 0) { |
| @@ -1371,8 +1371,8 @@ export async function showMoreMessages(messagesToLoad = null) { | ||
| 1371 | 1371 | } |
| 1372 | 1372 | |
| 1373 | 1373 | if (isButtonInView) { |
| 1374 | 1374 | const newHeight = $('#chat')chatElement.prop('scrollHeight'); |
| 1375 | 1375 | $('#chat')chatElement.scrollTop(newHeight - prevHeight); |
| 1376 | 1376 | } |
| 1377 | 1377 | |
| 1378 | 1378 | applyStylePins(); |
| @@ -1385,7 +1385,7 @@ export async function printMessages() { | ||
| 1385 | 1385 | |
| 1386 | 1386 | if (chat.length > count) { |
| 1387 | 1387 | startIndex = chat.length - count; |
| 1388 | 1388 | $('#chat')chatElement.append('<div id="show_more_messages">Show more messages</div>'); |
| 1389 | 1389 | } |
| 1390 | 1390 | |
| 1391 | 1391 | for (let i = startIndex; i < chat.length; i++) { |
| @@ -1408,8 +1408,8 @@ export async function printMessages() { | ||
| 1408 | 1408 | } |
| 1409 | 1409 | } |
| 1410 | 1410 | |
| 1411 | 1411 | $chatElement.find('#chat .mes').removeClass('last_mes'); |
| 1412 | 1412 | $chatElement.find('#chat .mes').last().addClass('last_mes'); |
| 1413 | 1413 | hideSwipeButtons(); |
| 1414 | 1414 | showSwipeButtons(); |
| 1415 | 1415 | scrollChatToBottom(); |
| @@ -1442,7 +1442,7 @@ export async function clearChat() { | ||
| 1442 | 1442 | if (is_delete_mode) { |
| 1443 | 1443 | $('#dialogue_del_mes_cancel').trigger('click'); |
| 1444 | 1444 | } |
| 1445 | 1445 | $('#chat')chatElement.children().remove(); |
| 1446 | 1446 | if ($('.zoomed_avatar[forChar]').length) { |
| 1447 | 1447 | console.debug('saw avatars to remove'); |
| 1448 | 1448 | $('.zoomed_avatar[forChar]').remove(); |
| @@ -1454,7 +1454,7 @@ export async function clearChat() { | ||
| 1454 | 1454 | |
| 1455 | 1455 | export async function deleteLastMessage() { |
| 1456 | 1456 | chat.length = chat.length - 1; |
| 1457 | 1457 | $('#chat')chatElement.children('.mes').last().remove(); |
| 1458 | 1458 | await eventSource.emit(event_types.MESSAGE_DELETED, chat.length); |
| 1459 | 1459 | } |
| 1460 | 1460 | |
| @@ -1797,7 +1797,7 @@ function getMessageFromTemplate({ | ||
| 1797 | 1797 | * @param {boolean} [options.rerenderMessage=true] Whether to re-render the message content (inside <c>.mes_text</c>) |
| 1798 | 1798 | */ |
| 1799 | 1799 | export function updateMessageBlock(messageId, message, { rerenderMessage = true } = {}) { |
| 1800 | 1800 | const messageElement = $chatElement.find(`#chat [mesid="${messageId}"]`); |
| 1801 | 1801 | if (rerenderMessage) { |
| 1802 | 1802 | const text = message?.extra?.display_text ?? message.mes; |
| 1803 | 1803 | messageElement.find('.mes_text').html(messageFormatting(text, message.name, message.is_system, message.is_user, messageId, {}, false)); |
| @@ -1819,7 +1819,7 @@ export function appendMediaToMessage(mes, messageElement, adjustScroll = true) { | ||
| 1819 | 1819 | // Add image to message |
| 1820 | 1820 | if (mes.extra?.image) { |
| 1821 | 1821 | const container = messageElement.find('.mes_img_container'); |
| 1822 | 1822 | const chatHeight = $('#chat')chatElement.prop('scrollHeight'); |
| 1823 | 1823 | const image = messageElement.find('.mes_img'); |
| 1824 | 1824 | const text = messageElement.find('.mes_text'); |
| 1825 | 1825 | const isInline = !!mes.extra?.inline_image; |
| @@ -1827,10 +1827,10 @@ export function appendMediaToMessage(mes, messageElement, adjustScroll = true) { | ||
| 1827 | 1827 | if (!adjustScroll) { |
| 1828 | 1828 | return; |
| 1829 | 1829 | } |
| 1830 | 1830 | const scrollPosition = $('#chat')chatElement.scrollTop(); |
| 1831 | 1831 | const newChatHeight = $('#chat')chatElement.prop('scrollHeight'); |
| 1832 | 1832 | const diff = newChatHeight - chatHeight; |
| 1833 | 1833 | $('#chat')chatElement.scrollTop(scrollPosition + diff); |
| 1834 | 1834 | }; |
| 1835 | 1835 | image.off('load').on('load', function () { |
| 1836 | 1836 | image.removeAttr('alt'); |
| @@ -1877,16 +1877,16 @@ export function appendMediaToMessage(mes, messageElement, adjustScroll = true) { | ||
| 1877 | 1877 | const container = $('#message_video_template .mes_video_container').clone(); |
| 1878 | 1878 | messageElement.find('.mes_video_container').remove(); |
| 1879 | 1879 | messageElement.find('.mes_block').append(container); |
| 1880 | 1880 | const chatHeight = $('#chat')chatElement.prop('scrollHeight'); |
| 1881 | 1881 | const video = container.find('.mes_video'); |
| 1882 | 1882 | video.off('loadedmetadata').on('loadedmetadata', function () { |
| 1883 | 1883 | if (!adjustScroll) { |
| 1884 | 1884 | return; |
| 1885 | 1885 | } |
| 1886 | 1886 | const scrollPosition = $('#chat')chatElement.scrollTop(); |
| 1887 | 1887 | const newChatHeight = $('#chat')chatElement.prop('scrollHeight'); |
| 1888 | 1888 | const diff = newChatHeight - chatHeight; |
| 1889 | 1889 | $('#chat')chatElement.scrollTop(scrollPosition + diff); |
| 1890 | 1890 | }); |
| 1891 | 1891 | |
| 1892 | 1892 | video.attr('src', mes.extra?.video); |
| @@ -2041,7 +2041,7 @@ export function addOneMessage(mes, { type = 'normal', insertAfter = null, scroll | ||
| 2041 | 2041 | // Callers push the new message to chat before calling addOneMessage |
| 2042 | 2042 | const newMessageId = typeof forceId == 'number' ? forceId : chat.length - 1; |
| 2043 | 2043 | |
| 2044 | 2044 | const newMessage = $chatElement.find(`#chat [mesid="${newMessageId}"]`); |
| 2045 | 2045 | const isSmallSys = mes?.extra?.isSmallSys; |
| 2046 | 2046 | |
| 2047 | 2047 | if (isSmallSys === true) { |
| @@ -2103,8 +2103,8 @@ export function addOneMessage(mes, { type = 'normal', insertAfter = null, scroll | ||
| 2103 | 2103 | } |
| 2104 | 2104 | |
| 2105 | 2105 | if (showSwipes) { |
| 2106 | 2106 | $chatElement.find('#chat .mes').last().addClass('last_mes'); |
| 2107 | 2107 | $chatElement.find('#chat .mes').eq(-2).removeClass('last_mes'); |
| 2108 | 2108 | hideSwipeButtons(); |
| 2109 | 2109 | showSwipeButtons(); |
| 2110 | 2110 | } |
| @@ -2930,7 +2930,7 @@ class StreamingProcessor { | ||
| 2930 | 2930 | async onFinishStreaming(messageId, text) { |
| 2931 | 2931 | this.markUIGenStopped(); |
| 2932 | 2932 | await this.onProgressStreaming(messageId, text, true); |
| 2933 | 2933 | addCopyToCodeBlocks($chatElement.find(`#chat .mes[mesid="${messageId}"]`)); |
| 2934 | 2934 | |
| 2935 | 2935 | await this.reasoningHandler.finish(messageId); |
| 2936 | 2936 | |
| @@ -3358,7 +3358,7 @@ class TempResponseLength { | ||
| 3358 | 3358 | */ |
| 3359 | 3359 | function removeLastMessage() { |
| 3360 | 3360 | return new Promise((resolve) => { |
| 3361 | 3361 | const lastMes = $('#chat')chatElement.children('.mes').last(); |
| 3362 | 3362 | if (lastMes.length === 0) { |
| 3363 | 3363 | return resolve(); |
| 3364 | 3364 | } |
| @@ -5122,18 +5122,18 @@ export async function duplicateCharacter() { | ||
| 5122 | 5122 | } |
| 5123 | 5123 | |
| 5124 | 5124 | function setInContextMessages(msgInContextCount, type) { |
| 5125 | 5125 | $chatElement.find('#chat .mes').removeClass('lastInContext'); |
| 5126 | 5126 | |
| 5127 | 5127 | if (type === 'swipe' || type === 'regenerate' || type === 'continue') { |
| 5128 | 5128 | msgInContextCount++; |
| 5129 | 5129 | } |
| 5130 | 5130 | |
| 5131 | 5131 | const lastMessageBlock = $chatElement.find('#chat .mes:not([is_system="true"])').eq(-msgInContextCount); |
| 5132 | 5132 | lastMessageBlock.addClass('lastInContext'); |
| 5133 | 5133 | |
| 5134 | 5134 | if (lastMessageBlock.length === 0) { |
| 5135 | 5135 | const firstMessageId = getFirstDisplayedMessageId(); |
| 5136 | 5136 | $chatElement.find(`#chat .mes[mesid="${firstMessageId}"`).addClass('lastInContext'); |
| 5137 | 5137 | } |
| 5138 | 5138 | |
| 5139 | 5139 | // Update last id to chat. No metadata save on purpose, gets hopefully saved via another call |
| @@ -7848,7 +7848,7 @@ export function showSwipeButtons() { | ||
| 7848 | 7848 | }; |
| 7849 | 7849 | } |
| 7850 | 7850 | |
| 7851 | 7851 | const currentMessage = $('#chat')chatElement.children().filter(`[mesid="${chat.length - 1}"]`); |
| 7852 | 7852 | const swipeId = chat[chat.length - 1].swipe_id; |
| 7853 | 7853 | const swipeCounterText = formatSwipeCounter((swipeId + 1), chat[chat.length - 1].swipes.length); |
| 7854 | 7854 | const swipeRight = currentMessage.find('.swipe_right'); |
| @@ -7994,13 +7994,13 @@ async function importCharacterChat(formData, eventTarget) { | ||
| 7994 | 7994 | function updateViewMessageIds(startFromZero = false) { |
| 7995 | 7995 | const minId = startFromZero ? 0 : getFirstDisplayedMessageId(); |
| 7996 | 7996 | |
| 7997 | 7997 | $('#chat')chatElement.find('.mes').each(function (index, element) { |
| 7998 | 7998 | $(element).attr('mesid', minId + index); |
| 7999 | 7999 | $(element).find('.mesIDDisplay').text(`#${minId + index}`); |
| 8000 | 8000 | }); |
| 8001 | 8001 | |
| 8002 | 8002 | $chatElement.find('#chat .mes').removeClass('last_mes'); |
| 8003 | 8003 | $chatElement.find('#chat .mes').last().addClass('last_mes'); |
| 8004 | 8004 | |
| 8005 | 8005 | updateEditArrowClasses(); |
| 8006 | 8006 | } |
| @@ -8012,14 +8012,14 @@ export function getFirstDisplayedMessageId() { | ||
| 8012 | 8012 | } |
| 8013 | 8013 | |
| 8014 | 8014 | function updateEditArrowClasses() { |
| 8015 | 8015 | $chatElement.find('#chat .mes .mes_edit_up').removeClass('disabled'); |
| 8016 | 8016 | $chatElement.find('#chat .mes .mes_edit_down').removeClass('disabled'); |
| 8017 | 8017 | |
| 8018 | 8018 | if (this_edit_mes_id !== undefined) { |
| 8019 | 8019 | const down = $chatElement.find(`#chat .mes[mesid="${this_edit_mes_id}"] .mes_edit_down`); |
| 8020 | 8020 | const up = $chatElement.find(`#chat .mes[mesid="${this_edit_mes_id}"] .mes_edit_up`); |
| 8021 | 8021 | const lastId = Number($chatElement.find('#chat .mes').last().attr('mesid')); |
| 8022 | 8022 | const firstId = Number($chatElement.find('#chat .mes').first().attr('mesid')); |
| 8023 | 8023 | |
| 8024 | 8024 | if (lastId == Number(this_edit_mes_id)) { |
| 8025 | 8025 | down.addClass('disabled'); |
| @@ -8038,7 +8038,7 @@ function updateEditArrowClasses() { | ||
| 8038 | 8038 | export function closeMessageEditor(what = 'all') { |
| 8039 | 8039 | if (what === 'message' || what === 'all') { |
| 8040 | 8040 | if (this_edit_mes_id) { |
| 8041 | 8041 | $chatElement.find(`#chat .mes[mesid="${this_edit_mes_id}"] .mes_edit_cancel`).trigger('click'); |
| 8042 | 8042 | } |
| 8043 | 8043 | } |
| 8044 | 8044 | if (what === 'reasoning' || what === 'all') { |
| @@ -8713,10 +8713,10 @@ export function swipe_right(_event = null, { source, repeated } = {}) { | ||
| 8713 | 8713 | easing: animation_easing, |
| 8714 | 8714 | queue: false, |
| 8715 | 8715 | complete: async function () { |
| 8716 | 8716 | const is_animation_scroll = ($('#chat')chatElement.scrollTop() >= ($('#chat')chatElement.prop('scrollHeight') - $('#chat')chatElement.outerHeight()) - 10); |
| 8717 | 8717 | //console.log(parseInt(chat[chat.length-1]['swipe_id'])); |
| 8718 | 8718 | //console.log(chat[chat.length-1]['swipes'].length); |
| 8719 | 8719 | const swipeMessage = $('#chat')chatElement.find('[mesid="' + (chat.length - 1) + '"]'); |
| 8720 | 8720 | if (run_generate && parseInt(chat[chat.length - 1]['swipe_id']) === chat[chat.length - 1]['swipes'].length) { |
| 8721 | 8721 | //shows "..." while generating |
| 8722 | 8722 | swipeMessage.find('.mes_text').html('...'); |
| @@ -8749,12 +8749,12 @@ export function swipe_right(_event = null, { source, repeated } = {}) { | ||
| 8749 | 8749 | queue: false, |
| 8750 | 8750 | progress: function () { |
| 8751 | 8751 | // Scroll the chat down as the message expands |
| 8752 | 8752 | if (is_animation_scroll) $('#chat')chatElement.scrollTop($('#chat')chatElement[0].scrollHeight); |
| 8753 | 8753 | }, |
| 8754 | 8754 | complete: function () { |
| 8755 | 8755 | this_mes_div.css('height', 'auto'); |
| 8756 | 8756 | // Scroll the chat down to the bottom once the animation is complete |
| 8757 | 8757 | if (is_animation_scroll) $('#chat')chatElement.scrollTop($('#chat')chatElement[0].scrollHeight); |
| 8758 | 8758 | }, |
| 8759 | 8759 | }); |
| 8760 | 8760 | this_mes_div.children('.mes_block').transition({ |
| @@ -10066,15 +10066,15 @@ jQuery(async function () { | ||
| 10066 | 10066 | }); |
| 10067 | 10067 | |
| 10068 | 10068 | if (this_del_mes >= 0) { |
| 10069 | 10069 | $chatElement.find(`.mes[mesid="${this_del_mes}"]`).nextAll('div').remove(); |
| 10070 | 10070 | $chatElement.find(`.mes[mesid="${this_del_mes}"]`).remove(); |
| 10071 | 10071 | chat.length = this_del_mes; |
| 10072 | 10072 | chat_metadata['tainted'] = true; |
| 10073 | 10073 | await saveChatConditional(); |
| 10074 | 10074 | chatElement.scrollTop(chatElement[0].scrollHeight); |
| 10075 | 10075 | await eventSource.emit(event_types.MESSAGE_DELETED, chat.length); |
| 10076 | 10076 | $chatElement.find('#chat .mes').removeClass('last_mes'); |
| 10077 | 10077 | $chatElement.find('#chat .mes').last().addClass('last_mes'); |
| 10078 | 10078 | } else { |
| 10079 | 10079 | console.log('this_del_mes is not >= 0, not deleting'); |
| 10080 | 10080 | } |
| @@ -10179,9 +10179,9 @@ jQuery(async function () { | ||
| 10179 | 10179 | return; |
| 10180 | 10180 | }*/ |
| 10181 | 10181 | |
| 10182 | 10182 | let chatScrollPosition = $('#chat')chatElement.scrollTop(); |
| 10183 | 10183 | if (this_edit_mes_id !== undefined) { |
| 10184 | 10184 | let mes_edited = $chatElement.find(`#chat [mesid="${this_edit_mes_id}"]`).find('.mes_edit_done'); |
| 10185 | 10185 | if (Number(edit_mes_id) == chat.length - 1) { //if the generating swipe (...) |
| 10186 | 10186 | let run_edit = true; |
| 10187 | 10187 | if (chat[edit_mes_id]['swipe_id'] !== undefined) { |
| @@ -10240,7 +10240,7 @@ jQuery(async function () { | ||
| 10240 | 10240 | String(edit_textarea.val()).length, |
| 10241 | 10241 | ); |
| 10242 | 10242 | if (Number(this_edit_mes_id) === chat.length - 1) { |
| 10243 | 10243 | $('#chat')chatElement.scrollTop(chatScrollPosition); |
| 10244 | 10244 | } |
| 10245 | 10245 | |
| 10246 | 10246 | updateEditArrowClasses(); |
| @@ -10358,7 +10358,7 @@ jQuery(async function () { | ||
| 10358 | 10358 | |
| 10359 | 10359 | hideSwipeButtons(); |
| 10360 | 10360 | const targetId = Number(this_edit_mes_id) - 1; |
| 10361 | 10361 | const target = $chatElement.find(`#chat .mes[mesid="${targetId}"]`); |
| 10362 | 10362 | const root = $(this).closest('.mes'); |
| 10363 | 10363 | |
| 10364 | 10364 | if (root.length === 0 || target.length === 0) { |
| @@ -10387,7 +10387,7 @@ jQuery(async function () { | ||
| 10387 | 10387 | |
| 10388 | 10388 | hideSwipeButtons(); |
| 10389 | 10389 | const targetId = Number(this_edit_mes_id) + 1; |
| 10390 | 10390 | const target = $chatElement.find(`#chat .mes[mesid="${targetId}"]`); |
| 10391 | 10391 | const root = $(this).closest('.mes'); |
| 10392 | 10392 | |
| 10393 | 10393 | if (root.length === 0 || target.length === 0) { |
| @@ -10820,7 +10820,7 @@ jQuery(async function () { | ||
| 10820 | 10820 | return; |
| 10821 | 10821 | } |
| 10822 | 10822 | if (isEditVisible && power_user.auto_save_msg_edits === true) { |
| 10823 | 10823 | $chatElement.find(`#chat .mes[mesid="${this_edit_mes_id}"] .mes_edit_done`).trigger('click'); |
| 10824 | 10824 | closeMessageEditor('reasoning'); |
| 10825 | 10825 | $('#send_textarea').trigger('focus'); |
| 10826 | 10826 | return; |