Head Reordering

Head reordering changes the order of head element children to help the browser to optimize processing the document and start rendering earlier.

Enable in conf/config.xml:

<config>
  <acceleration>
    <head-reordering [ remove-duplicates="true" ] />
  </acceleration>
</config>

When this feature is enabled, the order of head element children in the output is as follows:

  1. the first of meta charset="..." or meta http-equiv="content-type" content="...;charset=..." elements
  2. the (first) title element
  3. the (first) base element
  4. all remaining meta elements
  5. all link rel="dns-prefetch" or link rel="preconnect" elements
  6. all link rel="preload" elements
  7. all link rel="subresource" elements
  8. all internal script elements before the first blocking external script element (i.e. without defer or async attributes)
  9. all link rel="... stylesheet ..." or style elements
  10. all script defer elements
  11. all other blocking script elements (i.e. internal scripts or scripts without defer and async attributes)
  12. all script async elements (see notes below)
  13. all other elements, except the following:
  14. all link rel="prefetch" elements
  15. all link rel="prerender" elements

Within each group of elements, the document order is not changed. E.g.
<link rel="stylesheet" href="ext1.css">
... some other elements ...
<style>
/* my internal style */
</style>
... some other elements ...
<link rel="stylesheet" href="ext2.css">

results in

<link rel="stylesheet" href="ext1.css">
<style>
/* my internal style */
</style>
<link rel="stylesheet" href="ext2.css">
... some other elements ...
... some other elements ...

Removing Duplicates

If the option remove-duplicates is set to true, all scripts with the same src value or links with rel="stylesheet" and the same href are considered duplicates and will be removed.

Scripts

Only the first occurence will be kept, but it will obtain the most blocking loading directive of these particular duplicates. If any of them was blocking, the remaining script will be blocking. For non-blocking scripts, the defer attribute will get precedence over async. The first encountered id and any found ai-load="true" attributes will be preserved as well.

This behaviour can be prevented by adding a ai-keep-duplicate attribute to the desired script elements.

With remove-duplicates enabled, this head
    <script src="js/ext_1.js"></script>
    <script src="js/ext_1.js" ai-keep-duplicate></script>
    <script src="js/ext_1.js"></script>
    <script src="js/ext_2.js"></script>
    <script src="js/ext_2.js" id="first"></script>
    <script src="js/ext_2.js" id="second" ai-load="true"></script>

results in

    <script src="js/ext_1.js"></script>
    <script src="js/ext_1.js" ai-keep-duplicate></script>
    <script src="js/ext_2.js" id="first" ai-load="true"></script>

Note:

If the client does not support async scripts, these async scripts are moved to the end of the body.

Multiple media attributes for link elements with the same href will be combined and the last link element will be kept. In case of more than one link element with the same href having an id attribute, the last ocurring id attribute of respective elements will be kept. If one or more of these elements also has an ai-load attribute, the last respective id will be preferred over those from elements without ai-load attribute.

This behaviour can be prevented by adding a ai-keep-duplicate attribute to the desired link elements.

With remove-duplicates enabled, this head
    <link rel="stylesheet" href="assets/default.css">
    <link rel="stylesheet" href="assets/duplicate.css">
    <style id="style1"></style>
    <link rel="stylesheet" href="assets/duplicate.css">
    <link rel="stylesheet" href="assets/duplicate-media.css" media="printer">
    <link rel="stylesheet" href="assets/duplicate-media.css" media="screen" id="printOrScreen">
    <link rel="stylesheet" href="assets/duplicate-aiload-id.css" ai-load="true" id="ai-load">
    <link rel="stylesheet" href="assets/duplicate-aiload-id-media.css" ai-load="true" id="ai-load-media" media="printer">
    <link rel="stylesheet" href="assets/duplicate-aiload-id.css" id="asset">
    <link rel="stylesheet" href="assets/duplicate-aiload-id-media.css" media="screen">
    <link rel="stylesheet" href="assets/keep-duplicate.css">
    <link rel="alternate stylesheet" href="assets/alternate.css" title="alternate">
    <link rel="stylesheet" href="assets/keep-duplicate.css" ai-keep-duplicate>

results in

    <link rel="stylesheet" href="assets/default.css">
    <style id="style1"></style>
    <link rel="stylesheet" href="assets/duplicate.css">
    <link rel="stylesheet" href="assets/duplicate-media.css" media="screen, printer" id="printOrScreen">
    <link rel="stylesheet" href="assets/duplicate-aiload-id.css" id="ai-load">
    <link rel="stylesheet" href="assets/duplicate-aiload-id-media.css" media="screen, printer" id="ai-load-media">
    <link rel="stylesheet" href="assets/keep-duplicate.css">
    <link rel="alternate stylesheet" href="assets/alternate.css" title="alternate">
    <link rel="stylesheet" href="assets/keep-duplicate.css">

Conditional Comments

All conditional comments are converted to normal content before the reordering takes place. That way the document order for elements contained in conditional comments is retained.

Note:

Head reordering will be disabled if any errors are encountered within the content of a conditional comment.