Skip to content

question: something wrong with my config? gulpjs is 7% slower than my original grunt config. #239

Description

@stylenclass

Been reading alot of reviews, and all of them says gulp is superior in speed on the same equivalent of grunt.

Below is my gulpfile, it seems slower by 7% on a equivalent grunt:

var gulp            = require('gulp'),
        gutil       = require('gulp-util'),
        rename      = require('gulp-rename'),
        clean       = require('gulp-clean'),
        usemin      = require('gulp-usemin'),
        ngmin       = require('gulp-ngmin'),
        rev                 = require('gulp-rev'),
        uglify          = require('gulp-uglify');

gulp.task('default', ['clean'], function() {
        gulp.start('scripts');
});

gulp.task('clean', function() {
    return gulp.src(['./index.html', 'assets/js/min']).pipe(clean());
});

gulp.task('copy', function() {
    return gulp.src('./dev.html')
    .pipe(rename('index.html'))
    .pipe(gulp.dest('./'));
});

gulp.task('usemin', ['copy'], function() {
  return gulp.src('./index.html')
    .pipe(usemin({ cssmin: false, htmlmin: false, jsmin: false }))
    .pipe(gulp.dest('./'))
});

gulp.task('ngmin', ['usemin'], function(){
    return gulp.src('assets/js/min/app.js')
                .pipe(ngmin())
                .pipe(gulp.dest('./assets/js/min/'))
})

gulp.task('scripts', ['ngmin'], function () {
    var context = rev.Context();
  return gulp.src('assets/js/min/*.js')
        .pipe(uglify())
      .pipe(rev(context))
      .pipe(gulp.dest('./assets/js/min/')),
       gulp.src('./index.html')
        .pipe(context.replace(/src="assets\/js\/min\/(\w+\.js)"/g, 'src="assets/js/min/{{$1}}"'))
        .pipe(gulp.dest('./'));
});

It seems that the bulk slowness is uglify, is there any special settings so it can be on par or faster than grunt?

