Nuxt生产模式加载资源延迟

Posted

技术标签:

【中文标题】Nuxt生产模式加载资源延迟【英文标题】:Nuxt production mode loading resources late 【发布时间】:2019-10-19 11:37:25 【问题描述】:

我目前正在运行一个在开发模式下运行良好的 nuxt 应用程序。但是,当我切换到生产模式时,您会看到一些 css 被推迟到稍后加载。我很确定这是一些 vuetify css。我说一些是因为有些类确实已经存在。

您可以通过刷新this page 来了解我的意思(确保禁用缓存)。

似乎我缺少某种 nuxt/webpack 配置来禁用它,但我不确定它是什么。

编辑:临时站点有时会关闭,所以这里是 gif 形式发生的事情,您可以看到某些关键的 css 稍后加载。

编辑 #2:在此处添加了最少的复制 https://github.com/amritk/vuetify-nuxt-repro

编辑#3:所以@Sabee 解决了我的最小复制问题,但这并没有解决我最初的问题。正如您在此处看到的,在客户端添加了一些样式块,但在服务器上不存在。如何确保在服务器上加载这些样式?

服务器:

客户:

[

Edit#3:特别是它的 v-layout 样式加载较晚。有没有办法在服务器上预加载这个 css?

【问题讨论】:

特定于 nuxt 和 vuetify。我已经在生产中使用了很长一段时间,并且为此花费了无数个小时。唯一合理的创可贴是使用[v-cloak],尽管这不应该发生在 s-s-r 上。 @Ohgodwhy 一定有一些配置可以让你解决这个问题,我的意思是它在开发中运行良好。这绝对是应该通过推迟加载某些脚本来“优化”的东西。我们只需要找出该配置在哪里并禁用它。 它在开发中运行良好,因为您使用的是hot module reloading。生产没有 1:1 奇偶校验的原因是您不再使用 hmr hmr 与 css 闪烁无关。如果没有最少的复制,很难说会发生什么 好吧,我已经添加了一个最小复制github.com/amritk/vuetify-nuxt-repro 【参考方案1】:

我向您的仓库创建了一个拉取请求并上传了代码to codesandbox。我认为你有一个 vuetify 语法问题,我建议你使用vuetify default app layout markup,你的代码必须是这样的:

default.vue 布局

<template lang="pug">
v-app
    v-toolbar(app color="primary")

        v-toolbar-title.white--text SiteLogo
        v-spacer
        v-toolbar-items
            v-btn(flat dark to="/" nuxt) home
            v-btn(flat dark to="/inspire" nuxt) Inspiration
            v-btn(flat dark) about    
    v-content
        nuxt
</template>

和 index.vue

<template lang="pug">
v-container
    v-layout(row wrap)
        v-flex(xs12 sm6 offset-sm3)
            v-card
                v-img(src="https://cdn.vuetifyjs.com/images/cards/desert.jpg" aspect-ratio="2.75")
                v-card-title(primary-title)
                    div
                        h3(class="headline mb-0") Kangaroo Valley Safari
                        div  card_text 
                v-card-actions
                    v-btn(flat color="primary") Share
                    v-btn(flat color="primary") Explore
        v-flex(pt-4)        
            div PLACEHOLDDDDDDDDDDDEEEEEEEEEEEEERRRRRRRRRRRR
            v-btn(to="/inspire" nuxt) inspuration
</template>
<script>
  export default 
    data () 
      return 
        card_text: 'Lorem ipsum dolor sit amet, brute iriure accusata ne mea. Eos suavitate referrentur ad, te duo agam libris qualisque, utroque quaestio accommodare no qui. Et percipit laboramus usu, no invidunt verterem nominati mel. Dolorem ancillae an mei, ut putant invenire splendide mel, ea nec propriae adipisci. Ignota salutandi accusamus in sed, et per malis fuisset, qui id ludus appareat.'
      
    
  
</script>

第二个你不需要写 vuetify loader 使用默认值。 (如果你需要配置它) 并将s-s-r:false添加到nuxt.config.js中的vuetify样式全局加载,更好的方法是删除nuxt.config.js中的vuetify样式加载在vuetify插件中进行。

Vuetify 插件

import Vue from 'vue'
import Vuetify from 'vuetify/lib'


Vue.use(Vuetify, 
    theme: 
        // HC Green
        primary: 
            lighten3: '#009546', // hc-light-green
            base: '#008940'      // hc-green
        ,
        // Blue
        accent: 
            lighten1: '#23BFFF', // light-blue
            base: '#0279D7',     // medium-blue
            darken3: '#0D47A1'   // dark-blue, darker-blue
        ,
        // Grey
        secondary: 
            lighten5: '#FFFFFF', // white
            lighten4: '#EFEFEF', // lighter-grey, dark-white
            lighten3: '#DFDFDF', // light-medium-grey, light-grey
            base: '#9F9F9F',     // medium-grey
            darken2: '#777777',  // pastel-grey
            darken3: '#3E3E3E',  // darker-grey, charcoal-grey, light-black, dark-medium-grey, dark-grey
            darken5: '#000000'   // black
        ,
        // Blue
        info: 
            base: '#0279D7'      // medium-blue
        ,
        // Orange/Yellow
        warning: 
            lighten3: '#fad53e', // light-orange aka yellow
            base: '#ff8800',     // from https://www.google.com/search?q=css+warning+color
            darken3: '#e65100'   // dark-orange
        ,
        // Red
        error: 
            lighten1: '#ff5252', // light-red
            base: '#B71C1C'      // medium-red
        ,
        // Green
        success: 
            lighten3: '#4CAf50', // light-green
            base: '#28a745',     // bootstrap green https://getbootstrap.com/docs/4.3/getting-started/theming/
            darken3: '#00592A'   // dark-green
        
    
)

nuxt.config.js

import Sass from 'sass'
import dotenv from 'dotenv'
import vuetifyLoader from './src/plugins/vuetify-loader'
dotenv.config()

const config = 
    mode: 'universal',
    debug: !(process.env.NODE_ENV === 'production'),

    // Loading bar color
    loading: 
        color: '#fff'
    ,

    // Global css
    css: [ src: '~/assets/style/vuetify.styl', lang: 'styl',s-s-r:false ],

    // Change src directory
    srcDir: 'src/',
    // Plugins
    plugins: [
         src: '@/plugins/vuetify' 
    ],

    // Nuxt.js modules
    modules: [
        '@nuxtjs/axios',
        '@nuxtjs/dotenv',
        ['cookie-universal-nuxt',  alias: 'nuxtCookies' ]
    ],

    // Babel
    babel: 
        presets: ['@babel/preset-env'],
        plugins: [
            '@babel/plugin-transform-modules-commonjs',
            'dynamic-import-node',
            '@babel/plugin-syntax-dynamic-import',
            [
                'transform-runtime',
                
                    polyfill: false
                
            ]
        ]
    ,

    // Build Config
    build: 
        filenames: 
            app: ( isDev ) => isDev ? '[name].js' : '[name]-[hash].js',
            chunk: ( isDev ) => isDev ? '[name].js' : '[name]-[hash].js'
        ,

        // Extend webpack config
        extend: (config, ctx) => 

            config.devtool = ctx.isClient ? 'eval-source-map' : 'inline-source-map'
        ,

        loaders: 
            sass: 
                implementation: Sass
            
        ,

        // Vuetify Loader - To auto load your components
        transpile: [/^vuetify/],
        plugins: [ vuetifyLoader]
    


export default config

如果您有任何问题,请联系我

【讨论】:

好的,我去看看。但是我确实需要使用 vuetify loader,因为我也使用它来加载我自己的组件, 好吧,那就用你自己的加载器吧。更新了请查看。 s-s-r: false 在 css 上做了什么?在 JS 上,这意味着仅在客户端上加载,但在这种情况下,我希望在服务器上加载 CSS s-s-r (true or false) 表示使用 Nuxt.js 开启或关闭服务器端渲染 您的 css 样式实际上并不需要 s-s-r,因为它不会在 SEO 中发挥作用,但在某些情况下,如果您将 s-s-r 与样式一起使用,它可能会加载更慢【参考方案2】:

好的@Sabee 的回答让我找出了问题所在。原来是来自 VLayout 组件的样式没有被加载。我相信这是一个 vuetify-loader 插件问题,而不是 nuxt。它被加载到服务器而不是客户端上。我所要做的就是更改我的配置以在开始时加载 VLayout 并且它起作用了!

Vuetify 插件

import Vue from 'vue'
import Vuetify,  VLayout  from 'vuetify/lib'

Vue.use(Vuetify, 
    options: 
        .
        .
        .
    ,
    theme: 
        .
        .
        .
    ,
    components: 
        VLayout
    
)

【讨论】:

你也可以在default.vue中添加VLayout样式

以上是关于Nuxt生产模式加载资源延迟的主要内容,如果未能解决你的问题,请参考以下文章

nuxt build 项目文件分析nuxt build 发布后的资源如何部署cdn

线程安全的单例模式

webpack5 开发模式与生产模式

JAVA的单例模式与延时加载

单例模式

多线程下单例模式:懒加载(延迟加载)和即时加载