Klathmon / imagemin-webpack-plugin

Plugin to compress images with imagemin

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Images get only compressed by a few bytes

Wouter125 opened this issue · comments

I'm not getting the images to really minified. For example a jpg of 1,5mb only becomes 1,3mb, by using the default settings.

Other samples are;
JPG, 1,6MB -> 1,5MB
PNG, 1,6MB -> 1,5MB

Placing these in a compressor.io for example leaves me with the a jpg/png that has a size of around 258.92KB.

Perhaps I'm missing something here. I'm using htmlwebpackplugin for my static website and serve images like this;

<img src="<%=require('./images/homepage/HumanCaseCover.png')%>" />

I have my webpack common setup like this;

const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
    context: path.resolve('./app'),
    entry: {
        app: './js/index.js'
    },
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
        publicPath: ''
    },
    plugins: [
        new HtmlWebpackPlugin({
            filename: 'foreignrap.html',
            template: path.resolve(__dirname, './app/foreignrap.html'),
            inject: true
        }),
        new HtmlWebpackPlugin({
            filename: 'index.html',
            template: path.resolve(__dirname, './app/index.html'),
            inject: true
        }),
        new MiniCssExtractPlugin({
            filename: "styles/[name].css",
        }),
    ],
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /(node_modules|bower_components)/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['minify'],
                        plugins: ["@babel/plugin-proposal-object-rest-spread"]
                    }
                }
            },{
                test: /\.(woff|woff2|eot|ttf)$/,
                loader: "file-loader",
                options: {
                    outputPath: "fonts/",
                    name: "[hash].[ext]",
                },
                    // include: path.resolve("src", "static", "fonts"),
            },
            {
                test: /\.(png|jpg|gif|svg)$/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            name: '[path][name].[ext]'
                        }
                    }
                ]
            }
        ]
    }
};

And my webpack production file like this;

const webpack = require('webpack');
const common = require('./webpack.common.js');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CleanWebpackPlugin = require('clean-webpack-plugin');
const ImageminPlugin = require('imagemin-webpack-plugin').default;
const glob = require('glob');

module.exports = merge(common, {
    mode: 'production',
    devtool: 'source-map',
    plugins: [
        new CleanWebpackPlugin(['dist']),
        new webpack.DefinePlugin({
            'process.ev.NODE_ENV': JSON.stringify('production')
        }),
        new ImageminPlugin({
            externalImages: {
                context: 'app',
                sources: glob.sync('images/**/*.*'),
                destination: 'test/images'
            }
        })
    ],
    module: {
        rules: [
          {
            test: /\.scss$/,
            use: [{
                loader: MiniCssExtractPlugin.loader,
                options: {
                    publicPath: '../'
                }
            },{
                loader: "css-loader",
                options: { 
                    minimize: true 
                }
            },{
                loader: 'postcss-loader',
                options: {
                    plugins: () => [require('autoprefixer')]
                }
            },{
                loader: "sass-loader"
            }]
          }
        ]
    }
});

It seems to work correctly because it outputs all my images in test/images/subfolder/image.any. But the minification is just too minimal for a plugin like this.

If you have any suggestions please let me know because I'm running out of ideas. I also tried some custom settings, but that didn't do the trick either.

So this plugin on it's own doesn't actually do any of the image optimization, it includes imagemin plugins that do it.

By default, it includes these plugins:

  • jpegtran - default settings "progressive" set to false
  • gifsicle - optimization level set to 1 out of 3 with 3 being the "best compression"
  • optipng - optimization level set to 3 out of 7
  • pngquant - disabled by default

These are good defaults for most people, but they will not give you the best compression possible.

You can tweak these settings by tweaking the options for each of these plugins (see here in the readme, and the few bullet points below that, for links to those individual plugins that will show you all the options available).

Really read through those plugins documentation, as you can do both lossless and lossy compression on most images, and lossy will reduce the quality in some ways depending on how you configure it.

If you want, you can also search for additional imagemin-plugins on npm, there are many and you can add as many as you want to the plugins option with their own options.

If it helps, this is the config I use in a recent project to get good compression of PNGs (I don't use any JPEGs in this project):

      new ImageminPlugin({
        test: /\.gif|(?:pn|jpe?|sv)g$/i,
        optipng: {
          optimizationLevel: 7
        },
        pngquant: {
          quality: '95-100'
        }
      })

I hope this help!

I'm gonna close this issue since it's not a bug/issue with the program, but please feel free to respond if you still need more assistance, or feel there is a way that I can improve the README to get this information across better!