news Apr 12, 2026 · 4 views · 2 min read

Vue 3 Portfolio Port: Achieving 41% Smaller Gzip Than React

Discover how porting a portfolio landing page to Vue 3 resulted in a significantly smaller gzip size compared to React. This transformation retained all features while achieving a 41% reduction in bundle size.

Introduction

In the world of web development, optimizing bundle size can have significant impacts on performance. This article explores how porting a portfolio landing page to Vue 3 resulted in a 41% smaller gzip size compared to its React counterpart.

The Experiment Setup

The experiment maintained identical specifications, data, and CSS as the original React version. The only change was in the component layer, ensuring that the shared code, including types.ts, filter.ts, and data.ts, remained byte-identical. This controlled approach allowed for a clean comparison of framework overheads.

Vue 3's Efficient Syntax

Utilizing Vue 3 with the Composition API and <script setup> provided a streamlined component syntax. This setup eliminated the need for multiple useState calls and dependency arrays required in React, simplifying state management and reducing potential errors.

<script setup lang="ts">
import { ref, computed, watchEffect } from 'vue'
import type { PortfolioData, Entry, Lang } from './types'
// ... other imports and setup
</script>

URL Sync Made Simple

Vue's two-way binding with v-model combined with watchEffect facilitated seamless URL synchronization, removing the cumbersome declaration requirements of React.

<template>
  <input type="text" v-model="filter.query" :placeholder="m.searchPlaceholder" />
  <select v-model="filter.category">
    <!-- options -->
  </select>
</template>

Understanding the Byte Reduction

The significant reduction in gzip size is attributed to Vue's proxy-based reactivity and compile-time optimizations. In contrast to React's virtual DOM, Vue's model precomputes the exact DOM updates needed, leading to denser compiled output.

Component Structure

Vue's Single File Components (SFCs) allow for cohesive organization of template, script, and styles in one file, enhancing maintainability and type inference, especially with TypeScript.

Consistent Shared Code

The experiment confirmed the byte-identical nature of the shared code across frameworks, ensuring the observed differences were solely due to the rendering layer.

Testing Frameworks

Tests were consistently executed using Vitest, validating that the logic remained unchanged across different frameworks.

test('filters by category', () => {
  const r = filterAndSort(entries, { ...defaults, category: 'dev-tool' }, 'en')
  assert.ok(r.every((e) => e.category === 'dev-tool'))
})

Conclusion

Porting to Vue 3 demonstrates a substantial reduction in bundle size without compromising functionality. The next phase will explore further optimizations with Svelte 5, promising even smaller sizes.

Discussion

0 Comments

Leave a Comment

Comments are moderated and will appear after approval.