Bevezetés
A mobil eszközök használata az internetböngészésben mára dominánssá vált. A StatCounter adatai szerint a globális webes forgalom több mint 55%-a mobileszközökről érkezik. Ennek ellenére sok weboldal továbbra is elsősorban asztali felhasználókra optimalizált, ami a mobilfelhasználók számára lassú betöltési időt és frusztráló élményt eredményez.
A mobilbarát oldalsebesség optimalizálása nem csupán technikai kérdés, hanem üzleti szempontból is kritikus fontosságú. A Google adatai szerint:
- A 3 másodpercnél hosszabb betöltési idejű oldalakról a látogatók 53%-a távozik
- Minden egyes másodpercnyi késés a konverziós ráta 7%-os csökkenését eredményezheti
- A mobilfelhasználók 85%-a elvárja, hogy a mobilon használt oldal legalább olyan gyors legyen, mint asztali gépen
Ebben a cikkben részletesen bemutatjuk a mobilbarát oldalsebesség optimalizálásának legjobb módszereit, gyakorlati példákkal, kódrészletekkel és lépésről lépésre követhető útmutatókkal. Akár kezdő webfejlesztő vagy, akár már tapasztaltabb szakember, ezek a technikák segítenek jelentősen javítani mobiloldalaid teljesítményét.
1. A mobilsebesség mérése és elemzése
Mielőtt bármilyen optimalizálást végeznénk, fontos megérteni, hogy jelenleg hogyan teljesít az oldalunk. Ehhez számos eszköz áll rendelkezésünkre.
1.1. Google PageSpeed Insights
A Google PageSpeed Insights (PSI) az egyik legismertebb eszköz a weboldal teljesítményének mérésére. Valós felhasználói adatokat (Field Data) és laboratóriumi méréseket (Lab Data) egyaránt biztosít.
Hogyan használjuk:
- Látogassunk el a PageSpeed Insights oldalára
- Írjuk be a vizsgálandó weboldal URL-jét
- Kattintsunk az „Analyze” gombra
A jelentés részletes információkat nyújt a Core Web Vitals metrikákról:
- Largest Contentful Paint (LCP): A legnagyobb tartalmi elem betöltési ideje
- First Input Delay (FID): Az első interakció késleltetése
- Cumulative Layout Shift (CLS): Kumulatív elrendezés-eltolódás
1.2. Lighthouse
A Lighthouse a Chrome DevTools beépített teljesítményelemző eszköze, amely átfogó jelentést készít a weboldal teljesítményéről, hozzáférhetőségéről, SEO-ról és egyéb szempontokról.
Hogyan használjuk:
- Nyissuk meg a Chrome böngészőt
- Nyomjuk meg az F12 billentyűt vagy kattintsunk jobb gombbal az oldalon és válasszuk a „Vizsgálat” opciót
- Navigáljunk a „Lighthouse” fülre
- Válasszuk ki a „Mobile” eszközt és a kívánt kategóriákat
- Kattintsunk a „Generate report” gombra
1.3. WebPageTest
A WebPageTest egy fejlettebb teljesítményelemző eszköz, amely lehetővé teszi különböző helyszínekről, különböző böngészőkkel és kapcsolati sebességekkel történő tesztelést.
Hogyan használjuk:
- Látogassunk el a WebPageTest oldalára
- Írjuk be a vizsgálandó weboldal URL-jét
- Válasszuk ki a tesztelési helyszínt és a böngészőt
- Állítsuk be a kapcsolat típusát (pl. 3G, 4G)
- Kattintsunk a „Start Test” gombra
1.4. Teljesítménymérés kódban
JavaScript segítségével saját teljesítményméréseket is végezhetünk. A Performance API lehetővé teszi különböző metrikák mérését közvetlenül a kódban.
// Oldal betöltési idejének mérése
window.addEventListener('load', function() {
// Navigáció kezdetétől a betöltés befejezéséig eltelt idő
const pageLoadTime = performance.timing.loadEventEnd - performance.timing.navigationStart;
console.log(`Oldal betöltési ideje: ${pageLoadTime}ms`);
// Különböző teljesítménymetrikák lekérése
const perfEntries = performance.getEntriesByType('navigation');
console.log('Részletes teljesítményadatok:', perfEntries);
});
2. Képek optimalizálása
A képek általában a weboldal legnagyobb méretű erőforrásai, ezért optimalizálásuk kritikus fontosságú a mobilsebesség szempontjából.
2.1. Képformátumok helyes megválasztása
WebP formátum használata:
A WebP egy modern képformátum, amely jelentősen kisebb fájlméreteket biztosít a hagyományos formátumokhoz képest, miközben megőrzi a képminőséget.
<!-- WebP kép használata fallback-kel -->
<picture>
<source srcset="kep.webp" type="image/webp">
<source srcset="kep.jpg" type="image/jpeg">
<img src="kep.jpg" alt="Leírás" loading="lazy">
</picture>
AVIF formátum:
Az AVIF még újabb formátum, amely még jobb tömörítést kínál, mint a WebP:
<picture>
<source srcset="kep.avif" type="image/avif">
<source srcset="kep.webp" type="image/webp">
<source srcset="kep.jpg" type="image/jpeg">
<img src="kep.jpg" alt="Leírás" loading="lazy">
</picture>
2.2. Reszponzív képek
A reszponzív képek használata lehetővé teszi, hogy a különböző eszközökhöz különböző méretű képeket szolgáljunk ki.
<img
src="kep-small.jpg"
srcset="kep-small.jpg 400w, kep-medium.jpg 800w, kep-large.jpg 1200w"
sizes="(max-width: 600px) 100vw, (max-width: 1200px) 50vw, 33vw"
alt="Leírás"
loading="lazy">
2.3. Képek lusta betöltése (lazy loading)
A lusta betöltés lehetővé teszi, hogy a képek csak akkor töltődjenek be, amikor a felhasználó közel görget hozzájuk.
<!-- Natív lazy loading -->
<img src="kep.jpg" alt="Leírás" loading="lazy">
JavaScript alapú megoldással még több kontrollunk lehet:
document.addEventListener("DOMContentLoaded", function() {
const lazyImages = document.querySelectorAll('img.lazy');
if ('IntersectionObserver' in window) {
const imageObserver = new IntersectionObserver(function(entries, observer) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.classList.remove('lazy');
imageObserver.unobserve(img);
}
});
});
lazyImages.forEach(function(img) {
imageObserver.observe(img);
});
} else {
// Fallback megoldás régebbi böngészőkhöz
// ...
}
});
2.4. Képek tömörítése
A képek méretének csökkentése kulcsfontosságú a gyorsabb betöltéshez. Több eszköz is rendelkezésre áll:
- ImageOptim: Asztali alkalmazás (Mac)
- TinyPNG: Online szolgáltatás
- Squoosh: Google fejlesztésű online képoptimalizáló
- npm csomagok: sharp, imagemin
Példa képoptimalizálásra Gulp és imagemin használatával:
const gulp = require('gulp');
const imagemin = require('gulp-imagemin');
const webp = require('imagemin-webp');
gulp.task('optimizeImages', () => {
return gulp.src('src/images/**/*.{jpg,png,jpeg}')
.pipe(imagemin([
imagemin.mozjpeg({ quality: 75, progressive: true }),
imagemin.optipng({ optimizationLevel: 5 })
]))
.pipe(gulp.dest('dist/images'));
});
gulp.task('createWebP', () => {
return gulp.src('src/images/**/*.{jpg,png,jpeg}')
.pipe(imagemin([
webp({ quality: 75 })
]))
.pipe(gulp.rename({ extname: '.webp' }))
.pipe(gulp.dest('dist/images'));
});
3. CSS és JavaScript optimalizálása
3.1. CSS optimalizálása
3.1.1. Kritikus CSS elkülönítése
A kritikus CSS az a minimális CSS, amely az első képernyőnyi tartalom megjelenítéséhez szükséges. Ennek inline beágyazása gyorsabb kezdeti megjelenítést tesz lehetővé.
<head>
<style>
/* Kritikus CSS közvetlenül beágyazva */
body { font-family: Arial, sans-serif; margin: 0; padding: 0; }
header { background-color: #f8f8f8; padding: 20px; }
.hero { height: 50vh; background-color: #eee; }
/* ... */
</style>
<!-- Nem kritikus CSS késleltetett betöltése -->
<link rel="preload" href="styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="styles.css"></noscript>
</head>
A kritikus CSS generálásához használhatunk olyan eszközöket, mint a Critical, CriticalCSS vagy a Penthouse.
3.1.2. CSS minifikálása és tömörítése
A minifikálás eltávolítja a felesleges karaktereket (szóközök, kommentek, sortörések) a CSS fájlokból.
// Webpack példa cssminimizerwebpackplugin használatával
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = {
plugins: [new MiniCssExtractPlugin()],
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
}
]
},
optimization: {
minimizer: [
new CssMinimizerPlugin()
]
}
};
3.1.3. Felesleges CSS eltávolítása
A nem használt CSS szabályok eltávolítása jelentősen csökkentheti a fájlméretet. Erre szolgál a PurgeCSS vagy az UnCSS.
// PurgeCSS használata PostCSS-sel
// postcss.config.js
module.exports = {
plugins: [
require('autoprefixer'),
require('@fullhuman/postcss-purgecss')({
content: ['./src/**/*.html', './src/**/*.js'],
defaultExtractor: content => content.match(/[\w-/:]+(?<!:)/g) || []
})
]
};
3.2. JavaScript optimalizálása
3.2.1. Kód felosztása (code splitting)
A kód felosztása lehetővé teszi, hogy csak azt a JavaScript kódot töltsük be, amire ténylegesen szükség van az adott oldalon.
// Webpack dynamic import
const button = document.querySelector('button');
button.addEventListener('click', e => {
import('./nagyModul.js')
.then(module => {
module.inicializalas();
})
.catch(err => {
console.log('Modul betöltési hiba:', err);
});
});
3.2.2. JavaScript késleltetett betöltése
A nem kritikus JavaScript késleltetett betöltése javítja a kezdeti betöltési időt.
<!-- Defer attribútum használata -->
<script src="nem-kritikus.js" defer></script>
<!-- Async attribútum használata -->
<script src="analitika.js" async></script>
3.2.3. JavaScript minifikálása és tömörítése
A Terser vagy UglifyJS használata a JavaScript kód méretének csökkentésére:
// Webpack konfiguráció Terser használatával
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimize: true,
minimizer: [new TerserPlugin({
terserOptions: {
compress: {
drop_console: true,
},
mangle: true,
},
})],
},
};
4. Szerver oldali optimalizálások
4.1. HTTP/2 használata
A HTTP/2 protokoll számos előnyt kínál a HTTP/1.1-gyel szemben, különösen a mobil teljesítmény szempontjából:
- Multiplexing: több kérés kezelése egyetlen kapcsolaton keresztül
- Header tömörítés
- Server push
Apache szerveren a HTTP/2 engedélyezése:
# Apache konfiguráció HTTP/2 engedélyezéséhez
<VirtualHost *:443>
Protocols h2 http/1.1
# További konfiguráció...
</VirtualHost>
Nginx szerveren:
# Nginx konfiguráció HTTP/2 engedélyezéséhez
server {
listen 443 ssl http2;
# További konfiguráció...
}
4.2. Gyorsítótárazás (caching) beállítása
A megfelelő gyorsítótárazási szabályok beállítása jelentősen csökkentheti a visszatérő látogatók betöltési idejét.
# Apache .htaccess fájl
<IfModule mod_expires.c>
ExpiresActive On
# Képek
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
# CSS, JavaScript
ExpiresByType text/css "access plus 1 month"
ExpiresByType text/javascript "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
# HTML
ExpiresByType text/html "access plus 0 seconds"
</IfModule>
<IfModule mod_headers.c>
<FilesMatch "\.(js|css|xml|gz)$">
Header append Vary: Accept-Encoding
</FilesMatch>
</IfModule>
Nginx konfiguráció:
# Nginx konfiguráció
location ~* \.(jpg|jpeg|png|webp|svg|gif)$ {
expires 1y;
add_header Cache-Control "public, no-transform";
}
location ~* \.(css|js)$ {
expires 1M;
add_header Cache-Control "public, no-transform";
}
4.3. Tömörítés engedélyezése
A GZIP vagy Brotli tömörítés használata jelentősen csökkentheti az átvitt adatok méretét.
# Apache .htaccess GZIP tömörítés
<IfModule mod_deflate.c>
# Tömörítés bekapcsolása
SetOutputFilter DEFLATE
# Tömörítendő MIME típusok
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/json
# Régebbi böngészők kezelése
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
# Ne tömörítse a már tömörített fájlokat
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|zip|gz|bz2|rar)$ no-gzip dont-vary
</IfModule>
Nginx Brotli konfiguráció:
# Nginx Brotli konfiguráció
http {
brotli on;
brotli_comp_level 6;
brotli_types text/plain text/css application/javascript application/json image/svg+xml application/xml+rss;
# Alternatív GZIP konfiguráció
gzip on;
gzip_comp_level 5;
gzip_min_length 256;
gzip_proxied any;
gzip_vary on;
gzip_types text/plain text/css application/javascript application/json image/svg+xml application/xml+rss;
}
4.4. CDN használata
A Content Delivery Network (CDN) használata lehetővé teszi, hogy a statikus erőforrásokat a felhasználóhoz közelebbi szerverekről szolgáljuk ki.
<!-- Cloudflare CDN használata jQuery-hez -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<!-- Google Fonts betöltése -->
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap" rel="stylesheet">
5. Frontend optimalizálási technikák
5.1. Erőforrások előtöltése (preloading) és előfeldolgozása (prefetching)
Az előtöltés és előfeldolgozás segítségével jelezhetjük a böngészőnek, hogy mely erőforrásokra lesz hamarosan szükség.
<!-- Kritikus CSS előtöltése -->
<link rel="preload" href="kritikus-stilus.css" as="style">
<!-- Következő oldalra mutató link előfeldolgozása -->
<link rel="prefetch" href="kovetkezo-oldal.html">
<!-- Betűtípus előtöltése -->
<link rel="preload" href="fonts/roboto.woff2" as="font" type="font/woff2" crossorigin>
<!-- DNS előfeldolgozás -->
<link rel="dns-prefetch" href="//example.com">
<!-- Kapcsolat előkészítése -->
<link rel="preconnect" href="https://api.example.com">
5.2. Web fontok optimalizálása
A web fontok jelentősen befolyásolhatják a betöltési időt, ezért optimalizálásuk fontos.
/* Web fontok optimalizált betöltése */
@font-face {
font-family: 'MyCoolFont';
src: url('mycool-font.woff2') format('woff2'),
url('mycool-font.woff') format('woff');
font-display: swap; /* Fontos a gyors megjelenítéshez */
font-weight: 400;
font-style: normal;
}
A font-display: swap
beállítás lehetővé teszi, hogy a böngésző először a rendszerbetűtípust használja, majd amikor a webfont betöltődött, lecserélje azt.
5.3. Animációk és átmenetek optimalizálása
A rossz teljesítményű animációk jelentősen ronthatják a mobil élményt.
/* Hatékony animációk - csak az opacity és transform tulajdonságokat használjuk */
.optimized-animation {
transition: transform 0.3s ease, opacity 0.3s ease;
}
.optimized-animation:hover {
transform: scale(1.1);
opacity: 0.8;
}
/* Animációk kikapcsolása csökkentett mozgás esetén */
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
5.4. Harmadik féltől származó szkriptek kezelése
A harmadik féltől származó szkriptek gyakran jelentősen lassítják az oldalt. Ezek kezelésére több stratégia létezik:
<!-- Analitikai kód késleltetett betöltése -->
<script>
// Analitika késleltetett betöltése
window.addEventListener('load', function() {
setTimeout(function() {
const analyticsScript = document.createElement('script');
analyticsScript.src = 'https://www.google-analytics.com/analytics.js';
document.head.appendChild(analyticsScript);
}, 5000); // 5 másodperc késleltetés
});
</script>
<!-- Közösségi média gombok lusta betöltése -->
<div class="social-placeholder" data-social-type="facebook"></div>
<script>
// Közösségi média gombok lusta betöltése
const loadSocialButtons = () => {
const placeholders = document.querySelectorAll('.social-placeholder');
placeholders.forEach(placeholder => {
const type = placeholder.dataset.socialType;
if (type === 'facebook') {
// Facebook gomb betöltése
const fbScript = document.createElement('script');
fbScript.src = 'https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v11.0';
document.head.appendChild(fbScript);
const fbDiv = document.createElement('div');
fbDiv.className = 'fb-like';
fbDiv.setAttribute('data-href', window.location.href);
fbDiv.setAttribute('data-layout', 'button');
fbDiv.setAttribute('data-action', 'like');
placeholder.appendChild(fbDiv);
}
// Más típusok kezelése...
});
};
// Csak akkor töltjük be, ha a felhasználó görget
let socialLoaded = false;
window.addEventListener('scroll', function() {
if (!socialLoaded && window.scrollY > 200) {
loadSocialButtons();
socialLoaded = true;
}
});
</script>
6. Haladó optimalizálási technikák

