Image prefetching using <link> tag - html

I have seen sites using tag to load images eg;
<link href='images.jpg' rel='somthing' type='something'>
what relevance does this have while designing a website?
What aspect of website does it help optimize( i am thinking it's used for optimization. Right me if i am wrong). Can someone explain this to me?

Some people use this for image/css/page prefetching. You can read about it here.
Basically, once a page is finished loading the browser will see these link tags and if the rel attribute is "next" or "prefetch" then the browser will start downloading whatever the href attribute points to and store it in the cache so that it will load very fast if the user clicks on it.
This method can be used to prefetch anything including images, style sheets, different web pages, etc. As long as the url used in the <link> matches the url used to normally load the resource, it will load that resource from the cache.
For example, if your page had this link Page 2 and you wanted to prefetch it, you would add this to your page <link rel="next" href="page2.html">.
Finally, this method of prefetching is preferred over the javascript methods because this type of prefetching is standards compliant, is handled by the browser, and can be disabled by the user if they have metered bandwidth or other connection limitations.

While a page loads, blocking scripts can interrupt, forcing other scripts to wait. rel=preload in a link element becomes a declarative fetch primitive that initiates an early fetch and separates fetching from resource execution.
<link rel="preload" href="/style/other.css" as="style">
<link rel="preload" href="/assets/font.woff2" as="font">
<link rel="preload" href="/img/header.png" as="image">
ref. https://w3c.github.io/preload/
take note that preload is PREliminary

Related

Why do we need the "crossorigin" attribute when preloading font files?

To correctly preload font files, we're told we always need the crossorigin attribute applied to our <link rel="preload" /> tags, e.g:
<link rel="preload" href="fonts/comicsans.woff2" as="font" type="font/woff2" crossorigin>
Can anybody give me the true reason for this? All I can find are links in MDN that just dictate this requirement, without going into any detail as to why:
https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/preload#cors-enabled_fetches
When preloading resources that are fetched with CORS enabled (e.g. fetch(), XMLHttpRequest or fonts), special care needs to be taken to setting the crossorigin attribute on your element. The attribute needs to be set to match the resource's CORS and credentials mode, even when the fetch is not cross-origin.
As mentioned above, one interesting case where this applies is font files. Because of various reasons, these have to be fetched using anonymous-mode CORS (see Font fetching requirements).
It seems counterintuitive to my understanding of CORS, and why it's necessary. I'm sure there's a good reason for this, I just can't find it.
Before anybody just links to the same docs I'm talking about, see below:
https://drafts.csswg.org/css-fonts/#font-fetching-requirements
I'd really like an in depth answer from somebody who really knows why this is a requirement, and what it's purpose is, with some evidence (docs, etc) to back it up.
The HTML attribute crossorigin defines how to handle crossorigin requests. Setting the crossorigin attribute (equivalent to crossorigin="anonymous") will switch the request to a CORS request using the same-origin policy. It is required on the rel="preload" as font requests require same-origin policy.
The same-origin policy is required on almost all new resource types, such as fetch(), <script type="module"> or fonts. It doesn't apply to legacy resource types (images, scripts, css, video, audio) because of backwards-compatibility issues. <link rel="preload"> is a special case because it is a modern feature which needs to support legacy resource types, such as preloading an image.
the ideal is, from now on, you always SOR by default when you
introduce a new type of linking. It's just the right thing to do,
because it lets us avoid having to care about a whole annoying class
of security issues. Source
This requirement was then added to the W3C draft for CSS fonts.
For font loads, user agents must use the potentially CORS-enabled fetch method defined by the [FETCH] specification for URL's defined within #font-face rules. When fetching, user agents must use "Anonymous" mode, set the referrer source to the stylesheet's URL and set the origin to the URL of the containing document. Source
I have also come across repeated comments that it was requested by the font foundries to prevent font piracy, but I cannot substantiate that with evidence.
Other related links:
Discussion on Mozilla (dated 2010-10-14)
https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin
RFC6454

Preloading same resource in 2 different HTML pages

I have 2 separate HTML files, one just serving the homepage and another one serving the other routes of the application.
There is a CSS file, let's say common.css, which is needed for both the HTMLs.
If I have preloaded like,
<link rel="preload" as="style" href="/css/common.css" onload="this.rel='stylesheet'" />
In home page HTML, will it still be available in HTTP cache for my other routes navigation? Or do I have to preload common.css again in second HTML file.
I am new to using resource hints..
If preload is essential for both the renderings use preload twice. If the stylesheet is already loaded in the browsercache the browser will use it. If the stylesheet for one reason or the other is flushed it will preload it again. The most important thing is that you use the same path for both the calls.
Oh, and do not forget to tell the browser to store your sheet e.g. in apache or via the meta tag.
You could try to make a few test pages and look at the behaviour of the browser cache.

Why the requests in Chrome Debugger still queueing as the HTTP2 Protocol has been enabled?

As I have enabled the HTTP2 protocol of IIS, but the requests of the main javascript files were still queueing. According to the explanation of queueing by Chrome, I really don't know what cause this.
You can check at here: https://app.youjustgo.com/zh/
Queueing:
HTTP/2 means that more assets can be downloaded at once - not that they will be.
Browsers have various heuristics as to what to download and when.
For example, if an image is needed by a CSS file, then that image cannot be requested until the CSS file is downloaded and processed for example (ignoring preload). So in this case the CSS and the image will not download in parallel despite HTTP/2 allowing this.
Another issues is that <script> tags can change the content of the page, so unless it is explicitly marked as async (or defer) it is "render blocking". This means any JavaScript further down the page will not be run until the <script> tag is run. Now a browser could scan ahead and download the future scripts and just not run them until it needs to, if it wants, with the slight risk that it's a wasted download if the scripts subsequently are not actually needed. That's up to the browser and maybe Chrome decides it's not worth while to do this.
Looking at your specific site, your home page looks to be made up of basically only script tags. You could investigate the use of async or defer to allow more downloads to happen in parallel, but if you want the real performance improvement, you probably should go back to the basics of coding HTML, with CSS, and then enhancing it with JavaScript, rather than coding it all with JavaScript.
I'm also not sure of what the point of your preloading of your CSS is?
<link rel='preload' href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.37.0/mapbox-gl.css' as="style" onload="this.onload=null;this.rel='stylesheet'" />
<link rel='preload' href='https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-directions/v3.0.2/mapbox-gl-directions.css' as="style" onload="this.onload=null;this.rel='stylesheet'" />
<link rel="preload" href="https://npmcdn.com/angular2-toaster#2.0.0/toaster.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
<link rel="preload" href="//cdn.jsdelivr.net/jquery.slick/1.6.0/slick.css" as="style" onload="this.onload=null;this.rel='stylesheet'"/>
<link rel="preload" href="//cdn.jsdelivr.net/jquery.slick/1.6.0/slick-theme.css" as="style" onload="this.onload=null;this.rel='stylesheet'"/>
Preload is intended for assets that are not immediately apparent to the browser (like the image example above) to allow it to start downloading earlier. Here you are using it to preload CSS. The only advantage is it will not be render blocking and then you use the onload function to display it. However CSS normally is render blocking for a reason - otherwise your content looks unstyled. And because it is preloaded it's requested as high priority (which the CSS would have been requested as anyway), so not sure what advantage this is giving you to be honest. Very confused...

Why does resource prefetching not work in IE11?

Have a look at this slideshow:
http://www.jungledragon.com/all/slideshow/promoted
It loads one big image, and in the bottom there are 9 thumbnail images, which you can see when you toggle the thumbs icon button.
As a test in speeding up this slideshow, I'm including link prefetch statements for the large version of each thumb:
<link rel="prefetch" [large image url 1 here]" />
<link rel="prefetch" [large image url 2 here]" />
<link rel="prefetch" [large image url 3 here]" />
<link rel="prefetch" [large image url 4 here]" />
<link rel="prefetch" [large image url 5 here]" />
<link rel="prefetch" [large image url 6 here]" />
<link rel="prefetch" [large image url 7 here]" />
<link rel="prefetch" [large image url 8 here]" />
<link rel="prefetch" [large image url 9 here]" />
You'll find the above in the source of the page. The idea is that all large versions of the current batch (9 images) are preloaded so that when users navigate the slideshow, the large images often appear instantly.
Having implemented this, I've been testing the effects. The test instruction is simple:
Visit the slide show link
Wait for a few seconds (to allow the preloading)
Move to the next image a few times. If this works nearly instantly, prefetching was succesful. If an image load takes 2-3 seconds, it means it failed.
Alternatively, you can also open your browser's inspector window, network tab, and see both the preloading the the retrieval from cache. Note that if you do this test multiple times, you need to clear the cache each time.
Chrome results
The results in Chrome are spectacular. The prefetch hints are picked up aggressively. It's as good as it gets.
Firefox results
Firefox prefetches less aggressively and more slowly. Still, at least it does prefetch, and it works.
IE11 results
IE11 claims to support resource prefetching but it has zero effect. In Windows 8.1/IE11, none of the images are loaded instantly, it seems to prefecth nothing, also not by waiting a long time before navigating the slideshow. In IE's dev tools, I can confirm that the network tab shows no prefetch activity.
I learned later on that prefetching does not work with the dev tools open, but even when closed there is no prefetching going on, I can see that from the response times.
Any idea on why this works for Chrome and Firefox, yet not for IE11? It should be well supported but I cannot get it to work. This is a cross-domain fetch, both HTTP, not HTTPs, yet cross-domain prefetching should work according to the spec.
I have looked at the link you have provided and I believe the issue is the unusual and (probably) invalid placement of the link elements.
Microsoft state-
The link element can be used only within the head tag.
Within their MSDN documentation.
Mozilla Developer Network state-
Permitted parent elements Any element that accept metadata elements
This tallies with the official specification which further defines Metadata content-
Metadata content is content that sets up the presentation or behavior of the rest of the content, or that sets up the relationship of the document with other documents, or that conveys other "out of band" information.
base link meta noscript script style template title
The page head is able to contain metadata content whereas the body is only able to accept sectioning and flow content.
Just want to add that i just found out that prerender will not work if running your site through visual studio (using any other port than 443 or 80) with IE11/Edge. Chrome was working fine and i was trying to determine why ie/edge wasn't working. The only thing i could think of is the port. So i published to our web server and ie/edge started working. I would assume the same thing would hold true for prefetch but i haven't tried it.

How to prevent the browser from asking for the favicon?

Is there some directive I could use in my HTML to tell the browser not to ask for the favicon?
Add this line.
<link rel="icon" href="data:,">
This assigns an empty data URL to the favicon’s element which specifies the location of the external resource. This trick stops the user’s browser from sending an automatic HTTP request for the favicon.
This has some more details
No, I don't think there is. From Wikipedia:
Most web browsers do not require any HTML to retrieve a favicon that conforms to the de facto file name and type (favicon.ico) located in the web site's root. If no favicon link is detected upon HTML page load completion and no previous site visits are recorded in the browser's history, a favicon.ico is requested automatically.[8]
The only thing you could do is explicitly point the browser to a different location (that for example could return a 204 no content)
<link rel="shortcut icon" href="http://www.example.com/my_empty_resource" />
You could try pointing the <link> at a data URL. As commented below, IE will not like this, though.
Example (from 11011.net):
<link rel="icon" type="image/gif" href="data:image/gif;base64,R0lGODlhEAAQAIAAAAAAAAAAACH5BAkAAAEALAAAAAAQABAAAAIgjI+py+0PEQiT1lkNpppnz4HfdoEH2W1nCJRfBMfyfBQAOw==" />
Edited to reflect Pekka's concern regarding IE.
If you are not using HTML and its auto generated by Flask or some frameworks you can always add a dummy route in the app to just return dummy text to fix this issue.
Eg for Python Flask Application.
#app.route('/favicon.ico')
def favicon():
return 'dummy', 200