Activity

  1. tomasdev commented on Feb 5, 2014

    @tomasdev

    Can you post some extra information such as console output to know the time it takes to uglify in both grunt / gulp?

    I've a similar setup, without ngmin and rev and it works faster than grunt. :/

  2. stylenclass commented on Feb 5, 2014

    @stylenclass
    Author

    gulp 1.77s user 0.21s system 90% cpu 2.191 total

    vs

    grunt -g root.js 1.53s user 0.08s system 100% cpu 1.603 total

  3. robrich commented on Feb 5, 2014

    @robrich
    Contributor
    var gulp            = require('gulp'),
            gutil       = require('gulp-util'),
            rename      = require('gulp-rename'),
            clean       = require('gulp-rimraf'),
            usemin      = require('gulp-usemin'),
            ngmin       = require('gulp-ngmin'),
            rev                 = require('gulp-rev'),
            uglify          = require('gulp-uglify');
    
    gulp.task('default', ['clean', 'scripts']);
    
    gulp.task('clean', function() {
        return gulp.src(['./index.html', 'assets/js/min'], {read:false}).pipe(clean());
    });
    
    gulp.task('scripts', ['clean'], function () {
      var context = rev.Context();
      // ideally these would be separate tasks, but because both depend on context, they're still combined
      return gutil.combine(
        gulp.src('assets/js/min/app.js')
          .pipe(ngmin())
          .pipe(uglify())
          .pipe(rev(context))
          .pipe(gulp.dest('./assets/js/min/')),
        gulp.src('./dev.html')
          .pipe(rename('index.html'))
          .pipe(usemin({ cssmin: false, htmlmin: false, jsmin: false }))
          .pipe(context.replace(/src="assets\/js\/min\/(\w+\.js)"/g, 'src="assets/js/min/{{$1}}"'))
          .pipe(gulp.dest('./'))
      );
    });

    Try this out and see if it's faster.

    The key paradigm shift from grunt is to think of tasks not as a step in the build process but rather as a workflow to execute with a set of files. The task is "scripts" and "css", not "lint" and "minify" and "concat". It'll likely be much faster by not re-writing and re-reading index.html

  4. stylenclass commented on Feb 6, 2014

    @stylenclass
    Author

    @robrich doesn't work, app.js is being generated from usemin

  5. robrich commented on Feb 6, 2014

    @robrich
    Contributor

    Sounds like the usemin plugin is not very discoverable, and breaks one of the cardinal rules of plugins: don't use fs. Here's a second look with this new info:

    var gulp = require('gulp');
    var gutil = require('gulp-util');
    var rename = require('gulp-rename');
    var clean = require('gulp-rimraf');
    var usemin = require('gulp-usemin');
    var ngmin = require('gulp-ngmin');
    var rev = require('gulp-rev');
    var uglify = require('gulp-uglify');
    
    gulp.task('clean', function() {
        return gulp.src(['./index.html', 'assets/js/min'], {read:false}).pipe(clean());
    });
    
    gulp.task('html', ['clean'], function () {
      return gulp.src('./dev.html')
        .pipe(rename('index.html'))
        .pipe(usemin({ cssmin: false, htmlmin: false, jsmin: false }))
        .pipe(context.replace(/src="assets\/js\/min\/(\w+\.js)"/g, 'src="assets/js/min/{{$1}}"'))
        .pipe(gulp.dest('./'));
    });
    
    gulp.task('js', ['html'], function () {
      return gulp.src('assets/js/min/app.js') // FRAGILE: gulp-usemin creates this file
        .pipe(ngmin())
        .pipe(uglify())
        .pipe(rev())
        .pipe(gulp.dest('./assets/js/min/')),
    });
    
    gulp.task('default', ['js']);

    It's much less simultaneous, but still very simple to read.

  6. sindresorhus commented on Feb 6, 2014

    @sindresorhus
    Contributor

    Don't use gulp-usemin. It's awful and the author is non-responsive.

  7. yocontra commented on Feb 6, 2014

    @yocontra
    Member

    👍 on not using gulp-usemin. It's going to be blacklisted off the plugin search soon

  8. tomasdev commented on Feb 7, 2014

    @tomasdev

    👍 yay to blacklisting that plugin

  9. appleboy commented on Feb 7, 2014

    @appleboy
    Contributor

    Good news.

  10. stylenclass commented on Feb 7, 2014

    @stylenclass
    Author

    @sindresorhus thanks for the advice, I was actually just duplicating what I have in grunt.

    @robrich still not working I have provided the actual testcase in github public repo:
    https://github.com/stylenclass/gulp

    So you can play around, the grunt file is also included there, just do the usual npm install for dependencies.


    Also just want to take note, that there are 2 files being created here, one is app.js and foo.js, which is something usemin created from the html blocks.

    Also only app.js should be ngminify since foo.js are already annotated (since they are usually just modules).

    <!-- build:js assets/js/min/app.js -->
        <script src="assets/js/1.js"></script>
        <script src="assets/js/2.js"></script>
        <!-- endbuild -->
        <!-- build:js assets/js/min/foo.js -->
        <script src="assets/js/3.js"></script>
        <script src="assets/js/4.js"></script>
        <!-- endbuild -->
  11. stylenclass commented on Feb 7, 2014

    @stylenclass
    Author

    I did see @robrich comment
    // FRAGILE: gulp-usemin creates this file

    And if we're not to use usemin, what can we use as an alternative? I have provided my gruntfile here:
    https://github.com/stylenclass/gulp

  12. yocontra commented on Feb 7, 2014

    @yocontra
    Member

    @stylenclass Why not just build those rules into your gulpfile instead of using a plugin that reads them from your index.html?

  13. stylenclass commented on Feb 7, 2014

    @stylenclass
    Author

    @contra the reason being I have different configurations for each project, basically I have root and i have subfolders:

    /root
      /folder1
      /folder2
    

    Like that. I also want to use the rev plugin that updates index file with the revision files.

  14. stylenclass commented on Feb 7, 2014

    @stylenclass
    Author
  15. 2 remaining items

  16. robrich commented on Feb 8, 2014

    @robrich
    Contributor

    What if instead of getting the list of scripts by parsing an HTML file it
    got the list by traversing a directory?

  17. stylenclass commented on Feb 9, 2014

    @stylenclass
    Author

    @robrich some of the modules comes from bower_components, some of them comes from assets/js
    In bower_components, there is no standard way of referencing the js files. eg

    some reference like this
    bower_components/packagename/dist/package-name.js

    sometimes like this
    bower_components/packagename/package-name.js

    That's why I was using usemin in the first place, when I started grunt.

  18. robrich commented on Feb 9, 2014

    @robrich
    Contributor

    @contra what if there was a vinyl-fs source that parsed an HTML file for
    URLs? Can this happen in userland?

  19. yocontra commented on Feb 9, 2014

    @yocontra
    Member

    @robrich Plugins aren't limited to being just processors in the streams. They can be the head and the tail too.

    someplugin('file.html')
      .pipe(otherplugin())
      .pipe(gulp.dest('folder'))
      .pipe(someplugin.dest('stuff.html'))

    Just make sure your head puts out vinyl objects, and your tail (if you make one) accepts vinyl objects so it works within the ecosystem

  20. robrich commented on Feb 9, 2014

    @robrich
    Contributor

    This sounds like the way to replace usemin and the plugin that replaces
    URLs with data URLs. Both plugins currently use fs for their tasks. This is
    a much better solution.

  21. stylenclass commented on Feb 10, 2014

    @stylenclass
    Author

    oh wow, the syntax is very nice @contra and @robrich

  22. stylenclass commented on Feb 15, 2014

    @stylenclass
    Author

    hmm, that's an interesting take @thasmo . See here's my workflow,
    I have a dev.html (which links to the un minified version of the scripts) very useful to debugging, and index.html for production.


    Now I know what I can always use sourcemap, but I always do the minification after I debug everything in the unminified version. So not sure if a continuous minification is a right fit for that?

  23. cgross commented on Mar 8, 2014

    @cgross

    FWIW, I have a very similar workflow as you do @stylenclass. I always want to assemble a list of js/css from my index.html rather than via glob patterns. And like others have mentioned, I dislike the do-it-all/magical nature of usemin (either grunt-usemin or gulp-usemin).

    I've created gulp-dom-src to do essentially whats been suggested in this thread. Combine that with gulp-cheerio to do what usemin does in a less magical and more flexible way. Checkout a simplistic concat+min example.

  24. stylenclass commented on Mar 20, 2014

    @stylenclass
    Author

    @cgross say if I have 2 blocks of code I wanted? instead of 1 big js?
    eg. module.full.min.js and app.full.min.js ?

  25. cgross commented on Mar 20, 2014

    @cgross

    @stylenclass Sure. Gulp-dom-src pulls based on CSS selectors. So just add a data attribute to your module scripts. Something like data-module="true". Then configure your selector in gulp-dom-src like script[data-module="true"].

    So a more complete example:

    <script src="whatever/whatever.js"></script>
    <script src="whatever/whatever.js"></script>
    
    <script src="whatever/whatever.js" data-module="true"></script>
    <script src="whatever/whatever.js" data-module="true"></script>
    //do the app.full.min.js
    gulp.task('defaultJs', function () {
        domSrc({ file: 'index.html', selector: 'script[data-module!="true"]', attribute: 'src' })
            .pipe(concat('app.full.min.js'))
            .pipe(uglify())
            .pipe(gulp.dest('dist/'));
    });
    
    //do module.full.min.js
    gulp.task('moduleJs', function () {
        domSrc({ file: 'index.html', selector: 'script[data-module="true"]', attribute: 'src' })
            .pipe(concat('module.full.min.js'))
            .pipe(uglify())
            .pipe(gulp.dest('dist/'));
    });
  26. stylenclass commented on Mar 21, 2014

    @stylenclass
    Author

    @cgross

    • oh that seems like a plausible solution, would you happen to use gulp-rev?
  27. cgross commented on Mar 21, 2014

    @cgross

    I don't but I don't see any reason why you couldn't use that in this workflow.

  28. stylenclass commented on Mar 21, 2014

    @stylenclass
    Author

    I'm just having problems getting the context name of gulp-rev (the generated filename) and write it in html file.

    Because in your example

     $('body').append('<script src="app.full.min.js"></script>');
    $('head').append('<link rel="stylesheet" href="app.full.min.css">');
    

    You assume to know the full name of css, what if its generated by gulp-rev for example?

  29. stylenclass commented on Apr 20, 2014

    @stylenclass
    Author

    This sounds like the way to replace usemin and the plugin that replaces
    URLs with data URLs. Both plugins currently use fs for their tasks. This is
    a much better solution.

    someplugin('file.html')
      .pipe(otherplugin())
      .pipe(gulp.dest('folder'))
      .pipe(someplugin.dest('stuff.html'))

    I have yet to come across this kind of plugin. I am very close on my ideal build, using useref and gulp-rev replace

    Now the only problem is useref breaks when you use gulp.watch jonkemp/gulp-useref#6 at least that's the only limitation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions