perf: reduce practice page dev bundle from 47MB to 115KB
- Dynamic import echarts-for-react in SkillProgressChart, ValidationCharts, and SkillDifficultyCharts to avoid bundling 58MB echarts library - Lazy load game-registry in CreateRoomModal to prevent all arcade games from being bundled into every page using PageWithNav The practice page was bundling echarts (58MB) and all arcade game code because of static imports in shared components. These changes ensure: - echarts only loads when charts are actually rendered - game-registry only loads when CreateRoomModal is opened Bundle size: 47MB → 115KB (99.8% reduction) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,14 @@
|
||||
'use client'
|
||||
|
||||
import dynamic from 'next/dynamic'
|
||||
import { useState, useEffect } from 'react'
|
||||
import ReactECharts from 'echarts-for-react'
|
||||
import * as Tabs from '@radix-ui/react-tabs'
|
||||
|
||||
// Dynamic import echarts to reduce bundle size
|
||||
const ReactECharts = dynamic(() => import('echarts-for-react'), {
|
||||
ssr: false,
|
||||
loading: () => <div style={{ height: '300px', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>Loading chart...</div>,
|
||||
})
|
||||
import { css } from '../../../styled-system/css'
|
||||
|
||||
interface SkillData {
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
'use client'
|
||||
|
||||
import * as Tabs from '@radix-ui/react-tabs'
|
||||
import ReactECharts from 'echarts-for-react'
|
||||
import dynamic from 'next/dynamic'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
// Dynamic import echarts to reduce bundle size
|
||||
const ReactECharts = dynamic(() => import('echarts-for-react'), {
|
||||
ssr: false,
|
||||
loading: () => <div style={{ height: '300px', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>Loading chart...</div>,
|
||||
})
|
||||
import { css } from '../../../styled-system/css'
|
||||
|
||||
const chartContainerStyles = css({
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { useState } from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import * as Select from '@radix-ui/react-select'
|
||||
import { animated } from '@react-spring/web'
|
||||
import { Modal } from '@/components/common/Modal'
|
||||
import { useCreateRoom, useRoomData } from '@/hooks/useRoomData'
|
||||
import { getAvailableGames } from '@/lib/arcade/game-registry'
|
||||
import { RoomShareButtons } from './RoomShareButtons'
|
||||
import type { GameDefinition } from '@/lib/arcade/game-sdk/types'
|
||||
|
||||
export interface CreateRoomModalProps {
|
||||
/**
|
||||
@@ -31,8 +31,17 @@ type ModalState = 'creating' | 'created'
|
||||
export function CreateRoomModal({ isOpen, onClose, onSuccess }: CreateRoomModalProps) {
|
||||
const { mutateAsync: createRoom, isPending } = useCreateRoom()
|
||||
const { getRoomShareUrl } = useRoomData()
|
||||
const availableGames = getAvailableGames()
|
||||
const [availableGames, setAvailableGames] = useState<GameDefinition<any, any, any>[]>([])
|
||||
const [error, setError] = useState('')
|
||||
|
||||
// Lazy load game registry only when modal opens
|
||||
useEffect(() => {
|
||||
if (isOpen && availableGames.length === 0) {
|
||||
import('@/lib/arcade/game-registry').then(({ getAvailableGames }) => {
|
||||
setAvailableGames(getAvailableGames())
|
||||
})
|
||||
}
|
||||
}, [isOpen, availableGames.length])
|
||||
const [gameName, setGameName] = useState<string>('__choose_later__') // Special value = user will choose later
|
||||
const [accessMode, setAccessMode] = useState<
|
||||
'open' | 'password' | 'approval-only' | 'restricted'
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
'use client'
|
||||
|
||||
import ReactECharts from 'echarts-for-react'
|
||||
import dynamic from 'next/dynamic'
|
||||
import { useCallback, useMemo, useState } from 'react'
|
||||
|
||||
// Dynamic import echarts to avoid bundling 58MB library on pages that don't use charts
|
||||
const ReactECharts = dynamic(() => import('echarts-for-react'), {
|
||||
ssr: false,
|
||||
loading: () => <div style={{ height: '200px', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>Loading chart...</div>,
|
||||
})
|
||||
import {
|
||||
getExtendedClassification,
|
||||
type ExtendedSkillClassification,
|
||||
|
||||
Reference in New Issue
Block a user