W tym artykule wyjaśnię, jak zintegrować responsywne obrazy i progresywne ładowanie obrazów w aplikacji laravel. Zapewni to Twojej aplikacji duży wzrost wydajności. Po pierwsze. W tym samouczku będę używał dwóch niesamowitych pakietów: obrazu interwencyjnego do manipulacji obrazem i leniwych rozmiarów do progresywnego ładowania obrazu. Możesz postępować zgodnie z instrukcjami instalacji na odpowiednich stronach. Aby uzyskać szybki podgląd reakcji aplikacji po tym samouczku, zapoznaj się z tematem Codefield.To get a quick preview how your app will react after this tutorial, check out Codefield. Przeszedłem przez ten proces, aby go tam wdrożyć. Pamiętaj, aby zainstalować te dwa pakiety przed rozpoczęciem procesu. Więc zacznijmy.
Formularz
<form method="POST" action="{{ url('addPhotos') }}" enctype="multipart/form-data">
{{ csrf_field() }}
<input type="file" name="photo[]"
value="{{ old('photo') }}" multiple="multiple">
<button type="submit">
Add photo(s)
</button>
</form>
this is just a basic form with a post
method and action="{{ url('addPhotos') }}"
meaning that when the form is submitted it will point to the addPhotos
route on your web.php
file.
photo
is the name of the column on your database where the image path will be saved. the []
stands for multiple if you want to upload multiple photos at once.
przesyłania obrazu Trasa
W pliku web.php
dodaj tę trasę
Route::post('addPhotos', 'PhotosController@store');
this will set the route for addPhotos
and point to the store
method in PhotosController.php
or whatever controller you have the method in.
Tworzenie folderów
W folderze przechowywania w aplikacji utwórz folder o nazwie public
. W tym folderze dodaj następujące foldery: medium_photos
mobile_photos
original_photos
large_photos
oraz .tiny_photos
Następnie na konsoli uruchom poleceniephp artisan storage:link
, aby utworzyć publiczne łącze między folderem magazynu a folderem publicznym. Zasadniczo, aby upublicznić te zdjęcia.
Proces
przesyłania Teraz wszystko się dzieje. Będę miał tutaj pełną metodę, a następnie wyhamuję ją dla ciebie.
public function store(Request $request)
{
$this->validate(request(), [
'photo' => 'required'
]); $original_photo_storage = public_path('storage/original_photos/');
$large_photos_storage = public_path('storage/large_photos/');
$medium_photos_storage = public_path('storage/medium_photos/');
$mobile_photos_storage = public_path('storage/mobile_photos/');
$tiny_photos_storage = public_path('storage/tiny_photos/');$files = request()-> file('photo');foreach ($files as $file) { $photo = new Photo; //or whatever your model is called
$photo -> user_id = auth()->id();
$photo -> unique_id = uniqid();
$photo -> photo = $file->hashName(); $image = Image::make($file->getRealPath());
$image->save($original_photo_storage.$file->hashName(),100)->resize(860, null, function ($constraint) {
$constraint->aspectRatio();
})->save($large_photos_storage.$file->hashName(),85)->resize(640, null, function ($constraint) {
$constraint->aspectRatio();
})->save($medium_photos_storage.$file->hashName(),85)->resize(420, null, function ($constraint) {
$constraint->aspectRatio();
})->save($mobile_photos_storage.$file->hashName(),85)->resize(10, null, function ($constraint) {
$constraint->aspectRatio();
})->blur(1)->save($tiny_photos_storage.$file->hashName(),85);
$photo->save();
}
return back();
so let’s brake this down
$this->validate(request(), [
'photo' => 'required'
]);
this is just a validation telling laravel that a photo is required in order to submit the form. You don’t have to add this if you don’t want to.
$original_photo_storage = public_path('storage/original_photos/');
$large_photos_storage = public_path('storage/large_photos/');
$medium_photos_storage = public_path('storage/medium_photos/');
$mobile_photos_storage = public_path('storage/mobile_photos/');
$tiny_photos_storage = public_path('storage/tiny_photos/');
these are the paths to the folders on your public folder.That’s where the images are going to be saved. Now just by the name i guess you know where everything goes.The last folder tiny_photos
will be for the tiny images that will be used for progressive image loading.
$files = request()-> file('photo');
this will request the file from the form.
$photo = new Photo; //or whatever your model is called
$photo -> user_id = auth()->id();//create a user id for the photo. //This will be the id of the authenticated user.
$photo -> unique_id = uniqid();//give photo a unique id so you can //reference it when you want to see the photo on your app
$photo -> photo = $file->hashName();//give the uploaded photo a hash //name
$image = Image::make($file->getRealPath());//create a new image //resource from file.This is done by the Intervention Image package
next we save the image
$image->save($original_photo_storage.$file->hashName(),100)//save //the image on the original_photos folder with 100% quality
then we resize the images
->resize(860, null, function ($constraint) {
$constraint->aspectRatio();
})->save($large_photos_storage.$file->hashName(),85)
//we resize the image to 860px, save it to the large_photos folder
//with a quality of 85%.Keep the resized images under 85% to pass //the google lighthouse efficiently compress images requirement.
//there will be no changes in image quality->resize(640, null, function ($constraint) {
$constraint->aspectRatio();
})->save($medium_photos_storage.$file->hashName(),85)
//we resize the image to 640px, save it to the medium_photos folder
//with a quality of 85%.Keep the resized images under 85% to pass //the google lighthouse efficiently compress images requirement.
//there will be no changes in image quality->resize(420, null, function ($constraint) {
$constraint->aspectRatio();
})->save($mobile_photos_storage.$file->hashName(),85)
//we resize the image to 420px, save it to the mobile_photos folder
//with a quality of 85%.Keep the resized images under 85% to pass //the google lighthouse efficiently compress images requirement.
//there will be no changes in image quality->resize(10, null, function ($constraint) {
$constraint->aspectRatio();
})->blur(1)->save($tiny_photos_storage.$file->hashName(),85);
//we resize the image to 10px, save it to the tiny_photos folder
//with a quality of 85%.Keep the resized images under 85% to pass //the google lighthouse efficiently compress images requirement.
//there will be no changes in image quality
//we add the blur(1) method to blur the tiny image for progressive //image loading
then we save everything
$photo->save();
and return back to the form
eturn back();
With this we have uploaded 5 different versions of the image with different sizes that we can use for responsive images.Now we have to call these images based on the screen size.This is one way to go about it.
Z srcset
, jeśli wyświetlasz wiele obrazów, musisz zrobić pętlęforeach
.
Na przykład
@foreach ($photo as $img)
<img src="{{asset('storage/medium_photos/'.$img->photos)}}"
srcset="{{asset('storage/medium_photos/'.$img->photos.' 860w')}},{{asset('storage/medium_photos/'.$img->photos.' 640w')}},{{asset('storage/mobile_photos/'.$img->photos.' 420w')}}">
@endforeach
or if you are displaying only one image then no need for foreach
loop
<img src="{{asset('storage/medium_photos/'.$photo->photos)}}"
srcset="{{asset('storage/medium_photos/'.$photo->photos.' 860w')}},{{asset('storage/medium_photos/'.$photo->photos.' 640w')}},{{asset('storage/mobile_photos/'.$photo->photos.' 420w')}}">
the src
element works as a fallback just in case the srcset
fails.The srcset
element will read the screen size and for any screen that matches the given screen width e.g 860w
will load the respective image, in this case will load the large image. and so on for the 640w
will load the medium image and for the 420w
will load the mobile image.This way you ensure you are not loading a 4k image on a mobile device.That’s just pointless
element obrazu Innym sposobem na zrobienie tego jest element
<picture>
<source
media = "(min-width:860px)"
srcset="{{asset('storage/large_photos/'.$photo->photo.' 860w')}}">
<source
media = "(min-width:640px)"
srcset = "{{asset('storage/medium_photos/'.$photo->photo.' 640w')}}" >
<source
media = "(max-width:420px)"
srcset = "{{asset('storage/mobile_photos/'.$photo->photo.' 420w')}}" >
<img src="{{asset('storage/medium_photos/'.$photo->photo)}}" >
</picture>
again in this example the src
element will work as a fallback in case srcset
fails.I’d say this method is arguably more readable for the browser.We use the <picture>
element.Within that we add a <source>
element.Within the <source>
element we add media
where we can compare current screen size against the size defined on the media
element and for each screen size, we give the image defined in the srcset
element. Taking the example above for all screens larger than 860px
we will display the large images, and so it goes on for the rest of the screen sizes. Now, we have yet to implement progressive image loading. Let’s to that now.
obrazu Progresywne ładowanie
obrazu Po całej pracy, którą wykonaliśmy, wdrożenie progresywnego ładowania obrazu jest łatwe. Zasadniczo całe ciężkie podnoszenie odbywa się za pomocą pakietu lazysizes. Dodawanie progresywnego ładowania obrazu jest bardzo podobne do metody wyświetlania responsywnych obrazów. Jedyna różnica polega na tym, że zamiast używać będziemy używać i zamiast będziemy srcset
używać src
data-src
data-srcset
. Dokumentacja Lasysizes wyjaśnia to szczegółowo. Jedną z metod do tego byłoby :
obrazu Progresywne ładowanie with srcset
<img class="lazyload blur-up"
src="{{asset('storage/tiny_photos/'.$photo->photos)}}"
data-sizes="auto"
data-src="{{asset('storage/medium_photos/'.$photo->photos)}}"
data-srcset="{{asset('storage/medium_photos/'.$photo->photos.' 860w')}},{{asset('storage/medium_photos/'.$photo->photos.' 640w')}},{{asset('storage/mobile_photos/'.$photo->photos.' 420w')}}"
in this case src
element will we only used to load the blurred tiny image and the second the larger image is loaded, the tiny image will disappear and the larger image will take place.
Zauważ, że użyliśmy class="lazyload blur-up"
. W tym przypadku lazyload
klasa jest używana do realizacji techniki ładowania progresywnego. Opcjonalnie można użyć blur-up
technik lub ratio-box fade-box
odpowiednio dla rozmycia i zanikania. Aby skorzystać z tych klas, musisz dodać trochę dodatkowego css do swojego projektu, w ten sposób:
<style>
.blur-up {
-webkit-filter: blur(5px);
filter: blur(5px);
transition: filter 400ms, -webkit-filter 400ms;
} .blur-up.lazyloaded {
-webkit-filter: blur(0);
filter: blur(0);
}
</style><img src="lqip-src.jpg" data-src="image.jpg" class="lazyload blur-up" /><!-- ... --><style>
.fade-box .lazyload,
.fade-box .lazyloading {
opacity: 0;
transition: opacity 400ms;
} .fade-box img.lazyloaded {
opacity: 1;
}
</style><div class="ratio-box fade-box">
<img src="lqip-src.jpg" />
<img data-src="image.jpg" class="lazyload" />
</div>
but this is very well explained in the documentation.
obrazu Progresywne ładowanie with the picture element
<picture>
<source media = "(min-width:860px)"
data-srcset="{{asset('storage/large_photos/'.$photo->photo.' 860w')}}">
<source media = "(min-width:420px)"
data-srcset = "{{asset('storage/medium_photos/'.$photo->photo.' 640w')}}" >
<source media = "(max-width:420px)"
data-srcset = "{{asset('storage/mobile_photos/'.$photo->photo.' 420w')}}" >
<img class="lazyload blur-up"
src="{{asset('storage/tiny_photos/'.$photo->photo)}}"
data-src="{{asset('storage/medium_photos/'.$photo->photo)}}" >
</picture>
Same as before src
element will we only used to load the blurred tiny image and the second the larger image is loaded it the tiny image will disappear and the larger image will take place. And instead of using src
we will use data-src
and instead of srcset
we will use data-srcset
.
picture.. I to wszystko. Teraz masz progresywne ładowanie obrazów w połączeniu z responsywnymi obrazami w aplikacji laravel, co zapewnia duży wzrost wydajności. Połącz to z dodaniem progresywnych funkcji aplikacji internetowych do swojej aplikacji, a otrzymasz bardzo szybki produkt. Mam nadzieję, że podobał Ci się ten samouczek. Zapytaj mnie, jeśli masz jakieś pytania lub nie masz jasności co do czegoś.