# refactor: restructure .cursor directory for improved organization and clarity ## Description This PR refactors the `.cursor` directory to enhance organization, clarity, and maintainability. ### Problem The existing `.cursor` directory lacked clear organization, making it difficult to find specific files, understand their purpose, and add new components consistently. ### Solution A comprehensive restructuring: #### New Directory Structure ``` .cursor/ ├── settings.json # Main configuration file ├── docs/ # Documentation │ ├── guides/ # In-depth guides │ ├── references/ # Quick references │ └── practices/ # Best practices ├── rules/ # Rule definitions │ ├── commit/ # Commit-related rules │ ├── quality/ # Code quality rules │ ├── testing/ # Testing rules │ └── verification/ # Verification rules └── hooks/ # Git hooks and scripts ``` #### Key Changes 1. **Logical Categorization**: Organized files into clear categories based on purpose 2. **Improved Documentation**: Added comprehensive README files for each directory 3. **Standardized Naming**: Implemented consistent kebab-case naming convention 4. **Reference Updates**: Updated all internal references to point to new file locations ### Benefits - **Easier Navigation**: Clear categorization makes finding files intuitive - **Improved Understanding**: Comprehensive documentation explains purpose and usage - **Simplified Maintenance**: Logical structure makes updates and additions easier - **Better Onboarding**: New team members can quickly understand the system This refactoring sets a solid foundation for all Cursor AI-related configurations and rules, making it easier for the team to leverage Cursor's capabilities.
7.5 KiB
7.5 KiB
Appsmith Performance Optimization Guide
This guide outlines approaches for identifying, analyzing, and resolving performance issues in the Appsmith codebase.
Identifying Performance Issues
Frontend Performance Metrics
-
Page Load Time
- Initial page load
- Time to first paint
- Time to interactive
-
Rendering Performance
- Component render times
- React render cycles
- Frame rate (FPS)
-
Network Performance
- API request latency
- Payload sizes
- Number of requests
-
Memory Usage
- Heap snapshots
- Memory leaks
- DOM node count
Backend Performance Metrics
-
Response Times
- API endpoint latency
- Database query performance
- Worker thread utilization
-
Resource Utilization
- CPU usage
- Memory consumption
- I/O operations
-
Database Performance
- Query execution time
- Index utilization
- Connection pool efficiency
-
Concurrency
- Request throughput
- Thread pool utilization
- Blocking operations
Performance Analysis Tools
Frontend Tools
-
Browser DevTools
- Performance tab
- Network tab
- Memory tab
-
React DevTools
- Component profiler
- Highlight updates
-
Lighthouse
- Performance audits
- Optimization suggestions
-
Custom Timing
// Performance measurement performance.mark('start'); // ...code to measure... performance.mark('end'); performance.measure('operation', 'start', 'end'); console.log(performance.getEntriesByName('operation')[0].duration);
Backend Tools
-
Profilers
- JProfiler
- VisualVM
- YourKit
-
Logging and Metrics
- Log execution times
- Prometheus metrics
- Grafana dashboards
-
Load Testing
- JMeter
- K6
- Artillery
Common Performance Issues and Solutions
Frontend Performance Issues
-
Unnecessary Re-renders
Issue:
function Component() { // This creates a new object on every render const options = { value: 'example' }; return <ChildComponent options={options} />; }Solution:
function Component() { // Memoize object const options = useMemo(() => ({ value: 'example' }), []); return <ChildComponent options={options} />; } -
Unoptimized List Rendering
Issue:
function ItemList({ items }) { return ( <div> {items.map(item => ( <Item data={item} /> ))} </div> ); }Solution:
function ItemList({ items }) { return ( <div> {items.map(item => ( <Item key={item.id} data={item} /> ))} </div> ); } // Memoize the Item component const Item = React.memo(function Item({ data }) { return <div>{data.name}</div>; }); -
Large Bundle Size
Issue:
- Importing entire libraries
- Not code-splitting
Solution:
// Before import { map, filter, reduce } from 'lodash'; // After import map from 'lodash/map'; import filter from 'lodash/filter'; import reduce from 'lodash/reduce'; // Code splitting with React.lazy const HeavyComponent = React.lazy(() => import('./HeavyComponent')); -
Memory Leaks
Issue:
function Component() { useEffect(() => { const interval = setInterval(() => { // Do something }, 1000); // No cleanup }, []); return <div>Component</div>; }Solution:
function Component() { useEffect(() => { const interval = setInterval(() => { // Do something }, 1000); // Cleanup return () => clearInterval(interval); }, []); return <div>Component</div>; }
Backend Performance Issues
-
N+1 Query Problem
Issue:
List<Workspace> workspaces = workspaceRepository.findAll().collectList().block(); for (Workspace workspace : workspaces) { List<Application> apps = applicationRepository.findByWorkspaceId(workspace.getId()).collectList().block(); workspace.setApplications(apps); }Solution:
// Use join query or batch loading List<Workspace> workspaces = workspaceRepository.findAllWithApplications().collectList().block(); -
Missing Database Indexes
Issue:
// Query without proper index Mono<User> findByEmail(String email);Solution:
// Add index to database @Document(collection = "users") public class User { @Indexed(unique = true) private String email; // ... } -
Blocking Operations in Reactive Streams
Issue:
return Mono.fromCallable(() -> { // Blocking file I/O operation return Files.readAllBytes(Paths.get("path/to/file")); });Solution:
return Mono.fromCallable(() -> { // Blocking file I/O operation return Files.readAllBytes(Paths.get("path/to/file")); }).subscribeOn(Schedulers.boundedElastic()); -
Inefficient Data Processing
Issue:
// Processing large amounts of data in memory return repository.findAll() .collectList() .map(items -> { // Process all items at once return items.stream().map(this::transform).collect(Collectors.toList()); });Solution:
// Stream processing with backpressure return repository.findAll() .map(this::transform) .collectList();
Performance Optimization Workflow
Step 1: Establish Baselines
- Identify key metrics to track
- Measure current performance
- Set performance goals
Step 2: Identify Bottlenecks
- Use profiling tools
- Analyze critical user paths
- Focus on high-impact areas
Step 3: Optimize
- Make one change at a time
- Measure impact of each change
- Document optimizations
Step 4: Verify
- Compare to baseline metrics
- Run performance tests
- Check for regressions
Step 5: Monitor
- Set up continuous performance monitoring
- Track trends over time
- Set up alerts for degradations
Performance Testing Best Practices
- Test with realistic data volumes
- Simulate actual user behavior
- Test on hardware similar to production
- Include performance tests in CI/CD pipeline
- Test in isolation and under load
- Focus on critical user journeys
- Set clear performance budgets
- Compare results to previous baselines
Performance Optimization Checklist
Frontend Checklist
- Use React.memo for expensive components
- Implement proper keys for list items
- Memoize callbacks with useCallback
- Memoize computed values with useMemo
- Code-split large bundles
- Lazy load components and routes
- Optimize images and assets
- Minimize CSS and JS bundle sizes
- Use virtualization for large lists
- Implement proper cleanup in useEffect
- Avoid prop drilling with Context API
- Optimize Redux selectors
Backend Checklist
- Add appropriate database indexes
- Use pagination for large result sets
- Optimize database queries
- Avoid N+1 query problem
- Use reactive programming correctly
- Handle blocking operations properly
- Implement caching where appropriate
- Optimize serialization/deserialization
- Use connection pooling
- Configure thread pools appropriately
- Monitor and optimize GC behavior