refactor(files): simplify file event processing logic
Remove redundant checks for deleted paths and streamline binary file handling. This fixes the browser using excessive memory and freezing. Improve DiffView to use a singleton instance of Shiki
This commit is contained in:
@@ -542,8 +542,53 @@ const FileInfo = memo(
|
||||
},
|
||||
);
|
||||
|
||||
// Create and manage a single highlighter instance at the module level
|
||||
let highlighterInstance: any = null;
|
||||
let highlighterPromise: Promise<any> | null = null;
|
||||
|
||||
const getSharedHighlighter = async () => {
|
||||
if (highlighterInstance) {
|
||||
return highlighterInstance;
|
||||
}
|
||||
|
||||
if (highlighterPromise) {
|
||||
return highlighterPromise;
|
||||
}
|
||||
|
||||
highlighterPromise = getHighlighter({
|
||||
themes: ['github-dark', 'github-light'],
|
||||
langs: [
|
||||
'typescript',
|
||||
'javascript',
|
||||
'json',
|
||||
'html',
|
||||
'css',
|
||||
'jsx',
|
||||
'tsx',
|
||||
'python',
|
||||
'php',
|
||||
'java',
|
||||
'c',
|
||||
'cpp',
|
||||
'csharp',
|
||||
'go',
|
||||
'ruby',
|
||||
'rust',
|
||||
'plaintext',
|
||||
],
|
||||
});
|
||||
|
||||
highlighterInstance = await highlighterPromise;
|
||||
highlighterPromise = null;
|
||||
|
||||
// Clear the promise once resolved
|
||||
return highlighterInstance;
|
||||
};
|
||||
|
||||
const InlineDiffComparison = memo(({ beforeCode, afterCode, filename, language }: CodeComparisonProps) => {
|
||||
const [isFullscreen, setIsFullscreen] = useState(false);
|
||||
|
||||
// Use state to hold the shared highlighter instance
|
||||
const [highlighter, setHighlighter] = useState<any>(null);
|
||||
const theme = useStore(themeStore);
|
||||
|
||||
@@ -554,34 +599,32 @@ const InlineDiffComparison = memo(({ beforeCode, afterCode, filename, language }
|
||||
const { unifiedBlocks, hasChanges, isBinary, error } = useProcessChanges(beforeCode, afterCode);
|
||||
|
||||
useEffect(() => {
|
||||
getHighlighter({
|
||||
themes: ['github-dark', 'github-light'],
|
||||
langs: [
|
||||
'typescript',
|
||||
'javascript',
|
||||
'json',
|
||||
'html',
|
||||
'css',
|
||||
'jsx',
|
||||
'tsx',
|
||||
'python',
|
||||
'php',
|
||||
'java',
|
||||
'c',
|
||||
'cpp',
|
||||
'csharp',
|
||||
'go',
|
||||
'ruby',
|
||||
'rust',
|
||||
'plaintext',
|
||||
],
|
||||
}).then(setHighlighter);
|
||||
}, []);
|
||||
// Fetch the shared highlighter instance
|
||||
getSharedHighlighter().then(setHighlighter);
|
||||
|
||||
/*
|
||||
* No cleanup needed here for the highlighter instance itself,
|
||||
* as it's managed globally. Shiki instances don't typically
|
||||
* need disposal unless you are dynamically loading/unloading themes/languages.
|
||||
* If you were dynamically loading, you might need a more complex
|
||||
* shared instance manager with reference counting or similar.
|
||||
* For static themes/langs, a single instance is sufficient.
|
||||
*/
|
||||
}, []); // Empty dependency array ensures this runs only once on mount
|
||||
|
||||
if (isBinary || error) {
|
||||
return renderContentWarning(isBinary ? 'binary' : 'error');
|
||||
}
|
||||
|
||||
// Render a loading state or null while highlighter is not ready
|
||||
if (!highlighter) {
|
||||
return (
|
||||
<div className="h-full flex items-center justify-center">
|
||||
<div className="text-bolt-elements-textTertiary">Loading diff...</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<FullscreenOverlay isFullscreen={isFullscreen}>
|
||||
<div className="w-full h-full flex flex-col">
|
||||
@@ -602,7 +645,7 @@ const InlineDiffComparison = memo(({ beforeCode, afterCode, filename, language }
|
||||
lineNumber={block.lineNumber}
|
||||
content={block.content}
|
||||
type={block.type}
|
||||
highlighter={highlighter}
|
||||
highlighter={highlighter} // Pass the shared instance
|
||||
language={language}
|
||||
block={block}
|
||||
theme={theme}
|
||||
|
||||
Reference in New Issue
Block a user