Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apply incremental dom update #397

Merged
merged 3 commits into from
Nov 3, 2024
Merged

Apply incremental dom update #397

merged 3 commits into from
Nov 3, 2024

Conversation

blurfx
Copy link
Member

@blurfx blurfx commented Nov 2, 2024

What this PR does / why we need it:

Apply incremental DOM update to re-render only the DOM of the parts that have changed, rather than re-rendering all.

Which issue(s) this PR fixes:

Fixes #393

Special notes for your reviewer:

This PR only cares about the performance of DOM updates in markdown rendering process. I think incremental parsing is a more complicated problem, so it would be nice to have a separate discussion on that later.

Does this PR introduce a user-facing change?:

Maybe, Yes.

To apply the Incremental DOM Update, I changed the markdown renderer library from `remark` to `markdown-it`.
Also, markdown library's plugins are replaced that do the same thing as used before, but the rendering results or behavior may be different.

so, action required: We have to check.

Additional documentation:


Checklist:

  • Added relevant tests or not required
  • Didn't break anything

Summary by CodeRabbit

  • New Features

    • Enhanced markdown rendering capabilities with new libraries for improved syntax highlighting and math rendering.
    • Introduced responsive CSS styles for markdown previews, accommodating both light and dark themes.
  • Bug Fixes

    • Corrected subscription logic in the preview component.
  • Style

    • Comprehensive styling updates for markdown elements, ensuring better readability and aesthetics across themes.
    • Improved visual presentation of syntax-highlighted code and markdown elements.

@blurfx blurfx self-assigned this Nov 2, 2024
Copy link
Contributor

coderabbitai bot commented Nov 2, 2024

Walkthrough

The changes in this pull request primarily involve modifications to the package.json, Preview.tsx, and preview.css files within the @codepair/frontend project. The package.json file has seen updates in dependencies, focusing on markdown processing libraries. The Preview.tsx component has been restructured to utilize new libraries for rendering markdown, while the preview.css file introduces styles for dark and light themes. These changes aim to enhance the functionality and visual presentation of markdown content.

Changes

File Change Summary
frontend/package.json Removed @uiw/codemirror-themes; added several markdown-related dependencies and type definitions.
frontend/src/components/editor/Preview.tsx Refactored Preview component to use new markdown libraries and rendering methods; corrected unsubscribe logic.
frontend/src/components/editor/preview.css Added comprehensive CSS styles for markdown preview, supporting dark and light themes with responsive design.

Assessment against linked issues

Objective Addressed Explanation
Improve rendering performance during large document editing (393) It is unclear if the changes implement rendering optimization or incremental parsing as suggested.

Possibly related PRs

Suggested labels

enhancement 🌟

Suggested reviewers

  • devleejb

Poem

In the garden of code, we hop and play,
With markdown magic, brightening the day.
New styles and functions, oh what a sight,
Rendering dreams in dark and light!
So let's cheer for the changes, both bold and bright,
For a smoother preview, our hearts take flight! 🐇✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🧹 Outside diff range and nitpick comments (3)
frontend/package.json (1)

42-42: Consider implementing dependency monitoring

Given the significant number of new markdown-related dependencies, consider:

  1. Setting up dependency monitoring for security updates
  2. Adding a package.json comment documenting the purpose of each markdown-related package
  3. Creating an upgrade strategy document for these interconnected packages

Consider adding a comment block at the top of package.json:

+ /**
+  * Markdown Processing Dependencies:
+  * - markdown-it: Core markdown parser
+  * - markdown-it-incremental-dom: Enables incremental DOM updates
+  * - markdown-it-sanitizer: Security sanitization
+  * - markdown-it-prism: Syntax highlighting
+  * - @vscode/markdown-it-katex: Math formula rendering
+  */

Also applies to: 89-89

frontend/src/components/editor/preview.css (2)

1-111: Consider adding fallback values for CSS custom properties.

The theme implementation is comprehensive, but browser compatibility could be improved by adding fallback values to CSS custom properties.

Example modification:

