eduardweb.
PerformanceIntermediar#performance#vite#javascript#web-perf

De ce dynamic import-ul excesiv îți omoară performanța (și cum calculezi pragul de rentabilitate)

De Ana Ionescu, 7 iun. 2026 · 1 vizualizări · 3 like-uri

Postat acum 2 zile
javascript
// vite.config.js
export default {
  build: {
    rollupOptions: {
      output: {
        manualChunks(id) {
          // Grupăm toate bibliotecile mici de UI într-un singur chunk
          // ca să evităm 10 request-uri HTTP separate pentru fiecare iconiță sau buton
          if (id.includes('node_modules/@radix-ui')) {
            return 'ui-commons';
          }
        }
      }
    }
  }
}

Am văzut zeci de proiecte unde Lighthouse dădea scoruri proaste, iar echipa a sărit imediat să pună import() dinamic pe fiecare ruter și componentă mai răsărită. Sună bine pe hârtie: scazi bundle-ul inițial de la 1.2MB la 250KB și gata, ai rezolvat performanța. Doar că, în realitate, de multe ori doar muți problema din CPU-ul browserului direct în latența de rețea.

Azi vreau să vorbim despre costul ascuns al bundle splitting-ului și cum să calculezi matematic dacă o bucată de cod merită scoasă din bundle-ul principal sau nu.

Capcana micro-chunk-urilor

Am pățit asta la un proiect cu vreo 15k useri activi pe zi, majoritatea pe conexiuni mobile destul de instabile. Am spart tot ce se putea în bucăți mici: modale, tab-uri, dropdown-uri grele. Pagina principală se încărca instant, dar când userul dădea click pe un tab simplu, trebuia să aștepte 400ms să se descarce un chunk de doar 6KB.

De ce? Din cauza latenței (RTT - Round Trip Time). Chiar și pe HTTP/2, conexiunile mobile au un timp de negociere care face ca un fișier minuscul să dureze enorm până este livrat. Când ai 10-15 fișiere mici care se descarcă în cascadă (waterfall) pentru că unul depinde de altul, experiența devine execrabilă.

Practic, am făcut un trade-off prost: am îmbunătățit nesemnificativ timpul de încărcare inițial (FCP) cu prețul distrugerii interactive a aplicației (FID/INP).

Cum calculezi pragul de rentabilitate (Break-even)

Nu există o cifră magică universală, dar am o regulă empirică pe care am testat-o pe dispozitive low-end: regula de 30KB.

Dacă o componentă are sub 30KB (minified + gzipped) și este afișată în primele secunde după o interacțiune directă a utilizatorului, NU merită split-ul. Costul conexiunii HTTP depășește cu mult timpul de parsare JS pentru acei 30KB pe un procesor mobil mediu.

Ca să calculezi pragul de rentabilitate pentru audiența ta, folosește formula asta simplă:

Cost_Split = RTT_Retea + (Dimensiune_Chunk / Latime_Banda) Cost_In-Bundle = Timp_Parsare_CPU(Dimensiune_Chunk)

Dacă Cost_Split este mai mare decât Cost_In-Bundle, păstrează componenta în bundle-ul principal. Pe rețele mobile 3G/4G, un RTT de 150ms este standard. Parsarea a 30KB de JS pe un telefon de acum 3-4 ani durează sub 15ms. Matematica e simplă: split-ul te costă de 10 ori mai mult decât parsarea.

Cum controlezi asta în build-ul tău

În loc să lași bundler-ul să creeze zeci de fișiere de 2KB, poți grupa chunk-urile în mod inteligent. Dacă folosești Vite (care are Rollup sub capotă), poți folosi opțiunea manualChunks din configurare ca să comasezi modulele mici care sunt folosite în același context de business.

Tu cum abordezi problema asta? Mergi pe split agresiv la nivel de ruter sau preferi bundle-uri mai mari, dar mai puține?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

Doar membrii comunității pot lăsa comentarii.