WordPress wordt standaard geleverd met de volgende standaard afbeeldingsformaten:
Thumbnail: 150px square
Medium: maximum width of 300px
Medium Large: maximum width of 768px
Large: maximum width of 1024px
Full: original image size
Bij elke upload van media probeert WordPress deze afbeeldingsformaten voor je aan te maken. Zo kun je deze gebruiken bij het invoegen van media in de WYSIWYG-editor. (het medium grote formaat is hier niet beschikbaar) of door een van de ingebouwde WordPress-functies aan te roepen, zoals wp_get_attachment_image_src.
Voor standaardsjablonen met een brede headerafbeelding (16:9 crop-verhouding) upload je de afbeelding op ware grootte met de juiste verhouding.
<?php
$img_id = get_post_thumbnail_id();
$img_full = wp_get_attachment_image_src($img_id, 'full');
$img_alt = get_post_meta($img_id, '_wp_attachment_image_alt', true);
?>
<img class="my-header" src="<?= $img_full[0]; ?>" alt="<?= $img_alt; ?>" />
Maar omdat het serveren van te grote afbeeldingen op je website een van de zwaarste prestatiestraffen heeft in snelheidstestprogramma's zoals GTmetrix, PageSpeed Insights of Experte Page Speed Test en prestaties steeds belangrijker worden in SEO-ranking, wordt dit beschouwd als een slechte gewoonte.
Daarnaast werkt het uploaden van afbeeldingen met de juiste 16:9-verhouding alleen als je je weg weet in Photoshop.
Aangepaste afbeeldingsformaten
Dus waarom geen extra aangepast afbeeldingsformaat toevoegen met de functie add_image_size?
add_image_size('header', 1280, 720, true);
Nu zal WordPress dit formaat voor je maken en bijsnijden voor elke media upload, zodat je het kunt gebruiken in je sjabloon:
<?php
$img_id = get_post_thumbnail_id();
$img_header = wp_get_attachment_image_src($img_id, 'header');
$img_alt = get_post_meta($img_id, '_wp_attachment_image_alt', true);
?>
<img
class="my-header" src="<?= $img_header[0]; ?>"
alt="<?= $img_alt; ?>"
/>
Dit lost het verhoudingsprobleem op en het lost ook gedeeltelijk het prestatieprobleem op, omdat de afbeelding wordt verkleind tot 1280px, maar je website kan mogelijk nog steeds een afbeelding van 1280px breed weergeven aan een bezoeker op een mobiel scherm van slechts 640px breed. Dat is dus een verlies van 200%!
Je kunt dus een extra header toevoegen voor kleinere schermen met dezelfde crop ratio:
add_image_size('header-mobile', 640, 360, true);
En het als volgt weergeven:
<?php
$img_id = get_post_thumbnail_id();
$img_header = wp_get_attachment_image_src($img_id, 'header');
$img_header_mobile = wp_get_attachment_image_src($img_id, 'header-mobile');
$img_alt = get_post_meta($img_id, '_wp_attachment_image_alt', true);
?>
<img
class="my-header"
srcset="<?= $img_header_mobile[0]; ?> 640w, <?= $img_header[0]; ?> 1280w"
sizes="(max-width: 640px) 640px, 1280px"
alt="<?= $img_alt; ?>"
/>
Retina-ondersteuning
Maar wat als je een retinaversie van de headerafbeelding wilt weergeven op retinaschermen? Moeten we hiervoor een derde aangepast afbeeldingsformaat toevoegen? Ja, dat moet je:
add_image_size('header-retina', 2560, 1440, true);
Nu kunnen we de resolutie x-descriptors gebruiken:
<?php
$img_id = get_post_thumbnail_id();
$img_header = wp_get_attachment_image_src($img_id, 'header');
$img_header_retine = wp_get_attachment_image_src($img_id, 'header-retina');
$img_alt = get_post_meta($img_id, '_wp_attachment_image_alt', true);
?>
<img
class="my-header"
srcset="<?= $img_header[0]; ?> 1x, <?= $img_header_retina[0]; ?> 2x"
alt="<?= $img_alt; ?>"
/>
Als je de header-, header-retina- en header-mobiele formaten wilt combineren, moeten we de retina-afbeelding met dubbele breedte definiëren:
<img
class="my-header"
srcset="<?= $img_header_mobile[0]; ?> 640w, <?= $img_header[0]; ?> 1280w, <?= $img_header_retina[0]; ?> 2560w"
sizes="(max-width: 640px) 640px, 1280px"
alt="<?= $img_alt; ?>"
/>
Prestaties
Voor kleine persoonlijke websites werkt deze methode prima, maar als je meer inhoud en lay-outs voor je site gaat maken, zal je mediabibliotheek ook snel groeien.
Stel dat je afbeeldingen uploadt met een gemiddelde grootte van 2 Mb en een breedte van 3000px en je hebt 200 media-items in je bibliotheek, dan zal dat resulteren in een extra:
200 x ((640/3000) * 2) = 85,32 Mb
200 x ((1280/3000) * 2) = 170,66 Mb
200 x ((2560/3000) * 2) = 341,33 Mb
——————————————————————————————————-
597,31 Mb
Misschien heeft je website maar 4 pagina's met de sjabloon die deze afbeeldingsgrootte gebruikt. Boem! 588 afbeeldingen worden gegenereerd zonder ooit te worden gebruikt en bijna 600 Mb schijfruimte wordt in beslag genomen zonder reden. Als je een gedeelde hosting hebt met beperkte schijfruimte, kan dit een probleem worden.
Idealiter wil je alleen een (aangepast) afbeeldingsformaat genereren op de locaties in je lay-out waar dat nodig is, net zoals diensten als Cloudinary bieden.
Dit was een van de redenen waarom we besloten onze eigen tool hiervoor te schrijven: Responsive Pics en deze beschikbaar te stellen als open-source project.
Ons doel
Ons doel was om een eenvoudige syntaxis te maken waarmee iedere WordPress template auteur verschillende afbeeldingsformaten zou kunnen genereren, direct in onze templates en alleen voor de afbeeldingen die gebruikt zullen worden in die templates, zodat we responsieve markup kunnen gebruiken zoals het nieuwe <picture> element of de srcset en sizes syntaxis op <img> elementen.
Dus in plaats van te controleren welke voorgedefinieerde formaten voor je afbeelding beschikbaar zijn om te gebruiken in je sjabloon, draai je het om en geef je WordPress de taak om die afbeeldingsgrootte voor je te maken in de sjabloon zelf.
Een andere voorwaarde was dat er geen externe afhankelijkheden moesten zijn voor het maken van afbeeldingen. Hiermee voorkom je dat het te breed toegankelijk zou zijn voor elke gebruiker. Daarom waren we beperkt in het gebruik van WordPress' ingebouwde klasse WP_Image_Editor.
Na intensief testen en finetunen gedurende de afgelopen 2 jaar, hebben we precies het bovenstaande bereikt!
Dus om dat grote header-scenario opnieuw te maken met een uitsnedeverhouding van 16:9 in meerdere formaten en met retina-ondersteuning, kunnen we nu deze one-liner functie gebruiken:
<?= ResponsivePics::get_image(get_post_thumbnail_id(), 'xs-full', '0.56'); ?>
En dat zal de volgende html-opmaak voor je genereren:
<img
srcset="/app/uploads/2020/11/my-header-1400×784-center-center.jpg 1400w,
/app/uploads/2020/11/my-header-1400×784-center-center@2x.jpg 2800w,
/app/uploads/2020/11/my-header-1400×784-center-center.jpg 1400w,
/app/uploads/2020/11/my-header-1400×784-center-center@2x.jpg 2800w,
/app/uploads/2020/11/my-header-1200×672-center-center.jpg 1200w,
/app/uploads/2020/11/my-header-1200×672-center-center@2x.jpg 2400w,
/app/uploads/2020/11/my-header-992×556-center-center.jpg 992w,
/app/uploads/2020/11/my-header-992×556-center-center@2x.jpg 1984w,
/app/uploads/2020/11/my-header-768×430-center-center.jpg 768w,
/app/uploads/2020/11/my-header-768×430-center-center@2x.jpg 1536w,
/app/uploads/2020/11/my-header-576×323-center-center.jpg 576w,
/app/uploads/2020/11/my-header-576×323-center-center@2x.jpg 1152w"
sizes="(min-width: 1400px) 1400px,
(min-width: 1200px) 1400px,
(min-width: 992px) 1200px,
(min-width: 768px) 992px,
(min-width: 576px) 768px,
(min-width: 0px) 576px, 100vw"
src="/app/uploads/2020/11/my-header.jpg"
alt="Responsive header image example"
>
Dus, wat voor soort tovenarij is dit zou je kunnen denken?
Ik zal het even uitleggen;
Responsieve breekpunten
Allereerst is het je waarschijnlijk opgevallen hoeveel afbeeldingen er zijn gedefinieerd in srcset en de media queries die zijn ingesteld in sizes. Om een verscheidenheid aan afbeeldingsformaten te creëren die het beste passen op verschillende schermformaten, gebruikt Responsive Pics de volgende standaard breekpunten die deze media queries definiëren:
xs: 0
sm: 576px
md: 768px
lg: 992px
xl: 1200px
xxl: 1400px
Omdat wij als digitaal bureau en de meerderheid van de ontwikkelaars nog steeds graag CSS-frameworks gebruiken bij het ontwikkelen van frontends, hebben we onze standaardwaarden gebaseerd op de populairste: Bootstrap 4, maar je kunt ook je eigen breekpunten definiëren of toevoegen met de functie setBreakPoints:
ResponsivePics::setBreakPoints([
'xs' => 0,
'sm' => 576,
'md' => 768,
'lg' => 992,
'xl' => 1200,
'xxl' => 1400,
'xxxl' => 1600,
'xxxxl' => 1920
]);
Met deze onderbrekingspunten op zijn plaats zal onze plugin voor elk onderbrekingspunt met de opgegeven grootte proberen het formaat aan te passen en/of de afbeelding bij te snijden. Je hoeft dit formaat niet voor elk onderbrekingspunt te definiëren als het hetzelfde moet blijven. Wanneer je slechts 1 onderbrekingspunt definieert, zal Responsive Pics hetzelfde formaat gebruiken voor elk volgend onderbrekingspunt naar boven.
In ons minimale voorbeeld is dit:
<?= ResponsivePics::get_image(get_post_thumbnail_id(), 'xs-full', '0.56'); ?>
wordt eigenlijk geïnterpreteerd als:
<?= ResponsivePics::get_image(get_post_thumbnail_id(), 'xs-full, sm-full, md-full, lg-full, xl-full, xxl-full', '0.56'); ?>
Afbeeldingsgrootte
In ons voorbeeld vragen we dus eigenlijk om een 'volledig' afbeeldingsformaat voor alle onderbrekingspunten. De syntaxis 'volledig' betekent dat we de breedte van het volgende onderbrekingspunt willen gebruiken om het formaat van de afbeelding aan te passen:
0 < 576px: 576px
576 < 768px: 768px
768 < 992px: 992px
992 < 1200px: 1200px
1200 < 1400px: 1400px
≥ 1400px: 1400px
Afbeelding bijsnijden
Omdat de afbeeldingsbronnen in een responsief afbeeldingselement identiek moeten zijn, afgezien van hun grootte (dezelfde beeldverhouding, hetzelfde brandpunt), kunnen we een globale uitsnijdverhouding voor de afbeelding instellen: 0,56 met een standaard uitsnijpositie vanuit het midden.
Dit zal de hoogte van de afbeelding in elk onderbrekingspunt instellen op 56% van de breedte:
0 < 576px: 576px x 322px
576 < 768px: 768px x 430px
768 < 992px: 992px x 556px
992 < 1200px: 1200px x 672px
1200 < 1400px: 1400px x 784px
≥ 1400px: 1400px x 784px
Beelddichtheid
Voor elk gevraagd afbeeldingsformaat in het breekpunt, zal de plugin automatisch proberen het formaat te vermenigvuldigen met 2 voor retina-ondersteuning en het toevoegen aan de beschikbare afbeeldingsbronnen.
Prestaties
De uitvoer schaalt de afbeelding alleen omlaag, niet omhoog, en toont altijd de meest geschikte grootte voor het scherm. Dit verbetert direct de snelheid van je pagina's en deze keer zijn er slechts 12 afbeeldingen gegenereerd!