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

feat(site): optimize the performance of the official website, use lazy loading for document examples #2713

Merged
merged 2 commits into from
Dec 30, 2024

Conversation

zzcr
Copy link
Member

@zzcr zzcr commented Dec 28, 2024

feat: 优化官网性能,文档示例使用懒加载

PR

PR Checklist

Please check if your PR fulfills the following requirements:

  • The commit message follows our Commit Message Guidelines
  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • Other... Please describe:

What is the current behavior?

Issue Number: N/A

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

Summary by CodeRabbit

  • New Features

    • Added a build visualizer mode for analyzing bundle size
    • Implemented lazy-loading for demo components using Intersection Observer
    • Enhanced component rendering with dynamic visibility control
  • Chores

    • Updated Vite dependency to version 4.3.8
    • Added Rollup Visualizer plugin for build analysis
  • Performance

    • Optimized component loading by deferring rendering until viewport intersection

Copy link

coderabbitai bot commented Dec 28, 2024

Walkthrough

This pull request introduces enhancements to the build process and component rendering in the examples/sites directory. The changes focus on adding a build visualizer, updating dependencies, and implementing an Intersection Observer for more efficient component loading. The modifications improve performance by conditionally rendering components based on viewport visibility and provide better insights into the build bundle through a visualizer plugin.

Changes

File Change Summary
examples/sites/package.json - Added build:visualizer script
- Added rollup-plugin-visualizer dev dependency
- Updated vite dependency version
examples/sites/src/views/components/cmp-config.js - Added vueComponents constant for dynamic component mapping
examples/sites/src/views/components/components.vue - Simplified template rendering
- Added observer prop
- Implemented isIntersecting logic
examples/sites/src/views/components/demo.vue - Updated props to include observer and isIntersecting
- Added Intersection Observer logic
examples/sites/vite.config.ts - Imported visualizer plugin
- Added conditional plugin configuration for visualizer mode

Sequence Diagram

sequenceDiagram
    participant User
    participant Components
    participant IntersectionObserver
    participant DemoComponent

    User->>Components: Scroll/Navigate
    Components->>IntersectionObserver: Check Viewport
    IntersectionObserver-->>DemoComponent: Trigger Load
    alt Is Intersecting
        DemoComponent->>User: Render Component
    else Not Intersecting
        DemoComponent->>User: Defer Loading
    end
Loading

Possibly related PRs

Poem

🐰 Visualize the code, oh what a sight!
Bundles dancing in the build's delight
Components peek when scrollers glide
Performance leaps with rabbit pride
A magical render, swift and bright! 🚀

Tip

CodeRabbit's docstrings feature is now available as part of our Early Access Program! Simply use the command @coderabbitai generate docstrings to have CodeRabbit automatically generate docstrings for your pull request. We would love to hear your feedback on Discord.


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 generate docstrings to generate docstrings for this PR. (Beta)
  • @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

Walkthrough\nThis pull request optimizes the performance of the official website by implementing lazy loading for document examples. This change aims to enhance the user experience by loading content only when it is needed, thus reducing initial load times and improving overall site performance.\n\n### Changes\n| File | Summary |\n|------|---------|\n| examples/sites/package.json | Minor adjustments to dependencies. |\n| examples/sites/src/views/components/cmp-config.js | Introduced lazy loading for Vue component examples. |\n| examples/sites/src/views/components/components.vue | Refactored to support lazy loading of demo components using IntersectionObserver. |\n| examples/sites/src/views/components/demo.vue | Updated to load demo components only when they intersect with the viewport. |\n| examples/sites/vite.config.ts | Added rollup-plugin-visualizer for build analysis. |

