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>

9415185a890f5a7cc9c13af78444f6daaef2ec71

DeclineThyself <FallenHaze@tutamail.com>

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