- --color-fg-default: #c9d1d9;
+ --color-fg-default: #c9d1d9; /* Add fallback */
+ color: #c9d1d9;
+ color: var(--color-fg-default, #c9d1d9);

302-302: Remove duplicate font names in font-family declarations.

The static analysis tool correctly identified redundant font names in the font-family declarations.

Remove duplicate font names:

-  font-family: monospace, monospace;
+  font-family: monospace;

-  font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace;
+  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, Liberation Mono, monospace;

Also applies to: 425-425, 471-471, 564-564, 577-577

🧰 Tools
🪛 Biome

[error] 302-302: Duplicate font names are redundant and unnecessary: monospace

Remove duplicate font names within the property

(lint/suspicious/noDuplicateFontNames)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 20a84cf and 6d4b753.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • frontend/package.json (4 hunks)
  • frontend/src/components/editor/Preview.tsx (2 hunks)
  • frontend/src/components/editor/preview.css (1 hunks)
🧰 Additional context used
🪛 GitHub Check: Check the source code (18.x)
frontend/src/components/editor/Preview.tsx

[warning] 72-72:
React Hook useEffect has an unnecessary dependency: 'md'. Either exclude it or remove the dependency array. Outer scope values like 'md' aren't valid dependencies because mutating them doesn't re-render the component

🪛 Biome
frontend/src/components/editor/preview.css

[error] 302-302: Duplicate font names are redundant and unnecessary: monospace

Remove duplicate font names within the property

(lint/suspicious/noDuplicateFontNames)


[error] 425-425: Duplicate font names are redundant and unnecessary: Mono

Remove duplicate font names within the property

(lint/suspicious/noDuplicateFontNames)


[error] 471-471: Duplicate font names are redundant and unnecessary: Mono

Remove duplicate font names within the property

(lint/suspicious/noDuplicateFontNames)


[error] 564-564: Duplicate font names are redundant and unnecessary: Mono

Remove duplicate font names within the property

(lint/suspicious/noDuplicateFontNames)


[error] 577-577: Duplicate font names are redundant and unnecessary: Mono

Remove duplicate font names within the property

(lint/suspicious/noDuplicateFontNames)

🔇 Additional comments (4)
frontend/package.json (3)

57-60: LGTM: Comprehensive markdown-it setup with security considerations

The markdown-it ecosystem setup includes all necessary components for secure and feature-rich markdown rendering, including sanitization, syntax highlighting, and math support.


52-52: LGTM: Supporting utilities are properly configured

The additional utilities (hast-util-to-html and refractor) are appropriate choices for HTML generation and syntax highlighting support.

Also applies to: 79-79


53-53: Verify incremental-dom integration and performance

The incremental-dom setup looks correct, but since this is a major architectural change, we should verify:

  1. Performance improvements with large documents
  2. Memory usage patterns
  3. Compatibility with existing features

Also applies to: 58-58

✅ Verification successful

Incremental-DOM integration appears well-implemented

The implementation in Preview.tsx shows:

  • Correct setup with markdown-it and incremental-dom integration
  • Proper patch/render cycle in useEffect
  • Content updates handled efficiently with subscriptions
  • Appropriate sanitization and security measures in place

The integration follows best practices:

  • Uses incremental DOM's patch mechanism for efficient updates
  • Properly disposes subscriptions on unmount
  • Includes necessary security plugins (markdown-it-sanitizer)
  • Handles loading states gracefully
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if there are any known issues or breaking changes with incremental-dom
gh search issues "incremental-dom breaking changes" --repo google/incremental-dom
gh search issues "markdown-it-incremental-dom performance" --repo yhatt/markdown-it-incremental-dom

Length of output: 185


Script:

#!/bin/bash
# Let's check for actual usage of incremental-dom in the codebase
rg -l "incremental-dom" --type js --type ts

# Check for any performance-related code or benchmarks
rg -l "performance|benchmark" --type js --type ts

# Look for DOM manipulation patterns
ast-grep --pattern 'import $_ from "incremental-dom"'

# Check for markdown-it integration
rg -l "markdown-it-incremental-dom" --type js --type ts

Length of output: 411


Script:

#!/bin/bash
# Let's examine the actual implementation in Preview.tsx
cat frontend/src/components/editor/Preview.tsx

# Check if there are any test files related to Preview
fd "Preview.test" --type f

# Look for any error handling related to incremental-dom
rg "error|catch" frontend/src/components/editor/Preview.tsx

Length of output: 2676

frontend/src/components/editor/Preview.tsx (1)

33-35: ⚠️ Potential issue

Verify sanitizer configuration to prevent XSS vulnerabilities

Enabling html: true in the MarkdownIt configuration allows HTML content, which could introduce XSS risks. Ensure that markdown-it-sanitizer is properly configured to sanitize all potentially malicious input.

Please review the configuration and adjust if necessary to enhance security.

frontend/src/components/editor/preview.css Show resolved Hide resolved
frontend/src/components/editor/preview.css Show resolved Hide resolved
frontend/src/components/editor/preview.css Show resolved Hide resolved
frontend/src/components/editor/Preview.tsx Show resolved Hide resolved
frontend/src/components/editor/Preview.tsx Show resolved Hide resolved
frontend/src/components/editor/Preview.tsx Show resolved Hide resolved
frontend/src/components/editor/Preview.tsx Outdated Show resolved Hide resolved
frontend/src/components/editor/Preview.tsx Outdated Show resolved Hide resolved
@blurfx blurfx force-pushed the feat/incremental-dom-update branch from 6e4c465 to 020c12d Compare November 2, 2024 18:23
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (3)
frontend/src/components/editor/Preview.tsx (3)

19-19: Replace require() with ES6 import

Using require() in TypeScript/ES6 code is not recommended. Consider converting to an ES6 import statement.

-const IncrementalDOM = require("incremental-dom");
+import * as IncrementalDOM from "incremental-dom";

30-31: Improve type safety in highlight function

Instead of using any, consider creating a proper type for the refractor highlight result.

-refractor.highlight(code, lang) as any
+refractor.highlight(code, lang) as Root

Add this type import at the top:

import type { Root } from 'hast';

23-41: Consider adding comprehensive test coverage

The new markdown-it with incremental DOM implementation is a significant change that warrants thorough testing.

Consider adding the following types of tests:

  1. Unit tests for markdown rendering with different content types
  2. Integration tests for the incremental update behavior
  3. Performance tests comparing with the previous implementation
  4. Edge case tests for very large documents and concurrent updates

Would you like me to help create a testing strategy document or generate test templates?

Also applies to: 70-78

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 6d4b753 and 020c12d.

📒 Files selected for processing (1)
  • frontend/src/components/editor/Preview.tsx (2 hunks)
🔇 Additional comments (2)
frontend/src/components/editor/Preview.tsx (2)

Line range hint 43-67: LGTM! Clean implementation with proper cleanup

The component structure follows React best practices with proper state management and cleanup in the useEffect hook.


70-78: Verify performance improvements with incremental DOM

While the implementation looks correct, we should verify that it actually improves performance for large documents as intended.

Consider adding performance benchmarks to measure:

  1. Time to first render for large documents
  2. Update latency during collaborative editing
  3. Memory usage comparison with the previous implementation

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (4)
frontend/src/components/editor/Preview.tsx (3)

29-31: Improve type safety in highlight function

Instead of using any, consider creating a proper type for the refractor output.

type RefractorNode = {
  type: string;
  children?: RefractorNode[];
  value?: string;
  properties?: Record<string, unknown>;
};

Then replace the type assertion:

-refractor.highlight(code, lang) as any
+refractor.highlight(code, lang) as RefractorNode

38-40: Document incremental DOM configuration

Setting incrementalizeDefaultRules: false needs documentation explaining why default rules are disabled and potential implications.

Add a comment explaining the configuration:

 .use(markdownItIncrementalDOM, IncrementalDOM, {
+  // Disable default rule incrementalization to prevent conflicts with custom renderers
   incrementalizeDefaultRules: false,
 })

90-94: Consider memoizing the container element

The div properties could be memoized to prevent unnecessary re-renders.

+const containerProps = useMemo(() => ({
+  'data-color-mode': currentTheme,
+  style: { paddingBottom: '2rem' },
+  className: 'markdown-preview'
+}), [currentTheme]);

 return (
   <div
     ref={containerRef}
-    data-color-mode={currentTheme}
-    style={{ paddingBottom: "2rem" }}
-    className="markdown-preview"
+    {...containerProps}
   />
 );
frontend/package.json (1)

42-42: Consider bundle size impact.

The addition of multiple markdown-related packages could significantly increase the bundle size. Consider:

  1. Using dynamic imports for the markdown renderer to enable code-splitting
  2. Analyzing the bundle size impact using tools like webpack-bundle-analyzer
  3. Setting up size limits with size-limit to prevent unexpected increases

Also applies to: 52-53, 57-60, 79-79, 87-87, 90-90

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 020c12d and 4e8f967.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (2)
  • frontend/package.json (3 hunks)
  • frontend/src/components/editor/Preview.tsx (2 hunks)
🔇 Additional comments (7)
frontend/src/components/editor/Preview.tsx (3)

Line range hint 44-97: Implementation successfully addresses performance objectives

The transition to incremental DOM updates is well-implemented with proper cleanup and error handling. The code structure is clean and maintainable. While there are some minor improvements suggested above, the core implementation is solid and aligns well with the PR objectives to improve preview performance.


71-79: Verify incremental DOM update performance

The implementation aligns with the PR objective to improve preview performance. However, we should verify that the incremental updates are working as expected.

#!/bin/bash
# Search for performance tests
rg -l "Preview.*performance|performance.*Preview" --type=test

# Check for any existing benchmarks
rg -l "benchmark.*Preview|Preview.*benchmark" --type=test

Consider adding performance benchmarks to validate the improvements, especially for large documents.


10-10: Consider package stability implications

Using @vscode/markdown-it-katex instead of the original markdown-it-katex package. While this might be more stable, be aware that it could have version synchronization challenges with VSCode updates.

frontend/package.json (4)

57-58: LGTM: Core packages align with incremental DOM implementation goal.

The addition of markdown-it and incremental-dom packages provides the foundation needed for implementing incremental DOM updates, which should significantly improve performance for large document editing scenarios.

Also applies to: 53-53


87-87: LGTM: Type definitions are properly aligned.

The added TypeScript definitions match their package versions and are from the reliable DefinitelyTyped repository.

Also applies to: 90-90


42-42: Verify dependency compatibility.

Please verify that all new packages are compatible with the existing React version (^17.0.0 || ^18.0.0) and check for any conflicting peer dependencies.

Let's check for potential conflicts:

#!/bin/bash
# Description: Check for peer dependency conflicts in new packages
echo "Checking peer dependencies for new packages..."
for pkg in "@vscode/markdown-it-katex" "markdown-it" "markdown-it-incremental-dom" "markdown-it-prism" "markdown-it-sanitizer" "incremental-dom"; do
  echo "Package: $pkg"
  npm info $pkg peerDependencies
done

Also applies to: 52-53, 57-60, 79-79


42-42: ⚠️ Potential issue

Security: Consider alternatives to markdown-it-sanitizer.

While the markdown-it plugins generally look good, markdown-it-sanitizer (v0.4.3) hasn't been updated in 5 years. Consider using DOMPurify or a more actively maintained sanitizer.

Let's check the last commit date and open issues:

Also applies to: 59-60

Copy link
Member

@devleejb devleejb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution.

@devleejb devleejb changed the title feat: Apply incremental dom update Apply incremental dom update Nov 3, 2024
@devleejb devleejb merged commit 9e08612 into main Nov 3, 2024
2 checks passed
@devleejb devleejb deleted the feat/incremental-dom-update branch November 3, 2024 15:31
@blurfx blurfx mentioned this pull request Nov 3, 2024
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

Improve preview performance during large document editing
2 participants