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 would make a basic nuxt.js score perfect on Google PageSpeed Insights (https://developers.google.com/speed/pagespeed/insights/)
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 :-)
Right, so then perhaps this should be done only for the style in <head>
?
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!
Cool, best of luck.
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
i'm looking for~
This issue looks to be related to the problem I ran into.
Not being able to load local resources in the head()
.
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>
@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:
- 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.- bundleRenderer will be able to accept a special bundle object generated from code-split multi-chunk webpack builds
- ^ the bundle can be auto-generated by using
vue-ssr-webpack-plugin
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 configureextract-text-webpack-loader
- just usevue-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 🔥
Excellent, very excited for this.
Looks like 2.2 is out! https://github.com/vuejs/vue/releases/tag/v2.2.0
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.
The 0.10 is out with CSS embedded.
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.
Most helpful comment
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!