Feature Request: Stats for time spent in different loaders

I often am trying to get a better understanding of where time is being spent in webpack. Node v6 brings a tool to the table with solid support for running webpack attached to the web inspector profiler, but that is a quite the forest to jump into.

What I want is a high level view of what loaders are taking the most time.

Given the following devtime config it would be great to see what time is spent in js total and stylus total and also by loader. While working to optimize our development startup time as well as production build times it would be amazing to see where time is being spent from things that we are configuring (not all of webpack internals as well).

loaders: [
  {test: /\.js/, loaders: ['babel']},
  {test: /\.styl$/, loader: 'style!css!stylus'}
];

This would allow us to easily focus on what configuration and tools to experiment with for the largest wins.

Author: Fantashit

6 thoughts on “Feature Request: Stats for time spent in different loaders

  1. +1 to this. @TheLarkInn Let’s work together on landing this improvement into webpack.

    I wonder if we could use a format like HAR to dump the timing with, just so it is a generic format that can be loaded by a lot of different tools, instead of implementing a custom format, or a proprietary format.

  2. I’m down for that. There are some very general and more specific phases that go on in webpack. What do you think the best way to break them up would be?

    Here is just an idea (feel free to critique): This is more like “phases of webpack of things that are happening”.:

    Phase Based(?)

    1. Initialization: Compiler consumes options, plugins are applied based on them. Up until the beginning of the Dep Graph collection begins:

      compilation.addEntry(this.context, dep, this.name, callback);
    2. Dep Graph Creation: This is a bunch of parts
      a. (starting with entry): Send raw request (entry path), resolve it
      b. resolver returns path to Module Factories, collects source and creates module object
      c. loaders are applied
      d. module is parsed
      e. Dependencies Attached to module.
      f. For each Dependency, Repeat a/f (BFS Traversal)

    3. Sealing Phase
      a. Modules are put into chunks
      b. <Bunch of Plugin hooks fire and perform optimizations, side-effects etc>

    4. (Render Phase)[https://github.com/webpack/webpack/blob/master/lib/Compilation.js#L1233]
      a. chunkTemplate.render()
      b. which trigger each module in above chunks to render
      c. which call the Dependency Templates to render dependencies.

    5. Additional Assets etc. (other plugins creating stuff) + Emit

    6. Make stats!

    Maybe another idea would be since there are so many plugins, that we could also take a plugin approach.

    Event based timings (?)

    SomePlugin.js

    class SomePlugin {
      apply(compiler) {
        compiler.plugin("some-event", () => {
          start()
    
          stop()
        });
      }
    }

    This doesn’t feel like the cleanest approach, but just throwing ideas out there for this.

  3. I’ve created a plugin to do this (measure timing stats for loaders + plugins): https://www.npmjs.com/package/speed-measure-webpack-plugin

    It aggregates all grouped loaders (as the api isn’t granular enough otherwise, and tbh I’m not sure timing stats on each individual loader is that helpful)

    It gets the plugin timing data by wrapping all of the plugins (so the original plugins are only ever used through a wrapper)

    Please give it a go, and let me know what you think

  4. Yes, but my point is that it still involves digging around through the devtools, and provided you have some knowledge with the profiler and how to use it, you have to know what you’re looking for. Not to mention, you could still profile this stuff without this plugin.

    The better solution here would be to just time and log the aggregated times of the loader execution, with maybe some other stats (how many files the loader had to process, whatnot), a la the output of webpack.ProgressPlugin({profile: true}).

    PostCSS does this, and I’ve found it to be very helpful.

Comments are closed.