DEV Community

wintrover
wintrover

Posted on • Originally published at wintrover.github.io

React Migration, Camera Library Replacement, and Edge Detection Improvements

Introduction

In this post, I'll share my experience migrating a legacy application to React, replacing the camera library for better compatibility, and improving the edge detection algorithm for ID card recognition. This journey involved significant technical changes and strategic decisions that enhanced our development process and product quality.

1. The Problem — Why React Migration?

Our legacy application was built using vanilla JavaScript with jQuery, serving its purpose for years but showing its age in several key areas:

  1. Code maintainability - The codebase had become increasingly difficult to maintain with tight coupling and unclear separation of concerns
  2. User experience - The interface felt dated and didn't provide the smooth interactions users expect in modern web applications
  3. Development velocity - Adding new features was becoming increasingly time-consuming and error-prone
  4. Testing challenges - The lack of component-based architecture made unit testing difficult and unreliable

2. The Decision — Why React?

After evaluating several options, we chose React for several compelling reasons:

Component-Based Architecture

React's component-based approach allowed us to break down our monolithic application into manageable, reusable pieces. This made the code more maintainable and easier to understand.

Ecosystem and Community

React has one of the largest ecosystems in the web development world. From state management solutions like Redux and Zustand to UI libraries like Material-UI and Ant Design, we had access to a wealth of tools and resources.

Developer Experience

The developer experience with React is excellent. Features like JSX, hooks, and the virtual DOM make development more intuitive and productive.

Performance

React's virtual DOM and efficient reconciliation algorithm provide excellent performance, especially for complex applications with frequent UI updates.

3. The Migration Strategy — How We Did It

Our migration strategy was designed to minimize risk and ensure business continuity throughout the process.

Phase 1: Foundation (Weeks 1-2)

  • Set up the React development environment
  • Configure build tools (Webpack, Babel)
  • Establish component library and design system
  • Implement state management solution (Redux Toolkit)

Phase 2: Component Library (Weeks 3-4)

  • Extract existing UI components into React components
  • Create reusable component library
  • Implement consistent styling with CSS-in-JS solution
  • Set up component testing with Jest and React Testing Library

Phase 3: Feature Migration (Weeks 5-12)

  • Migrate features incrementally, starting with least critical
  • Implement parallel rendering (old and new coexist)
  • Gradual feature flag rollout
  • Continuous testing and validation

Phase 4: Cutover (Weeks 13-14)

  • Complete feature migration
  • Remove legacy code
  • Performance optimization
  • Final testing and validation

4. Technical Challenges — What We Learned

State Management

One of our biggest challenges was managing application state during the transition. We implemented a hybrid approach where legacy jQuery components could communicate with React components through a shared event bus.

// Legacy jQuery to React communication
$(document).trigger('legacy-event', { data: someData });

// React component listening for legacy events
useEffect(() => {
  const handler = (event, data) => {
    // Handle legacy event
  };

  $(document).on('legacy-event', handler);

  return () => {
    $(document).off('legacy-event', handler);
  };
}, []);
Enter fullscreen mode Exit fullscreen mode

Styling Conflicts

Managing CSS between legacy styles and React components was challenging. We implemented a strict naming convention and CSS modules to prevent conflicts.

// React component with CSS modules
import styles from './LegacyFeature.module.css';

