Hello,
I have some nuxt.configuration.js optimization issues. My pagespeed is to low on mobile (28) against desktop (75). For the record the mobile scrore was at 0 at the beginning
I try all the recommendation by
Nothing in the end can some one help me by taking a look on my file ?
`const pkg = require("./package")
import webpack from 'webpack'
import { version } from './package.json'
import shrinkRay from 'shrink-ray-current'
const HtmlWebpackPlugin = require('html-webpack-plugin')
const HtmlWebpackPreconnectPlugin = require('html-webpack-preconnect-plugin')
const InlineSourcePlugin = require('html-webpack-inline-source-plugin')
const {GenerateSW} = require('workbox-webpack-plugin')
const ClosurePlugin = require('closure-webpack-plugin')
const ManifestPlugin = require('webpack-manifest-plugin')
const isDev = (process.env.NODE_ENV !== 'production')
require('dotenv').config()
module.exports = {
mode: 'spa',
dev: isDev,
entry: {
home: './src/Home/index.js'
},
loading: '~/components/loading.vue',
head: {
title: 'Estimation de votre véhicule avec Renault – Vente de voiture – Côte & Inspection gratuite',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: pkg.description }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.png' },
{ rel: 'preconnect', href: '//www.googletagmanager.com', crossorigin: 'crossorigin' },
{ rel: 'preconnect', href: '//bat.bing.com', crossorigin: 'crossorigin' },
{ rel: 'preconnect', href: '//8sdeuiavcr-1.algolianet.com', crossorigin: 'crossorigin' },
{ rel: 'preconnect', href: '//renault-sellyourcar-536324.c.cdn77.org', crossorigin: 'crossorigin' }
]
},
render: {
compressor: shrinkRay()
},
modules: [
[
"nuxt-compress",
{
gzip: {
cache: true
},
brotli: {
threshold: 10240
}
}
],
'@nuxtjs/axios',
[
'nuxt-vuex-localstorage',
{
sessionStorage: ['customer', 'vehicle', 'inspector', 'quotation', 'deliveries', 'warranties', 'transactionBuyer', 'credit']
}
],
[
'@nuxtjs/moment',
{
locales: ['fr'],
defaultLocale: 'fr'
}
],
[
'@nuxtjs/dotenv',
{
filename: '.env'
}
],
['@nuxtjs/component-cache', {
max: 10000,
maxAge: 1000 * 60 * 60
}],
'bootstrap-vue/nuxt',
'vue-scrollto/nuxt'
],
optimization: {
nodeEnv: 'production',
minimize: true,
minimizer: [
new ClosurePlugin({mode: 'STANDARD'}, {
debug: isDev,
// compiler flags here
//
// for debuging help, try these:
//
// formatting: 'PRETTY_PRINT'
// renaming: false
})
],
runtimeChunk: true,
concatenateModules: !isDev,
splitChunks: {
chunks: 'all'
}
},
plugins: [
'~plugins/vue-instantsearch',
'~/plugins/google-maps',
'~/plugins/google-tag-manager',
'~plugins/autocomplete',
'~plugins/dataLayer',
{
src: '~plugins/vee-validate.js',
ssr: false
},
{
src: '~plugins/vue-lazyload.js',
ssr: false
},
{
src: '~plugins/vue-lazyload-video.js',
ssr: false
}
],
router: {
middleware: 'redirect'
},
build: {
cache: !isDev,
devtools: isDev,
hardSource: !isDev,
parallel: true,
terser: true,
filenames: {
index: ({ isDev }) => isDev ? '[name].js' : 'index/[chunkhash].js',
appraisal: ({ isDev }) => isDev ? '[name].js' : 'appraisal/[chunkhash].js',
cancel: ({ isDev }) => isDev ? '[name].js' : 'cancel/[chunkhash].js',
error: ({ isDev }) => isDev ? '[name].js' : 'error/[chunkhash].js',
informations: ({ isDev }) => isDev ? '[name].js' : 'informations/[chunkhash].js',
reservation: ({ isDev }) => isDev ? '[name].js' : 'resume/[chunkhash].js',
resume: ({ isDev }) => isDev ? '[name].js' : 'valuation/[chunkhash].js',
valuation: ({ isDev }) => isDev ? '[name].js' : '[chunkhash].js',
css: ({ isDev }) => isDev ? '[name].css' : '[contenthash].css',
img: ({ isDev }) => isDev ? '[path][name].[ext]' : 'img/[hash:7].[ext]',
font: ({ isDev }) => isDev ? '[path][name].[ext]' : 'fonts/[hash:7].[ext]',
video: ({ isDev }) => isDev ? '[path][name].[ext]' : 'videos/[hash:7].[ext]',
chunk: ({ isDev }) => isDev ? '[name].js' : '[id].[chunkhash].js'
},
html: {
minify: {
collapseBooleanAttributes: true,
decodeEntities: true,
minifyCSS: true,
minifyJS: true,
processConditionalComments: true,
removeEmptyAttributes: true,
removeRedundantAttributes: true,
trimCustomFragments: true,
useShortDoctype: true
}
},
//publicPath: process.env.CDN_PATH,
splitChunks: {
layouts: false,
pages: true,
commons: true
},
transpile: [/^vue2-google-maps($|\/)/, 'nuxt-vuex-localstorage'],
plugins: [
new webpack.DefinePlugin({
'process.VERSION': version
}),
new webpack.ProvidePlugin({
'$': 'jquery',
'jQuery': 'jquery',
}),
new HtmlWebpackPlugin({
// Inline all files which names start with “runtime~” and end with “.js”.
// That’s the default naming of runtime chunks
inlineSource: 'runtime~.+\\.js',
}),
// This plugin enables the “inlineSource” option
new InlineSourcePlugin(),
new HtmlWebpackPreconnectPlugin(),
new GenerateSW(),
new ManifestPlugin()
],
extend(config, { isDev, isClient }) {
if (isDev) {
config.devtool = '#source-map';
}
if (isDev && isClient) {
config.module.rules.push({
enforce: 'pre',
test: /\.(js|vue)$/,
loader: 'eslint-loader',
exclude: /(node_modules)/,
});
}
if (config.optimization.splitChunks && typeof config.optimization.splitChunks === 'object') {
config.optimization.splitChunks.maxSize = 200000;
}
const vueLoader = config.module.rules.find(rule => rule.loader === 'vue-loader')
vueLoader.options.transformAssetUrls = {
video: ['src', 'poster'],
source: 'src',
img: 'src',
image: 'xlink:href',
link: 'href',
use: ['xlink:href', 'href'],
'v-lazy-image': ['src', 'srcset'],
'LazyVideo': ['src', 'poster']
}
config.module.rules.forEach(rule => {
if (String(rule.test) === String(/\.(png|jpe?g|gif|svg|webp)$/)) {
// add a second loader when loading images
rule.use.push({
loader: 'image-webpack-loader',
// This will apply the loader before the other ones
enforce: 'pre'
})
}
if (String(rule.test) === String(/\.css$/)) {
// add a second loader when loading images
rule.use.push({
loader: 'style-loader',
options: {
minimize: true
}
})
}
if (String(rule.test) === String(/\.(jpe?g|png|gif)$/)) {
// add a second loader when loading images
rule.use.push({
loader: 'url-loader',
options: {
// Inline files smaller than 10 kB (10240 bytes)
limit: 10 * 1024,
}
})
}
if (String(rule.test) === String(/\.svg$/)) {
// add a second loader when loading images
rule.use.push({
loader: 'svg-url-loader',
options: {
// Inline files smaller than 10 kB (10240 bytes)
limit: 10 * 1024,
// Remove the quotes from the url
// (they’re unnecessary in most cases)
noquotes: true,
}
})
}
})
}
}
};
`
This issue as been imported as question since it does not respect nuxt.js issue template. Only bug reports and feature requests stays open to reduce maintainers workload.
If your issue is not a question, please mention the repo admin or moderator to change its type and it will be re-opened automatically.
Your question is available at https://cmty.app/nuxt/nuxt.js/issues/c10071.
+1 same problem here, it's have been really hard to get good results in pagespeed
+1
would like to follow the issue
+1, Do we have best practices for this?
+1 🙏🏻
+1
Is any fix available? +1
I have the same issue and I spent hours and hours on better practices but my website still has a very low score, which I am guessing is caused mostly by the long "Script Evaluation".
Same issue after pagespeed updating.
+1
Since loading times (especially on mobile devices) have a very high priority nowadays, it is an absolute must!
+1. Same problem. Tested with Empty project, empty template, literally nothing - gets only 80 on mobile.
+1
<><
Do you think AMP is your solution?
Do you think AMP is your solution?
If your project can have, sure is a good replacement, in my case must is has not features enough =/
Hi
Maybe best way is fix this problem ? I think for desktop, page not collect from JS, but for mobile ( even I using SSR ), page everytime collect from JS.
so do you solved this problem?
+1
+1
?+1
+1
👍
+1
Most helpful comment
+1 same problem here, it's have been really hard to get good results in pagespeed