Kurs JavaScript i React · Moduł 1: Podstawy React

Porównanie z innymi frameworkami

3 min czytania
W tej lekcji4

W kosmosie technologii frontendowych krąży wiele różnych planet-frameworków. Każda ma swój własny ekosystem, atmosferę i mieszkańców. Przyjrzyjmy się, jak React wypada na tle innych popularnych rozwiązań:

React vs Angular

Angular, stworzony i wspierany przez Google, to kompleksowy framework, który dostarcza wszystko, czego potrzebujesz do budowy aplikacji, od systemu routingu po zarządzanie formularzami i komunikację HTTP.

Różnicę między React a Angular można porównać do różnicy między modułowym statkiem kosmicznym (React), który możesz dowolnie konfigurować, a kompletną stacją kosmiczną (Angular), która ma już wszystko wbudowane.

Zalety Angular w porównaniu do React:

  • Kompletny framework z wieloma wbudowanymi narzędziami
  • Silne wsparcie dla typowania dzięki TypeScript
  • Jednoznaczna struktura projektu (mniej decyzji do podjęcia)

Zalety React w porównaniu do Angular:

  • Łagodniejsza krzywa uczenia się
  • Większa elastyczność w doborze narzędzi
  • Lżejszy i często wydajniejszy
  • Większa społeczność i ekosystem

React vs Vue

Vue.js, nazywany czasem "progresywnym frameworkiem", oferuje złoty środek między lekkością React a kompleksowością Angular.

Można to porównać do różnicy między statkiem badawczym (React), zaprojektowanym do eksploracji i odkrywania, a uniwersalnym transporterem (Vue), który jest przyjazny zarówno dla początkujących, jak i zaawansowanych pilotów.

Zalety Vue w porównaniu do React:

  • Łagodniejsza krzywa uczenia się
  • Bardziej intuicyjna składnia szablonów
  • Wbudowane rozwiązania dla często używanych funkcji

Zalety React w porównaniu do Vue:

  • Większy ekosystem i wsparcie społeczności
  • Lepsze wsparcie dla mobilnych aplikacji (React Native)
  • Większa dostępność doświadczonych deweloperów na rynku pracy

React vs Svelte

Svelte reprezentuje nową generację frameworków, gdzie magia dzieje się głównie podczas kompilacji, a nie w przeglądarce użytkownika.

To jak porównanie tradycyjnego silnika spalinowego (React), który potrzebuje paliwa (czasu procesora) aby działać, z nowoczesnym silnikiem elektrycznym (Svelte), który jest bardziej wydajny i prosty w budowie.

Zalety Svelte w porównaniu do React:

  • Mniejszy rozmiar kodu wynikowego
  • Często lepsza wydajność, szczególnie na słabszych urządzeniach
  • Bardziej intuicyjna składnia, bliższa "czystemu" HTML/CSS/JS

Zalety React w porównaniu do Svelte:

  • Dojrzalszy ekosystem i więcej bibliotek
  • Większa społeczność i zasoby edukacyjne
  • Lepsze wsparcie dla dużych, skomplikowanych aplikacji

Porównanie wydajności

Wydajność to jeden z kluczowych aspektów przy wyborze frameworka. Warto jednak pamiętać, że w większości rzeczywistych przypadków użycia, różnice wydajności między popularnymi frameworkami są często niezauważalne dla użytkownika końcowego.

Metryki wydajności:

FrameworkRozmiar (KB)Czas ładowania (ms)Czas interakcji (ms)
React~42~300~100
Angular~63~350~120
Vue~33~280~90
Svelte~10~250~80

Pamiętaj, że te wartości są przybliżone i mogą się znacznie różnić w zależności od specyfiki projektu, optymalizacji i przypadku użycia. Często największy wpływ na wydajność ma nie tyle wybór frameworka, co jakość napisanego w nim kodu.

