2014-09-16 4 views
0

Я использую grunt, чтобы объединить элементы reoccurring (нижний колонтитул, панель меню ..) на страницы простого веб-сайта, используя печенье.Оптимизация Grunt

В моей корневой директории я называю grunt --force

Процесс занимает много времени:

mocha:all 11.1s 
concurrent:dist 400.1s 
Total 414.5s 

Вопрос: Как я могу оптимизировать процесс и сэкономить время?

Gruntfile.js выглядит следующим образом:

'use strict'; 

// # Globbing 
// for performance reasons we're only matching one level down: 
// 'test/spec/{,*/}*.js' 
// use this if you want to recursively match all subfolders: 
// 'test/spec/**/*.js' 

module.exports = function (grunt) { 

    // Load grunt tasks automatically 
    require('load-grunt-tasks')(grunt); 

    // Time how long tasks take. Can help when optimizing build times 
    require('time-grunt')(grunt); 

    // Define the configuration for all the tasks 
    grunt.initConfig({ 

     // Project settings 
     config: { 
      // Configurable paths 
      app: 'app', 
      dist: 'dist/public', 
      prebake: 'appPreBake' 
     }, 

     bake: { 
      build: { 
       options: { 
        basePath: 'appPreBake' 
       }, 
       files: { 
        // Files that use templates should live in appPreBake. 
        // Add new files to the list below so that they will be 
        // added to the app/ folder, where they are served for the 
        // test server. When built they are compiled and put in the 
        // dist folder. 
        // 
        // grunt-bake adopts the formula: 
        // outputFile: templateFile 
        '<%= config.app %>/index.html': '<%= config.prebake %>/index.html', 
        '<%= config.app %>/first/index.html': '<%= config.prebake %>/first/index.html', 
        '<%= config.app %>/second/index.html': '<%= config.prebake %>/second/index.html', 
        '<%= config.app %>/third/index.html': '<%= config.prebake %>/third/index.html', 
        '<%= config.app %>/photos/index.html': '<%= config.prebake %>/photos/index.html', 
        '<%= config.app %>/about/index.html': '<%= config.prebake %>/about/index.html', 
        '<%= config.app %>blog.html': '<%= config.prebake %>blog.html' 
       } 
      } 
     }, 

     // Watches files for changes and runs tasks based on the changed files 
     watch: { 
      // We want to rerun bake every time we change a template file in 
      // the prebake directory. 
      bake: { 
       files: ['appPreBake/**'], 
       tasks: 'bake:build' 
      }, 
      bower: { 
       files: ['bower.json'], 
       tasks: ['bowerInstall'] 
      }, 
      js: { 
       files: ['<%= config.app %>/scripts/{,*/}*.js'], 
       tasks: ['jshint'], 
       options: { 
        livereload: true 
       } 
      }, 
      jstest: { 
       files: ['test/spec/{,*/}*.js'], 
       tasks: ['test:watch'] 
      }, 
      gruntfile: { 
       files: ['Gruntfile.js'] 
      }, 
      styles: { 
       files: ['<%= config.app %>/styles/{,*/}*.css'], 
       tasks: ['newer:copy:styles', 'autoprefixer'] 
      }, 
      livereload: { 
       options: { 
        livereload: '<%= connect.options.livereload %>' 
       }, 
       files: [ 
        '<%= config.app %>/{,*/}*.html', 
        '.tmp/styles/{,*/}*.css', 
        '<%= config.app %>/images/{,*/}*' 
       ] 
      } 
     }, 

     // The actual grunt server settings 
     connect: { 
      options: { 
       port: 9000, 
       livereload: 35729, 
       // Change this to '0.0.0.0' to access the server from outside 
       hostname: 'localhost' 
      }, 
      livereload: { 
       options: { 
        open: true, 
        base: [ 
         '.tmp', 
         '<%= config.app %>' 
        ] 
       } 
      }, 
      test: { 
       options: { 
        port: 9001, 
        base: [ 
         '.tmp', 
         'test', 
         '<%= config.app %>' 
        ] 
       } 
      }, 
      dist: { 
       options: { 
        open: true, 
        base: '<%= config.dist %>', 
        livereload: false 
       } 
      } 
     }, 

     // Empties folders to start fresh 
     clean: { 
      dist: { 
       files: [{ 
        dot: true, 
        src: [ 
         '.tmp', 
         '<%= config.dist %>/*', 
         '!<%= config.dist %>/.git*' 
        ] 
       }] 
      }, 
      server: '.tmp' 
     }, 

     // Make sure code styles are up to par and there are no obvious mistakes 
     jshint: { 
      options: { 
       jshintrc: '.jshintrc', 
       reporter: require('jshint-stylish') 
      }, 
      all: [ 
       'Gruntfile.js', 
       '<%= config.app %>/scripts/{,*/}*.js', 
       '!<%= config.app %>/scripts/vendor/*', 
       'test/spec/{,*/}*.js' 
      ] 
     }, 

     // Mocha testing framework configuration options 
     mocha: { 
      all: { 
       options: { 
        run: true, 
        urls: ['http://<%= connect.test.options.hostname %>:<%= connect.test.options.port %>/index.html'] 
       } 
      } 
     }, 

     // Add vendor prefixed styles 
     autoprefixer: { 
      options: { 
       browsers: ['last 1 version'] 
      }, 
      dist: { 
       files: [{ 
        expand: true, 
        cwd: '.tmp/styles/', 
        src: '{,*/}*.css', 
        dest: '.tmp/styles/' 
       }] 
      } 
     }, 

     // Automatically inject Bower components into the HTML file 
     bowerInstall: { 
      app: { 
       src: ['<%= config.app %>/index.html'], 
       ignorePath: '<%= config.app %>/' 
      } 
     }, 

     // Renames files for browser caching purposes 
     rev: { 
      dist: { 
       files: { 
        src: [ 
         '<%= config.dist %>/scripts/{,*/}*.js', 
         '<%= config.dist %>/styles/{,*/}*.css', 
         '<%= config.dist %>/images/{,*/}*.*', 
         '<%= config.dist %>/styles/fonts/{,*/}*.*', 
         '<%= config.dist %>/*.{ico,png}' 
        ] 
       } 
      } 
     }, 

     // Reads HTML for usemin blocks to enable smart builds that automatically 
     // concat, minify and revision files. Creates configurations in memory so 
     // additional tasks can operate on them 
     useminPrepare: { 
      options: { 
       dest: '<%= config.dist %>' 
      }, 
      html: '<%= config.app %>/index.html' 
     }, 

     // Performs rewrites based on rev and the useminPrepare configuration 
     usemin: { 
      options: { 
       assetsDirs: ['<%= config.dist %>', '<%= config.dist %>/images'] 
      }, 
      html: ['<%= config.dist %>/{,*/}*.html'], 
      css: ['<%= config.dist %>/styles/{,*/}*.css'] 
     }, 

     // The following *-min tasks produce minified files in the dist folder 
     imagemin: { 
      // There are several issues with this task in version 0.5.x. If you 
      // are encountering problems where it hangs, claims to not find 
      // files, or progresses on subsequent runs but emitting images of 
      // size 0, uncomment this options object. It will stop caching and 
      // this should fix the problem, although it will take longer. 
      // For a more thorough discussion, see the following links: 
      // https://github.com/gruntjs/grunt-contrib-imagemin/issues/140 
      // http://stackoverflow.com/questions/21175673/grunt-contrib-imagemin-output-fatal-error-enoent-no-such-file-or-directory 
      //options: { 
      // cache: false 
      //}, 
      dist: { 
       files: [{ 
        expand: true, 
        cwd: '<%= config.app %>/images', 
        src: '{,*/}*.{gif,jpeg,jpg,png}', 
        dest: '<%= config.dist %>/images' 
       }] 
      } 
     }, 

     svgmin: { 
      dist: { 
       files: [{ 
        expand: true, 
        cwd: '<%= config.app %>/images', 
        src: '{,*/}*.svg', 
        dest: '<%= config.dist %>/images' 
       }] 
      } 
     }, 

     htmlmin: { 
      dist: { 
       options: { 
        collapseBooleanAttributes: true, 
        collapseWhitespace: true, 
        removeAttributeQuotes: true, 
        removeCommentsFromCDATA: true, 
        removeEmptyAttributes: true, 
        removeOptionalTags: true, 
        removeRedundantAttributes: true, 
        useShortDoctype: true 
       }, 
       files: [{ 
        expand: true, 
        cwd: '<%= config.dist %>', 
        src: '{,*/}*.html', 
        dest: '<%= config.dist %>' 
       }] 
      } 
     }, 

     // By default, your `index.html`'s <!-- Usemin block --> will take care of 
     // minification. These next options are pre-configured if you do not wish 
     // to use the Usemin blocks. 
     // cssmin: { 
     //  dist: { 
     //   files: { 
     //    '<%= config.dist %>/styles/main.css': [ 
     //     '.tmp/styles/{,*/}*.css', 
     //     '<%= config.app %>/styles/{,*/}*.css' 
     //    ] 
     //   } 
     //  } 
     // }, 
     // uglify: { 
     //  dist: { 
     //   files: { 
     //    '<%= config.dist %>/scripts/scripts.js': [ 
     //     '<%= config.dist %>/scripts/scripts.js' 
     //    ] 
     //   } 
     //  } 
     // }, 
     // concat: { 
     //  dist: {} 
     // }, 

     // Copies remaining files to places other tasks can use 
     copy: { 
      dist: { 
       files: [{ 
        expand: true, 
        dot: true, 
        cwd: '<%= config.app %>', 
        dest: '<%= config.dist %>', 
        src: [ 
         '*.{ico,png,txt}', 
         '.htaccess', 
         'images/{,*/}*.webp', 
         '{,*/}*.html', 
         'styles/fonts/{,*/}*.*', 
         'bower_components/bootstrap/dist/fonts/*.*' 
        ] 
       }, { 
        // Have to manually add this copying to ensure that the 
        // glyphicons make it over. 
        // This solution comes from: 
        // http://stackoverflow.com/questions/18572941/why-does-yeoman-build-without-glyphicons 
        expand: true, 
        cwd: '<%= config.app %>/bower_components/bootstrap/dist/fonts', 
        dest: '<%= config.dist %>/fonts', 
        src: '*.*' 
       }] 
      }, 
      styles: { 
       expand: true, 
       dot: true, 
       cwd: '<%= config.app %>/styles', 
       dest: '.tmp/styles/', 
       src: '{,*/}*.css' 
      } 
     }, 

     // Run some tasks in parallel to speed up build process 
     concurrent: { 
      server: [ 
       'copy:styles' 
      ], 
      test: [ 
       'copy:styles' 
      ], 
      dist: [ 
       'copy:styles', 
       'imagemin', 
       'svgmin' 
      ] 
     } 
    }); 

    grunt.registerTask('serve', function (target) { 
     if (target === 'dist') { 
      return grunt.task.run(['build', 'connect:dist:keepalive']); 
     } 

     grunt.task.run([ 
      'clean:server', 
      'concurrent:server', 
      'autoprefixer', 
      'connect:livereload', 
      'watch' 
     ]); 
    }); 

    grunt.registerTask('server', function (target) { 
     grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.'); 
     grunt.task.run([target ? ('serve:' + target) : 'serve']); 
    }); 

    grunt.registerTask('test', function (target) { 
     if (target !== 'watch') { 
      grunt.task.run([ 
       'clean:server', 
       'concurrent:test', 
       'autoprefixer' 
      ]); 
     } 

     grunt.task.run([ 
      'connect:test', 
      'mocha' 
     ]); 
    }); 

    grunt.registerTask('build', [ 
     'clean:dist', 
     'bake', 
     'useminPrepare', 
     'concurrent:dist', 
     'autoprefixer', 
     'concat', 
     'cssmin', 
     'uglify', 
     'copy:dist', 
     'rev', 
     'usemin', 
     'htmlmin' 
    ]); 

    grunt.registerTask('default', [ 
     'newer:jshint', 
     'test', 
     'build' 
    ]); 
}; 
+0

у вас есть много изображений и SVG-файлов? похоже, что ваша задача concurrent: dist главным образом копирует файлы стилей и минимизирует изображения. так что это ваше узкое место (из того, что я могу сказать) – gabereal

+0

Всего, вероятно, не более 6 изображений – bogus

+0

что происходит, когда вы просто запускаете grunt без --force? – gabereal

ответ

0

сначала нужно увидеть, где именно проблема попробуйте запустить хрюкать с помощью -v флаг

grunt -v 

и после шагов здесь. Пожалуйста, имейте в виду отметить шаг, который, похоже, застрял весь процесс.

Для времени и производительности попробуйте использовать плагин time-grunt, который покажет вам хорошие графики продолжительности для каждой задачи.

enter image description here

Смежные вопросы