@github-actions github-actions bot added the enhancement New feature or request (功能增强) label Dec 28, 2024
@@ -556,6 +481,12 @@ export default defineComponent({
// 3、加载cmpId.js 文件
// eslint-disable-next-line no-eval
const json = jsData ? eval('(' + jsData.slice(15) + ')') : {}

Choose a reason for hiding this comment

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

Using eval can lead to security vulnerabilities if the input is not controlled. Consider using a safer alternative like JSON.parse if possible.

Copy link

[e2e-test-warn]
The component to be tested is missing.

The title of the Pull request should look like "fix(vue-renderless): [action-menu, alert] fix xxx bug".

Please make sure you've read our contributing guide

Copy link

@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

🧹 Nitpick comments (6)
examples/sites/vite.config.ts (1)

121-121: Consider making the visualizer plugin’s open behavior optional.
Randomly opening a browser may be unexpected for some developers. Consider adding a configuration flag to selectively disable/enable open.

examples/sites/src/views/components/components.vue (2)

408-408: Consider extracting scroll offset to a constant
Currently, the scroll offset is hard-coded to 52. For maintainability, consider defining a variable or constant.


722-722: Use design tokens for styling
Adopting design tokens or variables for your min-height may improve consistency and maintainability.

examples/sites/src/views/components/demo.vue (3)

5-49: Template structure and repeated tooltip usage
The template block is well organized, with consistent usage of tooltip and icon elements. However, consider extracting common tooltip logic into a reusable sub-component for better maintainability if you plan to use these controls repeatedly across the codebase.


112-112: Expanding props
Adding observer and isIntersecting as props is a convenient approach to combine external Intersection Observer logic with the child component's rendering. Ensure that calling pages handle null or undefined observer gracefully.


247-261: Intersection-based component loading
Watching props.isIntersecting to load the component dynamically is a strong performance optimization. Consider adding logic if isIntersecting reverts to false (e.g., to unload or reset the component) for further resource management if desired.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f0fb1f3 and ab60310.

📒 Files selected for processing (5)
  • examples/sites/package.json (4 hunks)
  • examples/sites/src/views/components/cmp-config.js (1 hunks)
  • examples/sites/src/views/components/components.vue (8 hunks)
  • examples/sites/src/views/components/demo.vue (5 hunks)
  • examples/sites/vite.config.ts (2 hunks)
🔇 Additional comments (24)
examples/sites/vite.config.ts (1)

17-17: Excellent addition of the visualizer plugin import.
This import is essential for generating bundle visualizations. The conditional usage is a neat way to keep the plugin out of production builds.

examples/sites/package.json (4)

18-18: New script definition looks good.
The build:visualizer script aligns with the plugin import and provides a convenient way to visualize the build output.


60-60: Dependency addition is appropriate.
Including rollup-plugin-visualizer as a development dependency is a tidy approach for analyzing bundle size.


96-96: No changes needed here.
This is just the file closing brace.


87-87: Verify that upgrading vite to ^4.3.8 doesn’t break existing functionality.
Be sure to confirm that other plugins and dev tooling remain compatible with this version.

✅ Verification successful

Let me analyze the compatibility of Vite 4.3.8 based on the search results.

Upgrading to Vite 4.3.8 appears safe and compatible with the codebase.

  • The project uses various Vite plugins that are compatible with Vite 4.x:

    • @vitejs/plugin-vue v5.1.0
    • @vitejs/plugin-vue-jsx v4.0.0
    • vite-plugin-dynamic-import v1.5.0
    • vite-plugin-md v0.13.1
    • vite-plugin-inspect v0.7.x
    • vite-plugin-checker v0.5.2
    • vite-svg-loader v3.6.0
  • The codebase already has examples using Vite 4.x configurations and plugins without any compatibility issues.

  • The workspace configuration in pnpm-workspace.yaml shows that other parts of the project are already using newer Vite versions (^6.0.0), indicating that v4.3.8 is a conservative and stable choice.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if there are known compatibility issues with Vite ^4.3.8
# Searching references to 'vite' usage in the codebase for potential conflict
rg -A 5 'vite'

Length of output: 89818

examples/sites/src/views/components/components.vue (6)

23-23: Ensure tab initialization is correct
The @click="onTabsClick" listener on <tiny-tabs> appears to be properly set. No issues found.


32-33: Props for observer-based lazy loading
Passing observer and isIntersecting into <demo> is a solid approach for lazy loading. Ensure the child component’s logic properly handles these props.


41-41: Forced intersection for single-demo mode
Enabling isIntersecting="true" ensures the single demo is always loaded. This is consistent with lazy loading logic elsewhere.


222-222: Observer property declaration
Defining observer in reactive state is consistent with the new IntersectionObserver usage. No immediate issues.


484-489: Avoid using eval to parse script
This usage can lead to security risks if the input is ever untrusted. Consider using a safer alternative such as JSON.parse.


569-589: Verify IntersectionObserver usage
This callback is well-defined, but ensure each demo element is properly observed (e.g., by calling observer.observe(element)) so that intersection events actually fire.

✅ Verification successful

Let me search for more specific information about how the observer is used in this component.


Let me search for where the demos are rendered and how they might be connected to the observer.


Let me check the demo component to see how it uses the observer prop.


IntersectionObserver implementation is correctly set up

The implementation is properly handling both observation and cleanup:

  • Each demo component is observed when mounted via observer.observe(demoContainer.value)
  • Observation is properly cleaned up on unmount via observer.unobserve(demoContainer.value)
  • The observer callback correctly updates the isIntersecting state for the matching demo when intersection occurs
  • The observer is configured with appropriate threshold (0.2) and root element
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Searching for "observer.observe" calls to confirm each demo component is observed
rg "observer\.observe"

Length of output: 1584


Script:

#!/bin/bash
# Search for observer usage in the components.vue file
rg -A 5 "state\.observer" "examples/sites/src/views/components/components.vue"

Length of output: 274


Script:

#!/bin/bash
# Search for demo-related code in components.vue
rg -B 2 -A 5 "demo" "examples/sites/src/views/components/components.vue"

Length of output: 9852


Script:

#!/bin/bash
# Search for observer usage in the demo component
rg -B 2 -A 5 "observer" "examples/sites/src/views/components/demo.vue"

Length of output: 641

examples/sites/src/views/components/cmp-config.js (1)

3-4: Plain object for dynamic components
Using Object.create(null) is fine for storing component mappings. Optionally, consider an ES6 Map for modern semantics, but this is acceptable as-is.

examples/sites/src/views/components/demo.vue (12)

2-4: Lazy loading container
The use of ref="demoContainer" paired with v-if="isIntersecting" is a clear and effective approach to defer heavy component rendering until it's within the viewport. This optimizes performance significantly and follows a best practice for lazy loading.


51-51: Description rendering
Using <component :is="getDescMd(demo)" /> is a neat approach to conditionally render the relevant demo description. Code readability remains high, and it helps maintain separation of concerns for the Markdown logic.


53-54: Mobile-first check
The conditional branch for mobile-first mode is straightforward and helps ensure the UI is adapted for different form factors. Good job.


56-64: Mobile vs PC container
This clear branching logic for mobile vs. desktop scenarios improves readability and maintainability. No immediate issues detected.


67-78: Toggleable code previews
Conditionally rendering code previews based on demo.isOpen keeps the UI uncluttered and loads code blocks only when needed. This approach boosts performance and user experience.


85-85: JSX script usage
Defining the <script lang="jsx"> block is fine, but be cautious about IDE or tooling support, as some setups might not fully support Vue single-file components in JSX mode.


154-156: Referencing the container
Declaring demoContainer = ref(null) is essential for Intersection Observer binding. The code is concise and aligns well with Vue's composition API.


228-232: Observing the container on mount
Observing the container within onMounted is a clean solution for lazy loading logic. One suggestion is to provide a fallback or log a warning if props.observer is absent, ensuring robust error handling.


238-242: Unobserving on unmount
Unobserving in onBeforeUnmount properly avoids potential memory leaks. This is an excellent housekeeping step.


262-262: Reacting to prop updates
The watch on props.demo ensures the component re-initializes if the provided demo data changes, maintaining an accurate display.


285-296: Returning references and methods
Spreading toRefs(state) and fn maintains clarity while returning all relevant references for the template. No issues detected.


302-305: Minimal container height
Setting min-height: 200px; on .demo-container ensures a consistent layout even before the lazy content is loaded, enhancing user experience with stable placeholders.

@kagol kagol merged commit dcb86cd into dev Dec 30, 2024
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request (功能增强)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants