Skip to content

Commit

Permalink
Pass more information from the link headers
Browse files Browse the repository at this point in the history
  • Loading branch information
indykoning committed Nov 5, 2024
1 parent f3fc8ce commit af2bd17
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 9 deletions.
3 changes: 2 additions & 1 deletion src/Data/LinkHeaders.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ public function makeUnique()
$handledHashes = [];

foreach ($this->getLinkProvider()->getLinks() as $link) {
$hash = md5(serialize($link));
/** @var Link $link */
$hash = md5($link->getHref(), serialize($link->getRels()));
if (! in_array($hash, $handledHashes)) {
$handledHashes[] = $hash;

Expand Down
27 changes: 19 additions & 8 deletions src/Listeners/AddFromBody.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ public function handle(GenerateEarlyHints $event)
$excludeKeywords = array_filter(config('http3earlyhints.exclude_keywords', []));
$headers = $this->fetchLinkableNodes($event->response)
->flatMap(function ($element) {
[$src, $href, $data, $rel, $type] = $element;
[$src, $href, $data, $rel, $type, $crossorigin, $as, $fetchpriority, $integrity, $referrerpolicy, $imagesizes, $imagesrcset] = $element;
$rel = $type === 'module' ? 'modulepreload' : $rel;

$attributes = array_filter(@compact('crossorigin', 'as', 'fetchpriority', 'integrity', 'referrerpolicy', 'imagesizes', 'imagesrcset'));

return [
$this->buildLinkHeader($src ?? '', $rel ?? null),
$this->buildLinkHeader($href ?? '', $rel ?? null),
$this->buildLinkHeader($data ?? '', $rel ?? null),
$this->buildLinkHeader($href ?? '', $rel ?? null, $attributes),
$this->buildLinkHeader($src ?? '', $rel ?? null, $attributes),
$this->buildLinkHeader($data ?? '', $rel ?? null, $attributes),
];
})
->filter(function (?Link $value) use ($excludeKeywords) {
Expand Down Expand Up @@ -60,13 +62,16 @@ protected function fetchLinkableNodes(Response $response): Collection
{
$crawler = $this->getCrawler($response);

return collect($crawler->filter('link:not([rel*="icon"]):not([rel="canonical"]):not([rel="manifest"]):not([rel="alternate"]), script[src]:not([defer]):not([async]), *:not(picture)>img[src]:not([loading="lazy"]), object[data]')->extract(['src', 'href', 'data', 'rel', 'type']));
return collect(
$crawler->filter('link:not([rel*="icon"]):not([rel="canonical"]):not([rel="manifest"]):not([rel="alternate"]), script[src]:not([defer]):not([async]), *:not(picture)>img[src]:not([loading="lazy"]), object[data]')
->extract(['src', 'href', 'data', 'rel', 'type', 'crossorigin', 'as', 'fetchpriority', 'integrity', 'referrerpolicy', 'imagesizes', 'imagesrcset'])
);
}

/**
* Build out header string based on asset extension.
*/
private function buildLinkHeader(string $url, ?string $rel = 'preload'): ?Link
private function buildLinkHeader(string $url, ?string $rel = 'preload', ?array $attributes = []): ?Link
{
$linkTypeMap = [
'.CSS' => 'style',
Expand Down Expand Up @@ -102,12 +107,18 @@ private function buildLinkHeader(string $url, ?string $rel = 'preload'): ?Link

$link = new Link($rel, $url);

foreach ($attributes as $key => $value) {
$link = $link->withAttribute($key, $value);
}

if ($rel === 'preconnect' && $url) {
return $link;
}

$link = $link->withAttribute('as', $type ?? 'fetch');
if ($type === 'font') {
if (empty($attributes['as'])) {
$link = $link->withAttribute('as', $type ?? 'fetch');
}
if ($type === 'font' && empty($attributes['crossorigin'])) {
$link = $link->withAttribute('crossorigin', true);
}

Expand Down

0 comments on commit af2bd17

Please sign in to comment.