Support prefetch/preload/dns-prefetch in the libraries API

Created on 13 June 2023, over 1 year ago

Problem/Motivation

Olivero ships a preload template with the following:

<link rel="preload" href="{{ olivero_path }}/fonts/metropolis/Metropolis-Regular.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="{{ olivero_path }}/fonts/metropolis/Metropolis-SemiBold.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="{{ olivero_path }}/fonts/metropolis/Metropolis-Bold.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="{{ olivero_path }}/fonts/lora/lora-v14-latin-regular.woff2" as="font" type="font/woff2" crossorigin>

This is to support fonts.css which is loaded as part of the global-styling library.

I think we should look at generic support for adding link tags as part of library definitions at the same level as CSS and JS. This can then be added to the HTML head via the same mechanism as #attached['html_head']. Via that, we'd then be able to support prefetch, preload, and dns-prefetch and possibly other things.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Feature request
Status

Active

Version

11.0 🔥

Component
Asset library 

Last updated about 14 hours ago

No maintainer
Created by

🇬🇧United Kingdom catch

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @catch
  • 🇬🇧United Kingdom catch
  • 🇫🇷France vbouchet

    I understand that for now, given the example, it is to add the possibility to specify additional "things" with the library that would generate the link tags. What about the existing external / js that are added in a library?
    Should we do something like:

    my_library:
      js:
       https://cdn.example.com/js/file.js: { type: external, preconnect: true, dns-prefech: true }
    

    or

    my_library:
      js:
       https://cdn.example.com/js/file.js: { type: external }
      links:
        -
          rel: preconnect
          href: //cdn.example.com
        -
          rel: dsn-prefetch
          href: //cdn.example.com
          
    

    The second option allows a lot of flexibility (and cover the example of fonts) but is much more verbose.
    Third option is a mix, allowing for shorter version for elements of the library (like example 1) and verbose version for other elements.

    I am curious of a direction as we are for now implementing custom on a project but would be keen to write a patch for this to land in core the proper way.

  • 🇬🇧United Kingdom catch

    I kind of like the more verbose option even for the same file, because you could have two files from the same CDN and then defining prefetch inline for one file (or both) doesn't seem ideal. We could always add a shorthand in a follow-up.

  • 🇦🇺Australia rikki_iki Melbourne

    @catch thanks for the redirect to this issue. As I posted on the other issue, in my mind I think a definition like this would be nice;

    font:
      css:
        base:
          https://fonts.example.com/font.css: { type: external }
      preconnect:
        https://fonts.example.com: {}
      preload:
        https://fonts.example.com/font-regular.woff2: { as: font, attributes: { type: font/woff2} }
        https://fonts.example.com/font-bold.woff2: { as: font, attributes: { type: font/woff2 } }
    

    dns-prefetch would also have it's own entry. I think having separate entries instead of one generic 'links' entry reduces the risk of user error (and general misuse - eg putting css and js into the links entry). It's also clearer to read.

  • 🇬🇧United Kingdom catch

    That looks pretty nice to me as an API. We'd have to handle any additions/removals manually but maybe that is fine.

  • 🇫🇷France MacSim

    Ahem, since the other issue was opened in 2022 and this one in 2023, the duplicate is this one, not the former...
    We should have close that issue and improve the original.

  • 🇦🇺Australia rikki_iki Melbourne

    The other issue has been postponed for a year, and no one seemed to care... I don't mind which issue so long as it stays active.

    DNS prefetch is more widely supported and recommended as a fallback for Preconnect, so maybe we can build that in? Or instead of two separate entries it's something like;

    font:
      prefetch:
        https://fonts.example.com: { preconnect: true }
        https://other.example.com: { }
      preload:
         etc..
    

    To optionally add a preconnect hint for certain dns-prefetch items, since preconnect usage should be limited to only critical assets;

    <link rel="preconnect" href="http://fonts.example.com">
    <link rel="dns-prefetch" href="http://fonts.example.com">
    <link rel="dns-prefetch" href="http://other.example.com">
    

    Regarding preload, there's also modulepreload to consider. I don't know if we want to have yet another entry just for this separate rel value or if we could so something like;

    main:
      js:
        js/main.module.js: { type: module }
        js/main.js: { }
      preload:
        js/main.module.js: { as: script, attributes: { type: module } }
        js/main.js: { as: script }
    

    And if the preload has type:module we can swap the rel value over?

    <link rel="preload" href="main.js" as="script" />
    <link rel="modulepreload" href="main.module.js" as="script" />
    

    And then how should we handle the crossorigin attribute? Currently it can be added via attributes which I guess is fine.

  • 🇫🇷France MacSim

    I don't really mind as well it's just about people who spent hours thinking about the problem / trying to fix it / reviewing code / rerolling it and who will never get credit for that.

    As long as the subject moves forward it's good, so now that it's been done, let's continue here.

  • 🇬🇧United Kingdom catch

    @macsim we can transfer issue credits over, but I'm not sure which issue you're talking about to be honest, there are at least three somewhat related to this one with different approaches. If you link it, I'll look at transferring relevant credits over.

Production build 0.71.5 2024