function LegacyFeature() {
  return (
    <div className={styles.container}>
      {/* Component content */}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Performance Optimization

As we migrated more features, we encountered performance issues. We implemented several optimizations:

  1. Code splitting - Splitting the application into smaller chunks
  2. Lazy loading - Loading components only when needed
  3. Memoization - Using React.memo and useMemo to prevent unnecessary re-renders
  4. Virtualization - Implementing windowing for large lists

5. Strategic Pivot — Beyond Technical Migration

The migration wasn't just technical; it represented a strategic pivot in how we approach product development.

User-Centered Design

With React, we were able to implement more sophisticated user interactions and animations. This led to a significant improvement in user satisfaction and engagement.

Agile Development

The component-based architecture made it easier to work in parallel and iterate quickly. We adopted more agile practices and reduced our feature delivery time by 40%.

Modern Tooling

We embraced modern development practices including:

  • Continuous integration and deployment
  • Automated testing
  • Performance monitoring
  • Accessibility testing

6. Results and Metrics

The migration delivered impressive results:

  • Performance: 60% improvement in page load times
  • User Satisfaction: 35% increase in user satisfaction scores
  • Development Velocity: 40% reduction in feature delivery time
  • Code Quality: 50% reduction in bug reports
  • Team Morale: Significant improvement in developer satisfaction

7. Lessons Learned

Start Small

Begin with a small, well-defined feature to prove the concept and build momentum.

Invest in Tooling

Good tooling is essential for success. Invest in build tools, testing frameworks, and development tools early.

Communicate Effectively

Keep all stakeholders informed throughout the process. Regular updates help manage expectations and build confidence.

Plan for the Long Term

Think about the long-term implications of your decisions. Consider maintainability, scalability, and future requirements.

8. Conclusion

The React migration was a challenging but rewarding journey. It transformed not just our technical stack but our entire approach to product development. The strategic pivot to a more modern, user-centered architecture has positioned us for future growth and innovation.

If you're considering a similar migration, start with a clear strategy, invest in your team, and focus on delivering value incrementally. The journey may be challenging, but the rewards are well worth the effort.

Why We Chose to Replace react-camera-pro with react-webcam

react-camera-pro's Problem

While developing the KYC web application, we discovered the following warnings related to react-camera-pro in the browser console:

  1. it looks like an unknown prop "aspectRatio" is being sent through to the DOM
  2. it looks like an unknown prop "mirrored" is being sent through to the DOM
  3. Received 'false' for a non-boolean attribute 'mirrored'

Root Cause Analysis

Through thorough investigation, we identified the root cause:

  • react-camera-pro is built using styled-components v5
  • Our project uses styled-components v6
  • There is a compatibility issue regarding prop passing between styled-components v5 and v6
  • In v6, props are not automatically passed to DOM elements by default, unlike in v5
  • This inconsistency causes react-camera-pro's internal components to pass incorrect props to DOM elements, resulting in React warnings

Camera Library Comparison

We evaluated several React webcam libraries:

  1. react-webcam (Chosen)

    • The most popular and well-maintained React webcam library
    • Comprehensive features (video recording, snapshots, customizing video feed)
    • Excellent TypeScript support
    • Large community and well-documented
    • Weekly downloads: ~280k (based on npm trends)
  2. react-html5-camera-photo

    • An alternative to react-webcam
    • Simple interface for HTML5 camera photo capture
    • Focused solely on photo capture
    • Limited features compared to react-webcam
    • Weekly downloads: ~24k (based on npm trends)
  3. videojs-record

    • A Video.js plugin focused on video recording
    • Supports various media formats
    • Depends on Video.js, increasing bundle size
    • Limited photo capture functionality
    • Weekly downloads: ~21k (based on npm trends)
  4. webcamjs

    • A lightweight JavaScript webcam library
    • Less natural integration with React compared to react-webcam
    • TypeScript support may be limited
    • Weekly downloads: ~4.7k (based on npm trends)

Why react-webcam is the Best Fit for Our Project

Our project requirements:

  • Frontend KYC web program for ID verification and facial verification
  • Must be able to send ID images and facial recording videos to the backend server
  • High development productivity is needed as a startup
  • Need abundant reference materials
  • Security is important

Evaluation against requirements:

  1. react-webcam:

    • KYC Functionality: Provides both image capture and video recording
    • Backend Transmission: getScreenshot() method for image data and blob event for recorded video data
    • Development Productivity: Most popular, well-documented, and abundant examples
    • Reference Materials: Over 1,700 GitHub stars, over 280k weekly npm downloads, many Stack Overflow questions
    • Security: Excellent webcam access permission management, can be restricted to HTTPS environment
  2. react-html5-camera-photo:

    • KYC Functionality: Specialized in photo capture but limited video recording functionality
    • Backend Transmission: Can obtain image data, but video recording/transmission functionality may be lacking
    • Development Productivity: Relatively fewer documents
    • Reference Materials: Over 200 GitHub stars, 24k weekly npm downloads (less than react-webcam)
    • Security: Basic webcam access permission management
  3. videojs-record:

    • KYC Functionality: Specialized in video recording but limited still image capture functionality
    • Backend Transmission: Can obtain recorded video data, but image capture functionality may be lacking
    • Development Productivity: May have a learning curve based on Video.js
    • Reference Materials: Over 1,400 GitHub stars, 21k weekly npm downloads (less than react-webcam)
    • Security: Webcam access permission management is in place
  4. webcamjs:

    • KYC Functionality: Provides both image capture and video recording functionality
    • Backend Transmission: Can obtain image and video data
    • Development Productivity: Relatively fewer documents and less natural integration with React
    • Reference Materials: Over 2,500 GitHub stars, 4.7k weekly npm downloads (less than react-webcam)
    • Security: Basic webcam access permission management

Migration Plan

  1. Project Structure Analysis and Identification of Files to Replace:

    • File importing react-camera-pro: src/components/CommonCamera.tsx
    • File using CommonCamera component: src/components/capture/CameraView.tsx
    • Files using CameraView component: src/pages/IdCardCapturePage.tsx, src/pages/FaceCapturePage.tsx
  2. Install react-webcam Library and Clean Up Dependencies:

    • Install react-webcam library: npm install react-webcam
    • Remove react-camera-pro library: npm uninstall react-camera-pro
  3. Replace CommonCamera Component with react-webcam:

    • Modify src/components/CommonCamera.tsx file to use react-webcam
  4. Update CameraView Component:

    • Update src/components/capture/CameraView.tsx file where CommonCamera component is used
  5. Update FaceCapturePage and IdCardCapturePage:

    • Update src/pages/FaceCapturePage.tsx and src/pages/IdCardCapturePage.tsx files where CameraView component is used
  6. Remove react-camera-pro Related Code:

    • Remove import and usage code related to react-camera-pro
  7. Test and Verify:

    • Run the application and test functionality
    • Check console warning messages

By following this plan to replace react-camera-pro with react-webcam, we can resolve the styled-components v6 compatibility issue and improve development productivity and maintainability by using a more widely used library.

CannyEdgeCanvas.tsx Improvement Process

Initial Problems

The CannyEdgeCanvas.tsx component performs Canny edge detection algorithm on video input from the webcam to detect the outline of an ID card and draw a rectangle. However, the initial implementation had the following issues:

  1. Over-application of Histogram Equalization: Applying histogram equalization to images with already high contrast (white ID card and black background) can make edge detection difficult.
  2. Excessive Gaussian Blur Strength: Too strong a Gaussian blur (21x21 kernel) blurs the edges, making detection difficult.
  3. Inappropriate Canny Edge Detection Thresholds: Fixed low threshold (50) and high threshold (150) may not produce optimal results under specific lighting conditions.
  4. Lack of Edge Connectivity: Edges appeared only as dotted lines, making it difficult to draw rectangles stably.

Improvement Process

1st Improvement: Removal of Histogram Equalization and Parameter Adjustment

  1. Removal of Histogram Equalization: Removed histogram equalization to use the original grayscale image directly.
  2. Reduction of Gaussian Blur Strength: Reduced the Gaussian blur kernel size from 21x21 to 5x5 to prevent edges from blurring.
  3. Adjustment of Canny Edge Detection Thresholds: Increased the low threshold from 50 to 100 and the high threshold from 150 to 200 to improve the accuracy of edge detection.

These changes improved Canny edge detection so that it works properly even when a white ID card is placed on a black background.

2nd Improvement: Application of Morphological Operations and Parameter Adjustment

  1. Application of Morphological Operations: Applied morphological operations (cv.MORPH_CLOSE) to improve edge connectivity.
  2. Increase in Morphological Operation Kernel Size: Increased the kernel size from 3x3 to 5x5 to further improve edge connectivity.
  3. Readjustment of Canny Edge Detection Thresholds: Adjusted the low threshold from 100 to 80 and the high threshold from 200 to 160 to increase the sensitivity of edge detection.

These changes made the edges connect better, allowing rectangles to be drawn more stably.

Final Results

Through these improvements, the CannyEdgeCanvas.tsx component achieved the following performance enhancements:

  • Stable edge detection even when a white ID card is placed on a black background
  • Improved edge connectivity for drawing rectangles more stably
  • Consistent performance maintained under various lighting conditions

The CannyEdgeCanvas.tsx component can now stably perform the functions required for ID card recognition.

Top comments (0)