Kod do tej lekcji: App.jsx
1import React from 'react';
2
3// Komponent do porównania frameworków
4function FrameworkComparison({ framework, logo, pros, cons, popularApps, color }) {
5  const [isExpanded, setIsExpanded] = React.useState(false);
6
7  return (
8    <div style={{
9      border: `2px solid ${color}`,
10      borderRadius: '12px',
11      padding: '20px',
12      margin: '15px 0',
13      backgroundColor: 'white',
14      boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',
15      transition: 'transform 0.2s',
16      transform: isExpanded ? 'scale(1.02)' : 'scale(1)'
17    }}>
18      <div style={{
19        display: 'flex',
20        alignItems: 'center',
21        marginBottom: '15px',
22        cursor: 'pointer'
23      }}
24      onClick={() => setIsExpanded(!isExpanded)}
25      >
26        <div style={{
27          fontSize: '40px',
28          marginRight: '15px'
29        }}>
30          {logo}
31        </div>
32        <h3 style={{
33          color,
34          margin: 0,
35          fontSize: '1.5rem'
36        }}>
37          {framework}
38        </h3>
39        <div style={{
40          marginLeft: 'auto',
41          fontSize: '20px',
42          color: '#666'
43        }}>
44          {isExpanded ? '▼' : '▶'}
45        </div>
46      </div>
47
48      {isExpanded && (
49        <div>
50          <div style={{
51            display: 'grid',
52            gridTemplateColumns: '1fr 1fr',
53            gap: '20px',
54            marginBottom: '20px'
55          }}>
56            <div>
57              <h4 style={{ color: '#28a745', marginBottom: '10px' }}>Zalety</h4>
58              <ul style={{ margin: 0, paddingLeft: '20px' }}>
59                {pros.map((pro, index) => (
60                  <li key={index} style={{ marginBottom: '5px' }}>{pro}</li>
61                ))}
62              </ul>
63            </div>
64
65            <div>
66              <h4 style={{ color: '#dc3545', marginBottom: '10px' }}>Wady</h4>
67              <ul style={{ margin: 0, paddingLeft: '20px' }}>
68                {cons.map((con, index) => (
69                  <li key={index} style={{ marginBottom: '5px' }}>{con}</li>
70                ))}
71              </ul>
72            </div>
73          </div>
74
75          <div style={{
76            backgroundColor: '#f8f9fa',
77            padding: '15px',
78            borderRadius: '8px'
79          }}>
80            <h4 style={{ margin: '0 0 10px 0', color: '#495057' }}>Popularne Aplikacje</h4>
81            <div style={{
82              display: 'flex',
83              flexWrap: 'wrap',
84              gap: '8px'
85            }}>
86              {popularApps.map((app, index) => (
87                <span key={index} style={{
88                  backgroundColor: color,
89                  color: 'white',
90                  padding: '4px 12px',
91                  borderRadius: '15px',
92                  fontSize: '14px'
93                }}>
94                  {app}
95                </span>
96              ))}
97            </div>
98          </div>
99        </div>
100      )}
101    </div>
102  );
103}
104
105// Interaktywny komponent do porównywania wydajności
106function PerformanceComparison() {
107  const [selectedFramework, setSelectedFramework] = React.useState('React');
108
109  const frameworks = {
110    React: { size: 42, loadTime: 300, interactionTime: 100, color: '#61dafb' },
111    Angular: { size: 63, loadTime: 350, interactionTime: 120, color: '#dd0031' },
112    Vue: { size: 33, loadTime: 280, interactionTime: 90, color: '#4fc08d' },
113    Svelte: { size: 10, loadTime: 250, interactionTime: 80, color: '#ff3e00' }
114  };
115
116  const current = frameworks[selectedFramework];
117
118  return (
119    <div style={{
120      backgroundColor: '#f8f9fa',
121      padding: '25px',
122      borderRadius: '12px',
123      margin: '20px 0'
124    }}>
125      <h3 style={{ textAlign: 'center', marginBottom: '20px', color: '#333' }}>
126        Porównanie Wydajności Frameworków
127      </h3>
128
129      <div style={{
130        display: 'flex',
131        justifyContent: 'center',
132        marginBottom: '25px',
133        flexWrap: 'wrap',
134        gap: '10px'
135      }}>
136        {Object.keys(frameworks).map(framework => (
137          <button
138            key={framework}
139            onClick={() => setSelectedFramework(framework)}
140            style={{
141              padding: '10px 20px',
142              backgroundColor: selectedFramework === framework ? frameworks[framework].color : '#fff',
143              color: selectedFramework === framework ? 'white' : '#333',
144              border: `2px solid ${frameworks[framework].color}`,
145              borderRadius: '25px',
146              cursor: 'pointer',
147              fontSize: '14px',
148              fontWeight: 'bold',
149              transition: 'all 0.3s'
150            }}
151          >
152            {framework}
153          </button>
154        ))}
155      </div>
156
157      <div style={{
158        display: 'grid',
159        gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))',
160        gap: '20px'
161      }}>
162        <div style={{
163          backgroundColor: 'white',
164          padding: '20px',
165          borderRadius: '8px',
166          textAlign: 'center',
167          border: '1px solid #dee2e6'
168        }}>
169          <h4 style={{ margin: '0 0 10px 0', color: '#666' }}>Rozmiar Bundla</h4>
170          <div style={{ fontSize: '2rem', fontWeight: 'bold', color: current.color }}>
171            {current.size} KB
172          </div>
173          <div style={{
174            height: '10px',
175            backgroundColor: '#e9ecef',
176            borderRadius: '5px',
177            margin: '10px 0',
178            overflow: 'hidden'
179          }}>
180            <div style={{
181              height: '100%',
182              backgroundColor: current.color,
183              width: `${(current.size / 70) * 100}%`,
184              transition: 'width 0.5s'
185            }}></div>
186          </div>
187        </div>
188
189        <div style={{
190          backgroundColor: 'white',
191          padding: '20px',
192          borderRadius: '8px',
193          textAlign: 'center',
194          border: '1px solid #dee2e6'
195        }}>
196          <h4 style={{ margin: '0 0 10px 0', color: '#666' }}>Czas Ładowania</h4>
197          <div style={{ fontSize: '2rem', fontWeight: 'bold', color: current.color }}>
198            {current.loadTime} ms
199          </div>
200          <div style={{
201            height: '10px',
202            backgroundColor: '#e9ecef',
203            borderRadius: '5px',
204            margin: '10px 0',
205            overflow: 'hidden'
206          }}>
207            <div style={{
208              height: '100%',
209              backgroundColor: current.color,
210              width: `${(current.loadTime / 400) * 100}%`,
211              transition: 'width 0.5s'
212            }}></div>
213          </div>
214        </div>
215
216        <div style={{
217          backgroundColor: 'white',
218          padding: '20px',
219          borderRadius: '8px',
220          textAlign: 'center',
221          border: '1px solid #dee2e6'
222        }}>
223          <h4 style={{ margin: '0 0 10px 0', color: '#666' }}>Czas Interakcji</h4>
224          <div style={{ fontSize: '2rem', fontWeight: 'bold', color: current.color }}>
225            {current.interactionTime} ms
226          </div>
227          <div style={{
228            height: '10px',
229            backgroundColor: '#e9ecef',
230            borderRadius: '5px',
231            margin: '10px 0',
232            overflow: 'hidden'
233          }}>
234            <div style={{
235              height: '100%',
236              backgroundColor: current.color,
237              width: `${(current.interactionTime / 150) * 100}%`,
238              transition: 'width 0.5s'
239            }}></div>
240          </div>
241        </div>
242      </div>
243
244      <p style={{
245        textAlign: 'center',
246        marginTop: '20px',
247        fontSize: '14px',
248        color: '#666',
249        fontStyle: 'italic'
250      }}>
251        * Wartości są przybliżone i mogą się różnić w zależności od specyfiki projektu
252      </p>
253    </div>
254  );
255}
256
257export default function App() {
258  const [activeTab, setActiveTab] = React.useState('comparison');
259
260  return (
261    <div style={{
262      fontFamily: 'Arial, sans-serif',
263      maxWidth: '1000px',
264      margin: '0 auto',
265      padding: '20px'
266    }}>
267      <header style={{
268        textAlign: 'center',
269        marginBottom: '30px',
270        padding: '25px',
271        background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
272        color: 'white',
273        borderRadius: '12px'
274      }}>
275        <h1 style={{ margin: '0 0 10px 0', fontSize: '2.2rem' }}>
276          React vs Inne Frameworki
277        </h1>
278        <p style={{ margin: 0, fontSize: '1rem', opacity: 0.9 }}>
279          Porównanie najpopularniejszych rozwiązań frontendowych
280        </p>
281      </header>
282
283      <div style={{
284        display: 'flex',
285        justifyContent: 'center',
286        marginBottom: '30px',
287        gap: '10px'
288      }}>
289        <button
290          onClick={() => setActiveTab('comparison')}
291          style={{
292            padding: '12px 24px',
293            backgroundColor: activeTab === 'comparison' ? '#667eea' : 'white',
294            color: activeTab === 'comparison' ? 'white' : '#333',
295            border: '2px solid #667eea',
296            borderRadius: '8px',
297            cursor: 'pointer',
298            fontWeight: 'bold'
299          }}
300        >
301          Porównanie Funkcji
302        </button>
303
304        <button
305          onClick={() => setActiveTab('performance')}
306          style={{
307            padding: '12px 24px',
308            backgroundColor: activeTab === 'performance' ? '#667eea' : 'white',
309            color: activeTab === 'performance' ? 'white' : '#333',
310            border: '2px solid #667eea',
311            borderRadius: '8px',
312            cursor: 'pointer',
313            fontWeight: 'bold'
314          }}
315        >
316          Wydajność
317        </button>
318      </div>
319
320      {activeTab === 'comparison' && (
321        <div>
322          <FrameworkComparison
323            framework="React"
324            logo="◆"
325            color="#61dafb"
326            pros={[
327              "Elastyczność w doborze narzędzi",
328              "Ogromny ekosystem",
329              "Silna społeczność",
330              "React Native dla mobile",
331              "Łagodna krzywa uczenia"
332            ]}
333            cons={[
334              "Wymaga dodatkowych bibliotek",
335              "Szybko zmieniający się ekosystem",
336              "JSX może być mylący na początku"
337            ]}
338            popularApps={["Facebook", "Instagram", "Netflix", "Airbnb", "Uber"]}
339          />
340
341          <FrameworkComparison
342            framework="Angular"
343            logo="A"
344            color="#dd0031"
345            pros={[
346              "Kompletny framework",
347              "Silne wsparcie TypeScript",
348              "Jednoznaczna struktura",
349              "Potężne CLI",
350              "Enterprise-ready"
351            ]}
352            cons={[
353              "Stroma krzywa uczenia",
354              "Większy bundle size",
355              "Może być nadmiarowy dla małych projektów"
356            ]}
357            popularApps={["Google", "Microsoft Office", "Samsung", "Deutsche Bank"]}
358          />
359
360          <FrameworkComparison
361            framework="Vue.js"
362            logo="◆"
363            color="#4fc08d"
364            pros={[
365              "Łagodna krzywa uczenia",
366              "Intuicyjna składnia",
367              "Dobra dokumentacja",
368              "Progresywne podejście",
369              "Mniejszy rozmiar"
370            ]}
371            cons={[
372              "Mniejszy ekosystem",
373              "Mniej ofert pracy",
374              "Młodsza społeczność"
375            ]}
376            popularApps={["GitLab", "Adobe", "Nintendo", "BMW", "Louis Vuitton"]}
377          />
378
379          <FrameworkComparison
380            framework="Svelte"
381            logo="◆"
382            color="#ff3e00"
383            pros={[
384              "Brak Virtual DOM",
385              "Bardzo mały bundle",
386              "Kompilacja w build time",
387              "Prostota składni",
388              "Świetna wydajność"
389            ]}
390            cons={[
391              "Mały ekosystem",
392              "Ograniczone narzędzia",
393              "Młoda technologia",
394              "Mało deweloperów"
395            ]}
396            popularApps={["The New York Times", "Apple", "Spotify", "IKEA"]}
397          />
398        </div>
399      )}
400
401      {activeTab === 'performance' && <PerformanceComparison />}
402
403      <div style={{
404        backgroundColor: '#e8f5e8',
405        padding: '25px',
406        borderRadius: '12px',
407        marginTop: '30px'
408      }}>
409        <h3 style={{ color: '#2e7d32', textAlign: 'center', marginBottom: '15px' }}>
410          Który Framework Wybrać?
411        </h3>
412        <div style={{
413          display: 'grid',
414          gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))',
415          gap: '15px'
416        }}>
417          <div style={{ textAlign: 'center', padding: '15px' }}>
418            <h4 style={{ color: '#1976d2' }}>Dla Początkujących</h4>
419            <p style={{ margin: 0 }}>Vue.js lub React</p>
420          </div>
421          <div style={{ textAlign: 'center', padding: '15px' }}>
422            <h4 style={{ color: '#1976d2' }}>Dla Enterprise</h4>
423            <p style={{ margin: 0 }}>Angular</p>
424          </div>
425          <div style={{ textAlign: 'center', padding: '15px' }}>
426            <h4 style={{ color: '#1976d2' }}>Dla Wydajności</h4>
427            <p style={{ margin: 0 }}>Svelte</p>
428          </div>
429          <div style={{ textAlign: 'center', padding: '15px' }}>
430            <h4 style={{ color: '#1976d2' }}>Dla Ekosystemu</h4>
431            <p style={{ margin: 0 }}>React</p>
432          </div>
433        </div>
434      </div>
435    </div>
436  );
437}

Widzisz błąd w tej lekcji?

Sprawdź się

Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.

  1. 1. Czym React różni się od pełnych frameworków jak Angular?

  2. 2. Co oznacza deklaratywne programowanie w React?

Przydatne artykuły