Webpacker: What is the best way to preload my chunked CSS?

Created on 11 Jun 2019  路  10Comments  路  Source: rails/webpacker

I'm currently running my Rails/Vue app through Google's PageSpeed Insights and it's telling me I could shave off a reasonable amount of time (on mobile) if I preload my chunked CSS.

It says:

Consider using <link rel=preload> to prioritize fetching resources that are currently requested later in page load
URL: 鈥ss/below-fold-369ba11f.chunk.css

It seems webpack 4.6.0 adds support for preloading using a magic comment:

import(/* webpackPreload: true */ "...")

However, the latest version of webpacker uses webpack 4.33.

What is the best way to implement this using the current version of webpacker? I'd be grateful for a pointer in the right direction.

All 10 comments

However, the latest version of webpacker uses webpack 4.33.

Luckily, I think you may have just misread the version. 4.33 is 27 versions later than 4.6. Enjoy preloading, but keep in mind the specifics: https://github.com/rails/webpacker/issues/1874#issuecomment-500936752

Funny you should ask today, we are currently looking into the CSS/font/image aspect this in https://github.com/rails/webpacker/pull/2124. Hopefully, we can ship this feature for styles soon.

Lol, oops, I was reading that as 4.3.3.
Thanks for the quick response and helpful links :)

No problem, feel free to chime in on the other issue with your use-case.

Sure thing. I just need to get it working first.

I'm creating the chunk like this:

const BelowFold = () => import(
  './below-fold.vue'
  /* webpackChunkName: "below-fold" */
);

Which works as expected.

However, when I change that to:

const BelowFold = () => import(
  './below-fold.vue'
  /* webpackPreload: true */
  /* webpackChunkName: "below-fold" */
);

Google PageSpeed Insights still complains that I should preload /packs/css/below-fold-e23536a5.chunk.css.

Do have any idea where I'm going wrong?

(Sorry, I know this likely isn't a webpacker issue, so I can head off to StackOverflow if you'd rather).

I think we can use Webpacker.manifest.lookup to resolve like this:
erb <link href="<%= Webpacker.manifest.lookup('below-fold-chunk.css') %>" rel="preload" as="style">

Can you do me a favor? Could you post your generated manifest.json file? It should be somewhere in public.

Sure.

{
  "application.css": "/packs/css/application-cade8523.css",
  "application.css.map": "/packs/css/application-cade8523.css.map",
  "application.js": "/packs/js/application-807c7484ddb65da3f261.js",
  "application.js.map": "/packs/js/application-807c7484ddb65da3f261.js.map",
  "below-fold.css": "/packs/css/below-fold-a5c67fb7.chunk.css",
  "below-fold.css.map": "/packs/css/below-fold-a5c67fb7.chunk.css.map",
  "below-fold.js": "/packs/js/below-fold-bfbd2fbf1380f51ecae1.chunk.js",
  "below-fold.js.map": "/packs/js/below-fold-bfbd2fbf1380f51ecae1.chunk.js.map",
  "entrypoints": {
    "application": {
      "css": [
        "/packs/css/application-cade8523.css"
      ],
      "js": [
        "/packs/js/application-807c7484ddb65da3f261.js"
      ],
      "css.map": [
        "/packs/css/application-cade8523.css.map"
      ],
      "js.map": [
        "/packs/js/application-807c7484ddb65da3f261.js.map"
      ]
    }
  },
  "media/fonts/brand-icons.eot": "/packs/media/fonts/brand-icons-13db00b7.eot",
  "media/fonts/brand-icons.svg": "/packs/media/fonts/brand-icons-a1a749e8.svg",
  "media/fonts/brand-icons.ttf": "/packs/media/fonts/brand-icons-c5ebe0b3.ttf",
  "media/fonts/brand-icons.woff": "/packs/media/fonts/brand-icons-a046592b.woff",
  "media/fonts/brand-icons.woff2": "/packs/media/fonts/brand-icons-e8c322de.woff2",
  "media/fonts/icons.eot": "/packs/media/fonts/icons-8e3c7f55.eot",
  "media/fonts/icons.svg": "/packs/media/fonts/icons-962a1bf3.svg",
  "media/fonts/icons.ttf": "/packs/media/fonts/icons-b87b9ba5.ttf",
  "media/fonts/icons.woff": "/packs/media/fonts/icons-faff9214.woff",
  "media/fonts/icons.woff2": "/packs/media/fonts/icons-0ab54153.woff2",
  "media/fonts/outline-icons.eot": "/packs/media/fonts/outline-icons-701ae6ab.eot",
  "media/fonts/outline-icons.svg": "/packs/media/fonts/outline-icons-82f60bd0.svg",
  "media/fonts/outline-icons.ttf": "/packs/media/fonts/outline-icons-ad97afd3.ttf",
  "media/fonts/outline-icons.woff": "/packs/media/fonts/outline-icons-ef60a4f6.woff",
  "media/fonts/outline-icons.woff2": "/packs/media/fonts/outline-icons-cd6c777f.woff2",
  "media/images/flags.png": "/packs/media/images/flags-9c74e172.png"
}

Thats what I thought. (the chunk bit is from webpack) This should work:

<link href="<%= Webpacker.manifest.lookup('below-fold.css') %>" rel="preload" as="style">

becomes 馃憞

<link href="/packs/css/below-fold-a5c67fb7.chunk.css" rel="preload" as="style">

Tell me how that works. (also, test out with fonts)

Oh yeah, that completely solved the problem. Thank you very much indeed!

also, test out with fonts

The fonts are being pulled in by Semantic UI. Should I go through and add a similar line for each font?

Ok, ta. I'll look into that tomorrow.

Thanks once again for your help.

Should I go through and add a similar line for each font?

I am not too familiar with Semantic UI, but I would assume so since they are in your manifest.

Was this page helpful?
0 / 5 - 0 ratings