Sveobuhvatan vodič za tehnike razdvajanja koda na frontendu, s fokusom na pristupe temeljene na rutama i komponentama za bolje performanse i korisničko iskustvo.
Razdvajanje koda na frontendu: pristup temeljen na rutama i komponentama
U svijetu modernog web razvoja, pružanje brzog i responzivnog korisničkog iskustva je ključno. Kako aplikacije postaju složenije, veličina JavaScript paketa (bundles) može narasti, što dovodi do duljeg početnog vremena učitavanja i tromog korisničkog iskustva. Razdvajanje koda (code splitting) je moćna tehnika za rješavanje ovog problema razbijanjem koda aplikacije na manje, lakše upravljive dijelove (chunks) koji se mogu učitavati na zahtjev.
Ovaj vodič istražuje dvije osnovne strategije za razdvajanje koda na frontendu: temeljenu na rutama i temeljenu na komponentama. Zaronit ćemo u principe iza svakog pristupa, raspraviti o njihovim prednostima i nedostacima te pružiti praktične primjere kako bismo ilustrirali njihovu implementaciju.
Što je razdvajanje koda?
Razdvajanje koda je praksa dijeljenja monolitnog JavaScript paketa na manje pakete ili dijelove. Umjesto učitavanja cjelokupnog koda aplikacije unaprijed, učitava se samo nužan kod za trenutni prikaz ili komponentu. To smanjuje početnu veličinu preuzimanja, što dovodi do bržeg vremena učitavanja stranice i poboljšanih percipiranih performansi.
Glavne prednosti razdvajanja koda uključuju:
- Poboljšano početno vrijeme učitavanja: Manje početne veličine paketa znače brže vrijeme učitavanja i bolji prvi dojam za korisnike.
- Smanjeno vrijeme parsiranja i kompilacije: Preglednici troše manje vremena na parsiranje i kompilaciju manjih paketa, što rezultira bržim renderiranjem.
- Poboljšano korisničko iskustvo: Brže vrijeme učitavanja doprinosi glađem i responzivnijem korisničkom iskustvu.
- Optimizirano korištenje resursa: Učitava se samo nužan kod, čime se štedi propusnost i resursi uređaja.
Razdvajanje koda temeljeno na rutama
Razdvajanje koda temeljeno na rutama uključuje podjelu koda aplikacije na temelju ruta ili stranica aplikacije. Svaka ruta odgovara zasebnom dijelu koda koji se učitava tek kada korisnik prijeđe na tu rutu. Ovaj pristup je posebno učinkovit za aplikacije s različitim odjeljcima ili značajkama kojima se ne pristupa često.
Implementacija
Moderni JavaScript okviri poput Reacta, Angulara i Vuea pružaju ugrađenu podršku za razdvajanje koda temeljeno na rutama, često koristeći dinamičke importe. Evo kako to konceptualno funkcionira:
- Definirajte rute: Definirajte rute aplikacije koristeći biblioteku za usmjeravanje kao što su React Router, Angular Router ili Vue Router.
- Koristite dinamičke importe: Umjesto izravnog importiranja komponenti, koristite dinamičke importe (
import()) kako biste ih asinkrono učitali kada se aktivira odgovarajuća ruta. - Konfigurirajte alat za izgradnju (build tool): Konfigurirajte svoj alat za izgradnju (npr. webpack, Parcel, Rollup) da prepozna dinamičke importe i stvori zasebne dijelove (chunks) za svaku rutu.
Primjer (React s React Routerom)
Uzmimo u obzir jednostavnu React aplikaciju s dvije rute: /home i /about.
// App.js
import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
const Home = lazy(() => import('./components/Home'));
const About = lazy(() => import('./components/About'));
function App() {
return (
Loading... U ovom primjeru, komponente Home i About učitavaju se lijeno (lazily) pomoću React.lazy() i dinamičkih importa. Komponenta Suspense pruža zamjensko sučelje (fallback UI) dok se komponente učitavaju. React Router upravlja navigacijom i osigurava da se ispravna komponenta renderira na temelju trenutne rute.
Primjer (Angular)
U Angularu se razdvajanje koda temeljeno na rutama postiže korištenjem lijeno učitanih modula (lazy-loaded modules).
// app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [
{ path: 'home', loadChildren: () => import('./home/home.module').then(m => m.HomeModule) },
{ path: 'about', loadChildren: () => import('./about/about.module').then(m => m.AboutModule) }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Ovdje, svojstvo loadChildren u konfiguraciji rute specificira put do modula koji bi se trebao lijeno učitati. Angularov usmjerivač (router) automatski će učitati modul i s njim povezane komponente tek kada korisnik prijeđe na odgovarajuću rutu.
Primjer (Vue.js)
Vue.js također podržava razdvajanje koda temeljeno na rutama koristeći dinamičke importe u konfiguraciji usmjerivača.
// router.js
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
const routes = [
{ path: '/', component: () => import('./components/Home.vue') },
{ path: '/about', component: () => import('./components/About.vue') }
];
const router = new VueRouter({
routes
});
export default router;
Opcija component u konfiguraciji rute koristi dinamički import za asinkrono učitavanje komponente. Vue Router će se pobrinuti za učitavanje i renderiranje komponente kada se pristupi ruti.
Prednosti razdvajanja koda temeljenog na rutama
- Jednostavno za implementaciju: Razdvajanje koda temeljeno na rutama relativno je jednostavno za implementaciju, posebno uz podršku koju pružaju moderni okviri.
- Jasno razdvajanje odgovornosti: Svaka ruta predstavlja zaseban dio aplikacije, što olakšava razumijevanje koda i njegovih ovisnosti.
- Učinkovito za velike aplikacije: Razdvajanje koda temeljeno na rutama posebno je korisno za velike aplikacije s mnogo ruta i značajki.
Nedostaci razdvajanja koda temeljenog na rutama
- Možda nije dovoljno granulirano: Razdvajanje koda temeljeno na rutama možda neće biti dovoljno za aplikacije sa složenim komponentama koje se dijele između više ruta.
- Početno vrijeme učitavanja i dalje može biti dugo: Ako ruta sadrži mnogo ovisnosti, početno vrijeme učitavanja za tu rutu i dalje može biti značajno.
Razdvajanje koda temeljeno na komponentama
Razdvajanje koda temeljeno na komponentama podiže razdvajanje koda na višu razinu dijeljenjem koda aplikacije na manje dijelove temeljene na pojedinačnim komponentama. Ovaj pristup omogućuje granuliraniju kontrolu nad učitavanjem koda i može biti posebno učinkovit za aplikacije sa složenim korisničkim sučeljima i višekratno iskoristivim komponentama.
Implementacija
Razdvajanje koda temeljeno na komponentama također se oslanja na dinamičke importe, ali umjesto učitavanja cijelih ruta, pojedinačne komponente se učitavaju na zahtjev. To se može postići tehnikama kao što su:
- Lijeno učitavanje komponenti: Koristite dinamičke importe za učitavanje komponenti samo kada su potrebne, kao što je prilikom njihovog prvog renderiranja ili kada se dogodi određeni događaj.
- Uvjetno renderiranje: Renderirajte komponente uvjetno na temelju interakcije korisnika ili drugih čimbenika, učitavajući kod komponente samo kada je uvjet ispunjen.
- Intersection Observer API: Koristite Intersection Observer API za otkrivanje kada je komponenta vidljiva u prozoru preglednika (viewport) i učitajte njezin kod u skladu s tim. Ovo je posebno korisno za učitavanje komponenti koje su u početku izvan ekrana.
Primjer (React)
import React, { Suspense, lazy } from 'react';
const MyComponent = lazy(() => import('./MyComponent'));
function App() {
return (
Loading... }>