6.1. Service Worker és offline élmény
A Service Worker lehetővé teszi az offline élményt és a gyorsabb ismételt betöltést.
// service-worker.js
const CACHE_NAME = 'my-site-cache-v1';
const urlsToCache = [
'/',
'/styles/main.css',
'/scripts/main.js',
'/images/logo.png'
];
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME)
.then(cache => {
return cache.addAll(urlsToCache);
})
);
});
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(response => {
// Cache hit - return response
if (response) {
return response;
}
return fetch(event.request).then(
response => {
// Check if we received a valid response
if(!response || response.status !== 200 || response.type !== 'basic') {
return response;
}
// Clone the response
const responseToCache = response.clone();
caches.open(CACHE_NAME)
.then(cache => {
cache.put(event.request, responseToCache);
});
return response;
}
);
})
);
});
Service Worker regisztrálása:
// main.js
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/service-worker.js')
.then(registration => {
console.log('ServiceWorker regisztrálva:', registration.scope);
})
.catch(error => {
console.log('ServiceWorker regisztrálási hiba:', error);
});
});
}
6.2. Web Workers használata
A Web Workers lehetővé teszik a hosszabb számítások háttérszálon történő futtatását, megakadályozva a felhasználói felület blokkolását.
// main.js
const worker = new Worker('worker.js');
// Adatok küldése a worker-nek
document.querySelector('#calculate-button').addEventListener('click', () => {
const data = { numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] };
worker.postMessage(data);
// UI frissítése, hogy jelezze a feldolgozást
document.querySelector('#status').textContent = 'Számítás folyamatban...';
});
// Válasz fogadása a worker-től
worker.onmessage = function(e) {
const result = e.data;
document.querySelector('#result').textContent = `Eredmény: ${result}`;
document.querySelector('#status').textContent = 'Számítás kész!';
};
// worker.js
self.addEventListener('message', function(e) {
const data = e.data;
// Intenzív számítás szimulálása
let result = 0;
for (let i = 0; i < 1000000000; i++) {
result += i;
}
// Eredmény visszaküldése a fő szálnak
self.postMessage(result);
});
6.3. Virtuális gördítés (virtualized scrolling)
Nagy listák esetén a virtuális gördítés jelentősen javíthatja a teljesítményt, mivel csak a látható elemeket rendereli.
// React példa react-window használatával
import React from 'react';
import { FixedSizeList as List } from 'react-window';
const Row = ({ index, style }) => (
<div style={style}>
Elem #{index}
</div>
);
const VirtualizedList = () => (
<List
height={400}
itemCount={10000}
itemSize={35}
width={300}
>
{Row}
</List>
);
export default VirtualizedList;
6.4. Komponensek lusta betöltése (lazy loading)
React-ban a komponensek lusta betöltése:
// React komponensek lusta betöltése
import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
// Komponensek lusta betöltése
const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));
const Contact = lazy(() => import('./routes/Contact'));
const App = () => (
<Router>
<Suspense fallback={<div>Betöltés...</div>}>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/contact" component={Contact} />
</Switch>
</Suspense>
</Router>
);
7. Mobilspecifikus optimalizálások
7.1. Érintésoptimalizált felhasználói felület
A mobilfelhasználók érintéssel navigálnak, ezért fontos az érintésbarát felület kialakítása.
/* Érintésbarát gombok */
.touch-button {
min-width: 44px;
min-height: 44px; /* Apple ajánlása szerinti minimális méret */
padding: 12px 16px;
margin: 8px;
border-radius: 4px;
background-color: #0066cc;
color: white;
border: none;
cursor: pointer;
}
/* Érintési területek közötti távolság */
.touch-nav li {
margin-bottom: 16px;
}
/* Aktív állapot visszajelzés */
.touch-button:active {
background-color: #004499;
transform: scale(0.98);
}
7.2. Mobilbarát űrlapok
A mobilon történő űrlapkitöltés optimalizálása jelentősen javíthatja a felhasználói élményt.
<!-- Mobilbarát űrlap -->
<form>
<!-- Megfelelő input típusok -->
<div class="form-group">
<label for="email">Email cím</label>
<input type="email" id="email" autocomplete="email" inputmode="email">
</div>
<div class="form-group">
<label for="phone">Telefonszám</label>
<input type="tel" id="phone" autocomplete="tel" inputmode="tel" pattern="[0-9]{9,11}">
</div>
<div class="form-group">
<label for="number">Mennyiség</label>
<input type="number" id="number" inputmode="numeric" min="1" max="100">
</div>
<!-- Automatikus kitöltés segítése -->
<div class="form-group">
<label for="name">Teljes név</label>
<input type="text" id="name" autocomplete="name">
</div>
<div class="form-group">
<label for="address">Cím</label>
<input type="text" id="address" autocomplete="street-address">
</div>
<button type="submit" class="touch-button">Küldés</button>
</form>
7.3. Alacsony sávszélességű kapcsolatok kezelése
A Network Information API segítségével érzékelhetjük a felhasználó kapcsolatának minőségét, és ennek megfelelően optimalizálhatjuk a tartalmat.
if ('connection' in navigator) {
const connection = navigator.connection;
// Kapcsolat típusának ellenőrzése
if (connection.effectiveType === 'slow-2g' || connection.effectiveType === '2g') {
// Alacsony minőségű képek betöltése
document.querySelectorAll('img').forEach(img => {
if (img.dataset.lowSrc) {
img.src = img.dataset.lowSrc;
}
});
// Videók kikapcsolása
document.querySelectorAll('video').forEach(video => {
video.setAttribute('preload', 'none');
video.style.display = 'none';
// Helyettesítő kép megjelenítése
if (video.dataset.poster) {
const img = document.createElement('img');
img.src = video.dataset.poster;
img.alt = 'Videó előnézet';
video.parentNode.insertBefore(img, video);
}
});
}
// Változások figyelése
connection.addEventListener('change', function() {
console.log('Kapcsolat változott:', connection.effectiveType);
// Kapcsolat változás kezelése...
});
}
8. Gyakori hibák és elkerülésük
8.1. Túl sok HTTP kérés
Probléma: Minden HTTP kérés növeli a betöltési időt, különösen gyenge mobilkapcsolat esetén.
Megoldás:
- Képek sprite-ok használata
- CSS és JavaScript fájlok összevonása
- Inline SVG használata kis ikonokhoz
- HTTP/2 használata a kérések párhuzamosításához
<!-- Sprite használata -->
<style>
.icon {
background-image: url('sprites.png');
width: 24px;
height: 24px;
}
.icon-home { background-position: 0 0; }
.icon-search { background-position: -24px 0; }
.icon-settings { background-position: -48px 0; }
</style>
<div class="icon icon-home"></div>
<div class="icon icon-search"></div>
<div class="icon icon-settings"></div>
<!-- Inline SVG használata -->
<svg width="24" height="24" viewBox="0 0 24 24">
<path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z" fill="currentColor" />
</svg>
8.2. Render-blokkoló erőforrások
Probléma: A <head>
részben található CSS és JavaScript fájlok blokkolhatják az oldal renderelését.
Megoldás:
- CSS-hez használjunk
media
attribútumot vagypreload
és aszinkron betöltést - JavaScript-hez használjunk
defer
vagyasync
attribútumokat
<!-- Csak nyomtatáshoz használt CSS nem blokkolja a renderelést -->
<link rel="stylesheet" href="print.css" media="print">
<!-- Csak nagy képernyőkhöz használt CSS -->
<link rel="stylesheet" href="desktop.css" media="(min-width: 1024px)">
<!-- Kritikus CSS inline, nem kritikus aszinkron betöltése -->
<style>
/* Kritikus CSS itt */
</style>
<link rel="preload" href="non-critical.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="non-critical.css"></noscript>
<!-- JavaScript nem blokkolja a renderelést -->
<script src="analytics.js" async></script>
<script src="app.js" defer></script>
8.3. Túl nagy DOM méret
Probléma: A túl nagy és komplex DOM struktúra lassú renderelést és interakciót eredményez.
Megoldás:
- DOM elemek számának csökkentése
- Virtuális listák használata
- Felesleges konténerek eltávolítása
- Elemek újrafelhasználása ahelyett, hogy újakat hoznánk létre
// Rossz gyakorlat: sok DOM elem létrehozása
function addItems(items) {
const container = document.getElementById('container');
container.innerHTML = ''; // Törli az összes elemet
items.forEach(item => {
const div = document.createElement('div');
div.textContent = item.name;
container.appendChild(div);
});
}
// Jó gyakorlat: DocumentFragment használata
function addItemsOptimized(items) {
const container = document.getElementById('container');
const fragment = document.createDocumentFragment();
items.forEach(item => {
const div = document.createElement('div');
div.textContent = item.name;
fragment.appendChild(div);
});
container.innerHTML = ''; // Törli az összes elemet
container.appendChild(fragment); // Egyetlen DOM művelet
}
8.4. Nem optimalizált betűtípusok
Probléma: A nagy méretű betűtípus fájlok és a betűtípusok rossz betöltési stratégiája látható szövegkésést okozhat.
Megoldás:
- WOFF2 formátum használata
- Csak a szükséges karakterkészletek betöltése
- Font-display beállítása
- Betűtípusok előtöltése
/* Optimalizált betűtípus betöltés */
@font-face {
font-family: 'MyFont';
src: url('myfont-subset.woff2') format('woff2');
font-display: swap;
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
<!-- Betűtípus előtöltése -->
<link rel="preload" href="myfont-subset.woff2" as="font" type="font/woff2" crossorigin>
9. Teljesítménytesztelés és monitorozás
9.1. Teljesítmény monitorozása valós felhasználóknál
A valós felhasználói metrikák (RUM) gyűjtése lehetővé teszi a tényleges teljesítmény mérését a felhasználók eszközein.
// Performance API használata a teljesítmény mérésére
document.addEventListener('DOMContentLoaded', () => {
// Navigation Timing API
const pageNav = performance.getEntriesByType('navigation')[0];
const loadTime = pageNav.loadEventEnd - pageNav.startTime;
// Első tartalom festés (FCP)
const paintMetrics = performance.getEntriesByType('paint');
const fcpTime = paintMetrics.find(entry => entry.name === 'first-contentful-paint')?.startTime;
// Teljesítményadatok küldése az analitikai rendszernek
sendAnalytics({
pageLoadTime: loadTime,
firstContentfulPaint: fcpTime,
url: window.location.href,
userAgent: navigator.userAgent,
connectionType: navigator.connection ? navigator.connection.effectiveType : 'unknown'
});
});
function sendAnalytics(data) {
// Adatok küldése a szervernek
fetch('/analytics/performance', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data),
// Használjuk a beacon API-t, ha elérhető, hogy ne blokkolja az oldal bezárását
keepalive: true
});
}
9.2. Teljesítmény budget beállítása
A teljesítmény budget segít a weboldal teljesítményének fenntartásában azáltal, hogy határértékeket állít fel a különböző metrikákra.
// webpack-bundle-analyzer és performance-budget használata
// webpack.config.js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
// ...
performance: {
hints: 'warning',
maxAssetSize: 100000, // 100 KB
maxEntrypointSize: 300000, // 300 KB
},
plugins: [
new BundleAnalyzerPlugin({
analyzerMode: process.env.NODE_ENV === 'production' ? 'static' : 'disabled',
reportFilename: 'bundle-report.html'
})
]
};
9.3. Automatizált teljesítménytesztelés
A teljesítménytesztelés beépítése a CI/CD folyamatba biztosítja, hogy a teljesítményproblémák már a fejlesztési szakaszban kiderüljenek.
// Lighthouse CI használata
// lighthouserc.js
module.exports = {
ci: {
collect: {
url: ['https://example.com/', 'https://example.com/about'],
numberOfRuns: 3,
settings: {
// Mobil teljesítmény tesztelése
preset: 'mobile',
throttling: {
cpuSlowdownMultiplier: 4,
downloadThroughputKbps: 1600,
uploadThroughputKbps: 750,
rttMs: 150
}
}
},
assert: {
assertions: {
'categories:performance': ['error', {minScore: 0.8}],
'first-contentful-paint': ['error', {maxNumericValue: 2000}],
'interactive': ['error', {maxNumericValue: 3500}],
'max-potential-fid': ['error', {maxNumericValue: 100}],
'cumulative-layout-shift': ['error', {maxNumericValue: 0.1}],
'largest-contentful-paint': ['error', {maxNumericValue: 2500}]
}
},
upload: {
target: 'temporary-public-storage'
}
}
};
10. Összefoglalás
A mobilbarát oldalsebesség optimalizálása kritikus fontosságú a modern webfejlesztésben. Ebben a cikkben számos technikát és stratégiát ismertettünk, amelyek segítségével jelentősen javítható a mobiloldalak teljesítménye:
- Teljesítménymérés és elemzés: A PageSpeed Insights, Lighthouse és WebPageTest eszközök használata a jelenlegi teljesítmény értékeléséhez és a problématerületek azonosításához.
- Képoptimalizálás: Modern képformátumok (WebP, AVIF) használata, reszponzív képek implementálása, képek lusta betöltése és hatékony tömörítése.
- CSS és JavaScript optimalizálás: Kritikus CSS elkülönítése, kód minifikálása és tömörítése, felesleges kód eltávolítása, kód felosztása és aszinkron betöltése.
- Szerver oldali optimalizálások: HTTP/2 használata, megfelelő gyorsítótárazási beállítások, GZIP/Brotli tömörítés és CDN használata a statikus tartalmakhoz.
- Frontend optimalizálási technikák: Erőforrások előtöltése és előfeldolgozása, web fontok optimalizálása, animációk és átmenetek optimalizálása, harmadik féltől származó szkriptek megfelelő kezelése.
- Haladó technikák: Service Worker implementálása offline élményhez, Web Worker használata intenzív számításokhoz, virtuális gördítés nagy listákhoz és komponensek lusta betöltése.
- Mobilspecifikus optimalizálások: Érintésoptimalizált felhasználói felület, mobilbarát űrlapok és alacsony sávszélességű kapcsolatok kezelése.
- Gyakori hibák elkerülése: Túl sok HTTP kérés csökkentése, render-blokkoló erőforrások elkerülése, DOM méret optimalizálása és betűtípusok megfelelő kezelése.
- Teljesítménytesztelés és monitorozás: Valós felhasználói metrikák gyűjtése, teljesítmény budget beállítása és automatizált teljesítménytesztelés a fejlesztési folyamatba integrálva.
A mobilbarát oldalsebesség optimalizálása nem egyszeri feladat, hanem folyamatos törekvés, amely a fejlesztési folyamat minden szakaszában figyelmet igényel. Az ebben a cikkben bemutatott technikák alkalmazásával jelentősen javíthatod weboldalad teljesítményét, ami jobb felhasználói élményt, magasabb konverziós arányt és jobb keresőmotor-helyezéseket eredményezhet.
Ne feledd, hogy a teljesítményoptimalizálás során a legfontosabb a felhasználói élmény javítása. Mindig mérd a változtatások hatását, és azokra a területekre összpontosíts, amelyek a legnagyobb javulást eredményezik a felhasználók számára.