DEV Community

Cover image for Rebuilding My Portfolio: A Week of React, Animations, and Testing
Albino Tonnina
Albino Tonnina

Posted on • Originally published at albinotonnina.com

Rebuilding My Portfolio: A Week of React, Animations, and Testing

After years of inactivity, I decided it was time for a complete overhaul of my personal portfolio. What started as a simple "let me fix this one animation" turned into a week-long intensive refactoring session that transformed the entire codebase.

🎯 The Challenge

My original portfolio stopped working because of many deprecated dependencies. The animation system was monolithic, testing was sparse, and adding new features felt like walking through a minefield.

🚀 What I Built

Complete Animation System Overhaul

The biggest change was moving from a single, monolithic animation controller to a modular scene-based system. Each section of my journey (freelance → company → ASOS) now has its own self-contained scene with dedicated animations.

// Before: One massive animation controller
const animateEverything = (progress) => {
  // 500+ lines of mixed concerns
}

// After: Modular scene management
import { deskScene } from './scenes/deskScene'
import { spaceScene } from './scenes/spaceScene'
import { contactsScene } from './scenes/contactsScene'

const scenes = {
  desk: deskScene,
  space: spaceScene,
  contacts: contactsScene
}
Enter fullscreen mode Exit fullscreen mode

Brand New Visuals and Interactions

Each career chapter now tells a visual story:

  • Desk Scene: My freelance days working from home
  • Space Scene: The journey to London and ASOS
  • Contacts Scene: Opening doors to new opportunities

Comprehensive Testing Infrastructure

Testing animations is tricky, but I managed to achieve 90%+ coverage using:

// Testing animation state changes
it('should progress through scenes correctly', () => {
  const { result } = renderHook(() => useAnimation())

  act(() => {
    result.current.setProgress(0.5)
  })

  expect(result.current.currentScene).toBe('space')
})
Enter fullscreen mode Exit fullscreen mode

Custom SVG Processing Pipeline

I built a custom webpack plugin to optimize and process SVG animations:

// SVG ID processor for animation targeting
class SVGIdPlugin {
  apply(compiler) {
    compiler.hooks.emit.tapAsync('SVGIdPlugin', (compilation, callback) => {
      // Process SVG files and assign unique IDs
    })
  }
}
Enter fullscreen mode Exit fullscreen mode

🛠️ Technical Stack

  • React 18 with hooks for state management
  • Custom animation system using D3 interpolation
  • React Testing Library for component testing
  • Webpack 5 with custom loaders and plugins
  • ESLint + Prettier + Stylelint for code quality
  • GitHub Copilot for enhanced development workflow

📱 Performance Optimizations

Mobile performance was crucial, especially for iOS Safari:

/* Viewport optimizations for iOS */
.animation-container {
  transform: translate3d(0, 0, 0);
  will-change: transform;
  backface-visibility: hidden;
}
Enter fullscreen mode Exit fullscreen mode

I also implemented throttled scroll handlers and IntersectionObserver for efficient animation triggers.

🧪 Testing Complex Animations

One of the biggest challenges was testing scroll-based animations. Here's how I approached it:

// Mock IntersectionObserver for testing
const mockIntersectionObserver = jest.fn()
mockIntersectionObserver.mockReturnValue({
  observe: () => null,
  unobserve: () => null,
  disconnect: () => null
})

window.IntersectionObserver = mockIntersectionObserver
Enter fullscreen mode Exit fullscreen mode

🎨 Animation Debugger

I built a timeline debugger to visualize animation states during development:

const AnimationDebugger = ({ scenes, currentProgress }) => (
  <div className="debug-timeline">
    {scenes.map(scene => (
      <div 
        key={scene.name}
        className={`scene-marker ${scene.active ? 'active' : ''}`}
        style={{ left: `${scene.progress * 100}%` }}
      >
        {scene.emoji} {scene.name}
      </div>
    ))}
  </div>
)
Enter fullscreen mode Exit fullscreen mode

📈 Key Metrics

After the refactor:

  • 90%+ test coverage (up from ~20%)
  • Modular architecture with 8 separate scene files
  • Enhanced mobile performance with iOS-specific optimizations
  • Custom tooling for SVG processing and animation debugging

🤔 Lessons Learned

1. Modular Architecture Pays Off

Breaking the monolithic animation system into scenes made debugging and extending much easier. Each scene can be developed and tested in isolation.

2. Testing Animations is Hard but Worth It

Finding the right abstractions for testing scroll-based animations took time, but the confidence it provides is invaluable.

3. Performance Matters on Mobile

iOS Safari has specific quirks that required targeted optimizations. Always test on real devices!

4. Developer Experience is Key

The animation debugger and GitHub Copilot integration made the development process much more enjoyable and productive.

🌟 What's Next?

The new modular system makes it easy to add new scenes and animations. I'm already planning:

  • Interactive scene selection
  • More detailed micro-interactions
  • Performance monitoring dashboard

🔗 Check It Out

The code is open source under CC BY-NC-ND 4.0 - feel free to explore and learn from it, but please don't use it as your own portfolio!


What's your approach to portfolio development? Have you tackled similar animation challenges? I'd love to hear about your experiences in the comments! 👇

Top comments (0)