Asset Prefetching Strategies with Vite in Laravel 11.21
Last updated on by Paul Redmond
The Laravel team released v11.21 this week, which includes asset prefetching strategies for Vite, a convenience method to force-destroy models with soft deletes, testing helper updates, and more.
Eager Asset Prefetching Strategies for Vite
Tim MacDonald contributed the ability to prefetch assets generated by Vite eagerly:
This PR adds the ability for applications to eagerly prefetch JavaScript and CSS chunks generated by Vite. The goal is to reduce the network delay / costs when navigating throughout a SPA front-end.
Applications built with Vite will often use "code splitting". This technique splits the JavaScript (and CSS) into smaller "chunks". When you load any given page, only the chunks required to render that page are loaded which leads to faster load times for applications. For example, when you land on the homepage you do not pay the cost of also downloading and parsing the admin dashboard JavaScript.
To configure prefetching, you could add one of the following methods to the boot()
method of a service provider:
// In a service provider `boot()` method: Vite::useWaterfallPrefetching(concurrency: 10);Vite::useAggressivePrefetching();Vite::usePrefetchStrategy('waterfall', ['concurrency' => 1]);
See Pull Request #52462 for usage details, including videos of assets based on the types of prefetching strategies.
expectsChoice()
Assertion More Intuitive with Associative Arrays
Make Jess Archer made updates to the expectsChoice()
assertion method when passing an associative array:
$this->choice('Choose an option', [ 'one' => 'One', 'two' => 'Two', 'three' => 'Three',]);
When using expectsChoice()
, you would need to write the expectation as follows:
// Before$this->expectsChoice('Choose an option', 'one', [ 'one', 'two', 'three', 'One', 'Two', 'Three',]);
After updating to Laravel 11.21, you can now do the following instead:
// After$this->expectsChoice('Choose an option', 'one', [ 'one' => 'One', 'two' => 'Two', 'three' => 'Three',]);
See Pull Request #52408 for more details.
Force Destroying a Soft-deleted Model
Jason McCreary contributed a forceDestroy()
convenience method to remove a record while using the SoftDeletes
trait:
// Before$comment = Comment::find(1);$comment->forceDelete(); // AfterComment::forceDestroy(1); // Destroy multiple records// Also, `forceDestroy()` returns an int count of destroyed records:$count = Comment::forceDestroy([1, 2]);
countBetween()
to AssertableJson
Add Borys Żmuda contributed a between()
method to the AssertableJson
class, which asserts that items are either greater than or equal to the minimum, or less than or equal to the maximum value:
$response->assertJson(fn (AssertableJson $json) => $json ->countBetween(10, 30) ->etc(),);
Get the Stream Response from Laravel’s HTTP Client
Einar Hansen contributed a resource()
method for the HTTP client’s Response
class, which allows you to directly obtain a PHP stream resource from the response body:
// Beforeuse GuzzleHttp\Psr7\StreamWrapper; $response = Http::get($imageUrl);Storage::disk('s3')->writeStream( 'thumbnail.png', StreamWrapper::getResource($response->toPsrResponse()->getBody()),); // After$response = Http::get($imageUrl);Storage::disk('s3')->writeStream('thumbnail.png', $response->resource());
See Pull Request #52412 for more examples and implementation details.
withoutHeaders()
Test Helper
Add Milwad Khosravi contributed a withoutHeaders()
method to skip headers during a test request. It was already possible to remove headers individually, and this update allows removing an array of headers in one call:
// Before:$this ->withoutHeader('name') ->withoutHeader('foo') ->from('previous/url'); // After:$this ->withoutHeaders(['name', 'foo']) ->from('previous/url');
Release notes
You can see the complete list of new features and updates below and the diff between 11.20.0 and 11.21.0 on GitHub. The following release notes are directly from the changelog:
v11.21.0
- [11.x] Test Improvements by @crynobone in https://github.com/laravel/framework/pull/52402
- [11.x] Fix docblock for the event dispatcher by @seriquynh in https://github.com/laravel/framework/pull/52411
- [11.x] fix: Update text email template by @tranvanhieu01012002 in https://github.com/laravel/framework/pull/52417
- [11.x] Make
expectsChoice
assertion more intuitive with associative arrays. by @jessarcher in https://github.com/laravel/framework/pull/52408 - [11.x] Add
resource()
method to Illuminate\Http\Client\Response by @einar-hansen in https://github.com/laravel/framework/pull/52412 - [10.x] fix: prevent casting empty string to array from triggering json error by @calebdw in https://github.com/laravel/framework/pull/52415
- [11.x] Add ResponseInterface mixin to
Illuminate\Http\Client\Response
by @einar-hansen in https://github.com/laravel/framework/pull/52410 - [11.x] Don't touch BelongsTo relationship when it doesn't exist by @patrickomeara in https://github.com/laravel/framework/pull/52407
- [11.x] Fix
Factory::afterCreating
callable argument type by @villfa in https://github.com/laravel/framework/pull/52424 - [11.x] Auto-secure cookies by @fabricecw in https://github.com/laravel/framework/pull/52422
- fix: add missing phpdoc types for Model::$table and Model::$dateFormat by @taka-oyama in https://github.com/laravel/framework/pull/52425
- [11.x] Add
withoutHeaders
method by @milwad-dev in https://github.com/laravel/framework/pull/52435 - Checking availability before calling Log::flushSharedContext() method by @ajaxray in https://github.com/laravel/framework/pull/52470
- [11.x] MessageBag errors out when custom rules are created and the class is left out of the message array by @DanteB918 in https://github.com/laravel/framework/pull/52451
- Create Notification make command markdown name placeholder from Notif… by @hosseinakbari-liefermia in https://github.com/laravel/framework/pull/52465
- [11.x] Add
forceDestroy
toSoftDeletes
by @jasonmccreary in https://github.com/laravel/framework/pull/52432 - Make SQLiteProcessor cope with '/' in column names by @vroomfondle in https://github.com/laravel/framework/pull/52490
- [11.x] Improve Cookie Testing Coverage by @saMahmoudzadeh in https://github.com/laravel/framework/pull/52472
- [11.x] Fix for #52436 artisan schema:dump infinite recursion by @rust17 in https://github.com/laravel/framework/pull/52492
- Run prepareNestedBatches on append/prependToChain & chain by @SabatinoMasala in https://github.com/laravel/framework/pull/52486
- [11.x] Enhance DB inspection commands by @hafezdivandari in https://github.com/laravel/framework/pull/52501
- [11.x] Constrain key when asserting database has a model by @patrickomeara in https://github.com/laravel/framework/pull/52464
- Add
between
toAssertableJson
by @rudashi in https://github.com/laravel/framework/pull/52479 - [11.x] Eager asset prefetching strategies for Vite by @timacdonald in https://github.com/laravel/framework/pull/52462
- [11.x] Support attributes in
app()->call()
by @innocenzi in https://github.com/laravel/framework/pull/52428 - [11.x] Applying
value
Function into the$default
value oftransform
helper by @devajmeireles in https://github.com/laravel/framework/pull/52510 - [11.x] Enhanced typing for
HigherOrderCollectionProxy
by @Voltra in https://github.com/laravel/framework/pull/52484 - [11.x] Add
expectsSearch()
assertion for testing prompts that usesearch()
andmultisearch()
functions by @JayBizzle in https://github.com/laravel/framework/pull/51669 - [11.x] revert #52510 which added a unneeded function call by @rodrigopedra in https://github.com/laravel/framework/pull/52526