Fixes #7: Rendering performance optimizations
- requestAnimationFrame batching: rerenderRpgState() now batches all render calls into a single animation frame, reducing reflow/repaint costs - Lightweight change detection: Render functions use updateIfChanged() to skip DOM updates when content hasn't changed, and only re-bind event handlers when the DOM was actually updated - CSS content-visibility: Added content-visibility: auto with contain-intrinsic-size to inventory and equipment containers, deferring rendering of off-screen content New file: src/systems/rendering/renderUtils.js (rendering utilities module) Updated: All render modules + sillytavern.js integration + style.css
This commit is contained in:
@@ -5,25 +5,16 @@
|
||||
|
||||
import { getContext } from '../../../../../../extensions.js';
|
||||
import { user_avatar } from '../../../../../../../script.js';
|
||||
import {
|
||||
extensionSettings,
|
||||
lastGeneratedData,
|
||||
committedTrackerData,
|
||||
$userStatsContainer,
|
||||
FALLBACK_AVATAR_DATA_URI
|
||||
} from '../../core/state.js';
|
||||
import { extensionSettings, lastGeneratedData, committedTrackerData, $userStatsContainer, FALLBACK_AVATAR_DATA_URI } from '../../core/state.js';
|
||||
import { i18n } from '../../core/i18n.js';
|
||||
import {
|
||||
saveSettings,
|
||||
saveChatData,
|
||||
updateMessageSwipeData
|
||||
} from '../../core/persistence.js';
|
||||
import { saveSettings, saveChatData, updateMessageSwipeData } from '../../core/persistence.js';
|
||||
import { getSafeThumbnailUrl } from '../../utils/avatars.js';
|
||||
import { buildInventorySummary } from '../generation/promptBuilder.js';
|
||||
import { isItemLocked, setItemLock } from '../generation/lockManager.js';
|
||||
import { updateFabWidgets } from '../ui/mobile.js';
|
||||
import { getStatBarColors } from '../ui/theme.js';
|
||||
import { getEquipmentBonuses } from '../interaction/equipmentActions.js';
|
||||
import { updateIfChanged } from './renderUtils.js';
|
||||
|
||||
/**
|
||||
* Extracts the base name (before parentheses) and converts to snake_case for use as JSON key.
|
||||
@@ -449,10 +440,12 @@ export function renderUserStats() {
|
||||
// console.log('[RPG UserStats Render] Container exists:', !!$userStatsContainer, '$userStatsContainer length:', $userStatsContainer?.length);
|
||||
|
||||
// Always render to the #rpg-user-stats container (mobile layout just moves it around in DOM)
|
||||
$userStatsContainer.html(html);
|
||||
// console.log('[RPG UserStats Render] ✓ HTML rendered to #rpg-user-stats container');
|
||||
// Use change detection to skip unnecessary DOM updates
|
||||
const domUpdated = updateIfChanged($userStatsContainer, html, 'rpg-user-stats');
|
||||
// console.log('[RPG UserStats Render] ✓ HTML rendered to #rpg-user-stats container, updated:', domUpdated);
|
||||
|
||||
// Add event listeners for editable stat values
|
||||
// Only re-bind event listeners if DOM was actually updated
|
||||
if (domUpdated) {
|
||||
$('.rpg-editable-stat').on('blur', function () {
|
||||
const field = $(this).data('field');
|
||||
const mode = $(this).data('mode');
|
||||
@@ -609,4 +602,5 @@ export function renderUserStats() {
|
||||
// Save settings
|
||||
saveSettings();
|
||||
});
|
||||
} // end if (domUpdated)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user