Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Eliminate external resource requests (above and below the fold) #12

Closed
jaredreich opened this issue Nov 21, 2016 · 14 comments
Closed

Eliminate external resource requests (above and below the fold) #12

jaredreich opened this issue Nov 21, 2016 · 14 comments
Assignees
Labels
Projects

Comments

@jaredreich
Copy link

jaredreich commented Nov 21, 2016

What would you think of a nuxt.js app using making no external resource requests for it's own JS and CSS files? It would all be inline injected into lib/views/app.html

Before:

<% const {
  title, htmlAttrs, bodyAttrs, link, style, script, noscript, meta
} = context.meta.inject() %><!DOCTYPE html>
<html n-head-ssr ${htmlAttrs.text()}>
  <head>
    ${meta.text()}
    ${title.text()}
    ${link.text()}
    ${style.text()}
    ${script.text()}
    ${noscript.text()}
    <base href="<%= baseUrl %>">
    <% if (!dev) { %><link rel="stylesheet" href="<%= files.css %>"><% } %>
  </head>
  <body ${bodyAttrs.text()}>
    <%= APP %>
    <script type="text/javascript" defer>window.__NUXT__=<%= serialize(context.nuxt) %></script>
    <script src="<%= files.vendor %>" defer></script>
    <script src="<%= files.app %>" defer></script>
  </body>
</html>

After:

<% const {
  title, htmlAttrs, bodyAttrs, link, style, script, noscript, meta
} = context.meta.inject() %><!DOCTYPE html>
<html n-head-ssr ${htmlAttrs.text()}>
  <head>
    ${meta.text()}
    ${title.text()}
    ${link.text()}
    ${style.text()}
    ${script.text()}
    ${noscript.text()}
    <base href="<%= baseUrl %>">
    <% if (!dev) { %><style><%= files.css.CODE %></style><% } %>
  </head>
  <body ${bodyAttrs.text()}>
    <%= APP %>
    <script type="text/javascript" defer>window.__NUXT__=<%= serialize(context.nuxt) %></script>
    <script><%= files.vendor.CODE %></script>
    <script><%= files.app.CODE %></script>
  </body>
</html>
This feature request is available on Nuxt.js community (#c9)
@jaredreich
Copy link
Author

This would make a basic nuxt.js score perfect on Google PageSpeed Insights (https://developers.google.com/speed/pagespeed/insights/)
image

@Atinux
Copy link
Member

Atinux commented Nov 21, 2016

The problem here will be that the HTML will be too heavy.

The point of the actual configuration is to display the HTML (server-rendered) so the browser can display it before loading the JavaScript and making the page reactive afterwards.

But you're right about the performances, we want Nuxt.js to generate the fastest web apps :-)

@jaredreich
Copy link
Author

Right, so then perhaps this should be done only for the style in <head>?

@Atinux
Copy link
Member

Atinux commented Nov 21, 2016

Exactly, that's actually the main issue with Nuxt.js, I will meet Evan You in December to know how I can find a way to extract the CSS of the matched components to inject the minimal CSS in the .

I'll keep you updated!

@jaredreich
Copy link
Author

Cool, best of luck.

@zspecza
Copy link

zspecza commented Nov 30, 2016

Haven't tested this (rather busy setting up my company atm) but I think this might work - although I think it may be inefficient (it might do multiple <style> tag injections) but it is a step in the right direction

https://github.com/kriasoft/isomorphic-style-loader

webpack.config

module.exports = {
  // ...
  module: {
    loaders: [
      {
        test: /\.vue$/,
        loader: 'vue'
      },
    ]
  },
  vue: {
    loaders: {
      ExtractTextPlugin.extract({
        loader: ['ismorphic-style-loader', 'css-loader'],
        fallbackLoader: 'vue-style-loader'
      })
    }
  },
  plugins: [
    new ExtractTextPlugin("style.css")
  ]
}

If my suspicion is correct that this solution creates a critical style injection more times than is appropriate, then it might be in the best interest to write a Webpack plugin that can extract the critical CSS from the ExtractTextPlugin output

FWIW I don't agree that the problem domain of this issue belongs in Nuxt, but rather in vue-loader

@ckken
Copy link

ckken commented Dec 1, 2016

i'm looking for~

@Atinux Atinux added feature and removed enhancement labels Dec 8, 2016
@lmj0011
Copy link

lmj0011 commented Jan 28, 2017

This issue looks to be related to the problem I ran into.

Not being able to load local resources in the head().

https://nuxtjs.org/faq

This doesn't work

<script>
export default {
  data ({ req }) {
    return {
      name: req ? 'server' : 'client'
    }
  },
  head () {
    return {
      title: 'Tables',
      link: [
        { rel: 'stylesheet', src: '../../assets/css/lib/datatables/css/datatables-1.10.13.min.css' }
      ],
      script: [
        {
          src: '../../assets/js/datatables/datatables-1.10.13.min.js'
        }
      ]
    }
  }
}
</script>

@Atinux
Copy link
Member

Atinux commented Jan 29, 2017

@lmj0011 please create a separate issue.

We might have a solution to have a perfect score on Google Page Speed and Lighthouse.

With the upcoming 2.2 of Vue, we will be able to insert the CSS into the page and also add a better debugging experience on SSR + code splitting on SSR as well.

Said by Evan You:

  1. vue-router (2.2 already out) now supports a router.onReady method which allows waiting until all async hooks/components are resolved before rendering/hydration. This makes async hooks and code splitting a breeze.
  2. bundleRenderer will be able to accept a special bundle object generated from code-split multi-chunk webpack builds
  3. ^ the bundle can be auto-generated by using vue-ssr-webpack-plugin
  4. vue-style-loader will be upgraded to work on both client and server. On the server it collects the CSS and generates corresponding <style> tag strings and attaches it to the SSR render context. The user simply add these style tags to the HTML output. On the client it will smartly “hydrate” the style tags (thus hot-reloading will also work!)
    ^ this basically gives us automatic critical CSS for initial server render, and with code-splitting for CSS in all async chunks
    Better yet the user no longer needs to configure extract-text-webpack-loader - just use vue-style-loader (which is the default) and it just works!

When the Vue 2.2 is out, we will try to implement it, so the 1.0 of Nuxt.js will create universal application with a perfect score 🔥

@jaredreich
Copy link
Author

Excellent, very excited for this.

@Atinux Atinux moved this from Backlog to 0.9.9 in Roadmap 1.0 Feb 3, 2017
@Atinux Atinux self-assigned this Feb 5, 2017
@Atinux Atinux added this to the 1.0 milestone Feb 5, 2017
@Atinux Atinux moved this from 0.9.9 to 1.0 in Roadmap 1.0 Feb 6, 2017
@antcook
Copy link

antcook commented Feb 26, 2017

Looks like 2.2 is out! https://github.com/vuejs/vue/releases/tag/v2.2.0

@msudgh
Copy link

msudgh commented Mar 11, 2017

How exactly scss transformation works in nuxt.js? is it based on webpack loaders?
I want to use critical CSS instead CSS file that nuxt.js made it.

@Atinux
Copy link
Member

Atinux commented Mar 24, 2017

The 0.10 is out with CSS embedded.

@Atinux Atinux closed this as completed Mar 24, 2017
@lock
Copy link

lock bot commented Nov 5, 2018

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Nov 5, 2018
@danielroe danielroe added the 2.x label Jan 18, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
No open projects
Development

No branches or pull requests

8 participants