webpack-contrib / css-loader

CSS Loader
MIT License
4.31k stars 601 forks source link

css-loader with `sourceMap: true` cause adding style tag delayed #613

Closed Aqours closed 7 years ago

Aqours commented 7 years ago

Version: 0.28.7

webpack.config.js

const path = require('path');
const webpack = require('webpack');

module.exports = {
    entry: './src/index.js',
    devtool: 'inline-source-map',
    module: {
        rules: [
            // babel-loader, ...
            {
                test: /\.less$/,
                use: [
                    {
                        loader: 'style-loader'
                    },
                    {
                        loader: 'css-loader',
                        options: {
                            sourceMap: true, // [1] `sourceMap: true` option will cause some problems.
                            minimize: {
                                discardComments: { removeAll: true }
                            }
                        }
                    },
                    {
                        loader: 'less-loader',
                        options: { sourceMap: true }
                    }
                ]
            }
        ]
    },
    output: {
        path: path.resolve(__dirname, 'dist/'),
        filename: 'bundle.js'
    },
    resolve: {
        extensions: ['.tsx', '.ts', '.jsx', '.js']
    }
};

// src/index.js file
import './less/index.less';
// other code, ...

What is the current behavior? bundle.js will add <style> tag to <head> tag when page loading bundle.js. normally, <style> tag will added firstly. actually, <style> tag added delayed when i setting sourceMap: true[1], which cause page flickering and error result style computed by scripts.

It works great when set sourceMap: false[1].

If the current behavior is a bug, please provide the steps to reproduce. repo link

webpack version: 3.6.0 node.js version: 8.0.0 Operating System: Windows 10 x64

zikaari commented 7 years ago

The cause of this behavior is the fact that turning sourceMaps on makes style loader switch from style tags to link tags with href set to Blob url of css.

But so what you ask? Its because hrefs are now treated as regular network requests, which are initiated from bundle.js, which means bundle.js loads, executes and renders content to document long before css is loaded (and painted).

In this profile, yellow strip is bundle.js, and after a while two purple ones are blobs of css. Performance timeline

Even though style tags are also inserted after bundle.js, they just happen to be slightly faster that you don't notice the flicker (also know as Flash of Unstyled Content - FOUC)

zikaari commented 7 years ago

As a side note, I'm working on new loader + plugin that aims to completely replace style-loader. I started this because the pain you described. This new loader + plugin allows source maps while not causing the flicker.

It does so by not injecting css at runtime but instead at compile time using HTMLWebpackPlugin and it also listens for hot updates once loaded. I'll add a link here once its up. stay subscribed to this discussion.

EDIT: The mentioned plugin is now live at https://github.com/chipto/css-visor

Aqours commented 7 years ago

Thanks for your answer. I read source code of style-loader. I found style-loader always use <style> tag when options.singleton: true, which can resolve this issue temporary. And I'm joyfull expecting your new loader + plugin.

zikaari commented 7 years ago

I have strong feeling that <style> tags don't play well with source maps. I might be wrong, let me know if I am 😜.

Aqours commented 7 years ago

😂yeah, sourcemap has no effect when css injected by style tag.

zikaari commented 7 years ago

@Aqours As promised the plugin is now live at https://github.com/chipto/css-visor

Please give it a shot and file any issues you run into. It's just a start of new horizons.

Aqours commented 7 years ago

It works. Sometimes, I want to debug single JavaScript file by proxy online. In this condition, this plugin is not suitable.

zikaari commented 7 years ago

Do you mind sharing minimal setup to reproduce that issue?

Aqours commented 7 years ago

😄Don't mind. It's not an issue.

alexander-akait commented 7 years ago

@Aqours can we close issue?