Grunt with livereload, to slow - performance

Here is my Gruntfile.js
watch: {
options: { livereload: true },
compass: {
files: ['assets/sass/*.{scss,sass}'],
tasks: ['compass']
},
// js: {
// files: '<%= jshint.all %>',
// tasks: ['jshint', 'uglify']
// },
livereload: {
// files: ['*.html', '*.php', 'assets/stylesheets/**/*.{css}']
files: ['*.html', '*.php', 'assets/stylesheets/custom.css']
}
},
// compass and scss
compass: {
dist: {
options: {
config: 'config.rb',
force: true
}
}
},
and this is output from grunt watch :
Done, without errors.
... Reload assets/sass/custom.scss ...
... Reload assets/stylesheets/custom.css ...
Completed in 11.033s at Fri Dec 06 2013 14:20:48 GMT+0100 (CET) - Waiting...
OK
>> File "assets/stylesheets/custom.css" changed.
>> File "assets/sass/custom.scss" changed.
Running "compass:dist" (compass) task
overwrite assets/stylesheets/custom.css (0.701s)
identical assets/stylesheets/app.css (3.452s)
Compilation took 4.158s
Done, without errors.
... Reload assets/sass/custom.scss ...
... Reload assets/stylesheets/custom.css ...
Completed in 10.719s at Fri Dec 06 2013 14:21:53 GMT+0100 (CET) - Waiting...
..so, why is livereload taking so much time for refreshing the page,
10secs to preview any change in my .scss file, also how it would be
possible not to refresh page completely but only inject .css changes
in page?
..another thing i would like to know is how to avoid that
compilation lag on app.css, which took almost 4 secs, and it is not
even changed?
I am using livereload browser extension with this configuration.
Thanks.

1a: to speed things up in a watch task try the option spawn:false. This might make things unstable, but it's worth a try. If it seems ok go for it. It might cause you problems later though if you add a lot of different tasks to the watch task. But you can worry about that then and disable it potentially.
1b:
First of all don't enable livereload on for the compass task. (you have it globally, take in only in the css) Because of this it will trigger a livereload event for the scss file as well. But since the livereload client doesn't know this file then it will reload the whole page. Make sure the only reported file is the compiled css.
Secondly the watch task will trigger livereload for previously changed files as well. This is a known but, I believe it is fixed in master, but no published yet.
https://github.com/gruntjs/grunt-contrib-watch/issues/205
2:
Well it have to compile it to compare it, then it just reports that it is identical.

To only inject .css changes:
watch: {
compass: {
files: ['assets/sass/*.{scss,sass}'],
tasks: ['compass']
},
livereload: {
files: ['assets/stylesheets/*.css'],
options: { livereload: true }
}
}
Unfortunately, I am also getting slow and similar compilation times (it must be compass).

Related

Firefox Developer Tools don't work with Webpack CSS source maps

I have a problem to make Firefox Developer Tools (Firefox Developer Edition 59.0b7) work with CSS source maps generated by Webpack in development mode (using webpack-dev-server).
In Firefox Developer Tools, when I inspect an alement, it's CSS rules locations are some chunk's hashes, e.g. blob:http://localhost:9090/1e451f65-5d5a-4155-a7a9-96df9945244b instead of real file names (screen below). Also those locations links are invalid - clicking them doesn't take me to the source file.
I'm also sometimes getting this kind of errors in Firefox Developer Tools console, which I are probably connected:
Source map error: Error: sourceMapURL could not be parsed Resource URL: blob:null/b9a1fdd6-c0a3-4426-9df0-d50f1e8dc670 Source Map URL: data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3JvYmVydC9wcm9ncmFtbWluZy93ZWJwYWNrLXBsYXlncm91bmQvc3JjL2NvbXBvbmVudC1hL2NvbXBvbmVudC1hLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtJQUNJLGNBQWM7SUFDZCx1QkFBdUI7SUFDdkIsa0JBQWtCO0NBQ3JCOzs7QUFHRDtJQUNJLG1CQUFtQjtJQUNuQixpQkFBaUI7SUFDakIsaUJBQWlCO0NBQ3BCOzs7QUFHRDtJQUNJLG1CQUFtQjtDQUN0QiIsImZpbGUiOiJjb21wb25lbnQtYS5jc3MiLCJzb3VyY2VzQ29udGVudCI6WyIuQ29tcG9uZW50QSB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgIGZsZXgtd3JhcDogbm93cmFwO1xufVxuXG5cbi5Db21wb25lbnRBLUhlYWRlciB7XG4gICAgbWFyZ2luLWJvdHRvbTogM3B4O1xuICAgIGJhY2tncm91bmQ6ICNlZWU7XG4gICAgZm9udC1zaXplOiAxLjVlbTtcbn1cblxuXG4uQ29tcG9uZW50QS1Cb2R5IHtcbiAgICBwYWRkaW5nLWxlZnQ6IDEwcHg7XG59XG4iXSwic291cmNlUm9vdCI6IiJ9[Learn More]
Everything displays perfectly fine in Chrome Developer Tools (Chrome 59.0.3071.104) - I see original file names in the inspector (screen below) and original SCSS contents after clicking the the file name link.
Is there a way to make Firefox work properly with Webpack's CSS source maps like Chrome does?
My configuration
I have Enable Source Maps turned on in Developer Tools' options. devtools.debugger.source-maps-enabled is set to true in about:config.
Here are relevant excerpts from my Webpack config:
// I tried different devtools but the results in Firefox were the same.
devtool: 'eval-source-map'
(...)
// Chain of loaders for CSS files.
{
test: /\.(scss|sass|css)$/,
use: [
{
loader: 'style-loader',
options: {
sourceMap: true
}
},
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
sourceMap: true,
plugins: [
autoprefixer
]
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
outputStyle: 'expanded',
/* Custom functions to use in Sass files. */
functions: {
'base64encode($text)': function(text) {
let textInBase64 = new Buffer.from(text.getValue()).toString('base64');
return new sass.types.String(textInBase64);
}
}
}
}
]
}
I'd guess this is a bug in the Firefox DevTools. And as far as I know, there is currently a lot of work going into fixing such source mapping issues.
Therefore, you should first try out the latest Nightly build and see if it's still a problem there. And if yes, file a bug for it and maybe mark it as blocker of bug 1339970.

Grunt SASS Watch not working

I have a grunt file as shown below. The problem I am having is when I change the contents of a .scss file, grunt watch sass does not trigger a refresh. Is there something obvious that I am doing wrong?
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
build : {
dest: '_site'
},
sass: {
dist: {
options: {
style: 'compressed',
trace: true
},
files: {
'css/main.css': '_scss/main.scss',
'css/ie8.css': '_scss/ie8.scss',
'css/ie9.css': '_scss/ie9.scss'
}
}
},
shell: {
jekyllBuild: {
command: 'jekyll build'
},
jekyllServe: {
command: 'jekyll serve'
}
},
watch: {
files: ['_layouts/*.html', '*.md', '*.yml'],
// SASS watch does not work :(
sass: {
files: ['_scss/**/*.scss'],
tasks: ['sass:dist'] // This should be sass'
}
}
});
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-shell');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-jekyll');
// Compiles SASS, Builds Jekyll, and Serves Jekyll.
grunt.registerTask('default', ['sass:dist', 'shell:jekyllBuild', 'shell:jekyllServe']);
}
Also when I change a .scss file, the terminal indicates that a file has been changed but grunt watch sass does not run.
Regenerating: 1 file(s) changed at 2015-08-05 13:14:50 ...done in 0.017384 seconds.
EDIT:
I figured it out. What I was attempting to do was use grunt to watch my sass files and re-compile when changes were made. I also wanted jekyll to serve & watch the html files for changes. These things cannot be ran concurrently which was what I was attempting to do. I did happen to find a helper called 'load-grunt-tasks' which allows for concurrent tasks to be ran by adding the following code to the gruntfile:
concurrent: {
serve: [
'sass',
'watch',
'shell:jekyllServe'
],
options: {
logConcurrentOutput: true
}
},
// Then register the following tasks
// Register the grunt serve task
grunt.registerTask('serve', ['concurrent:serve']);
// Then run the following from the terminal:
grunt serve
At first some general troubleshooting:
Did you made sure all dependencies are properly installed? npm install
Are all dependencies up to date? npm update
I see that you're using Jekyll, why do you introduce Grunt at this point? Jekyll comes with its own watch task. This may produce some errors.
watch: {
files: ['_layouts/*.html', '*.md', '*.yml'],
// SASS watch does not work :(
sass: {
files: ['_scss/**/*.scss'],
tasks: ['sass:dist']
}
}
This looks kinda broken to me. What is watch supposed to do with files: [...]? There is no task to be executed while watching over these files. You don't have any grunt tasks which would modify .html, .md or .yml files, so why do you even list them?
Apart from that, it looks fine to me.
Is there a reason that you're using Grunt for this? Jekyll comes with a perfectly fine Sass watcher, and if you want to carry out any further pre/post-processing tasks you can do so using Jekyll's plugin system.
You can place your .scss/.sass files in _sass, and call them from a .scss/.sass file located anywhere else that starts with some YAML frontmatter.
A common structure would be something like this:
- _scss/
- normalize.scss
- typography.scss
- [whatever].scss
- assets/
- main.scss
With assets/main.scss containing the following:
---
# You just need these --- lines to tell Jekyll to parse this file.
---
#import "normalize";
#import "typography";
#import [...]
// Other styles too
body {
background-color: #f00;
color: {{ site.branding.color }}; // Can even use Jekyll variables
}
As far as plugins go, I'm using octopress-autoprefixer to automatically prefix CSS3 properties. The process for using this plugin is as follows:
gem install octopress-autoprefixer
Add this to your _config.yml:
gems:
- octopress-autoprefixer
That's it.
Now when you make any changes to your Sass, after the CSS files are generated in _site/, autoprefixer will do it's magic to them.

Project file structure, how to reduce SASS compilation time in compass when you have a lot of pages?

For a project I am using SASS 3.2.19 and Compass 0.12.5 combined with the last version of Grunt.
My file structure looks like this :
styles/
css/
page1.css
page2.css
page3.css
...
sass/
page1.scss
page2.scss
page3.scss
...
generics/
_general.scss
_menu.scss
_ie.scss
...
partials/
_sectionBegin.scss
_sectionClients.scss
...
In each pages{number}.scss file I import the scss blocks I actually need like this :
#import "generics/general"; // inside this file _ie.scss is imported
#import "generics/menu";
#import "partials/sectionBegins";
#import "partials/sectionClients";
.additionalStyles {
background: url(/example/example-cover.jpg) no-repeat;
}
And finally, here is my Gruntfile.js :
compass: {
dev: {
options: {
sassDir: ['styles/sass'],
cssDir: ['styles/css'],
outputStyle: 'expanded',
noLineComments: true,
environment: 'development'
}
},
...
grunt.registerTask('default', ['compass:dev' , 'watch']);
So, what I am doing here is setting Grunt to watch the sass/ repository. As soon as it detects some changes the page.css will be overwrite.
Well, this project structure actually works perfectly when there are only a few pages but now that I have more than 40 pages the compilation time is taking approximately 1min.
Indeed supposed that I edit a .scss file which is used by all the pages, all the pages will have to be overwritten.
So, what I am missing here ? How can I improve my project file structure and do you have some good examples of a gruntfile conf in a similar scenario ?
We also have a Sass project with a lot of partials. We still haven't figured out what to do when modifying a partial that is used by a lot of .scss files; there really isn't a way to get around having to compile all of them (eventually, when you deploy; sometimes you're only working on one page and really do only need one to compile in the short term). You could set up grunt tasks to compile each of your pages individually so you at least have something to run when you only need to compile a single .scss file.
The best thing to do in your case might be to think outside the box here...what if that partial WASN'T required by a lot of .scss files? What if it was only imported into one main.scss file that compiled into a minified main.css that was included on every page of your project (as the first script on the page, so its styles would get overwritten by any more specific page styles)? We have one script that includes our generic styles for things like buttons, forms, panels...stuff that's on pretty much every page, and isn't too large a burden to load in on pages that don't have a form or a button, especially if minified.
For the cases where modifying a partial only needs to prompt compilation of a few Sass files, we have figured out a solution using the Gruntfile. You can use grunt-contrib-watch to run different tasks depending on where a change was detected. For example, we have the following 2 tasks set up for grunt-contrib-sass:
sass: {
dev_mainstyles: {
options: {
sourcemap: true,
trace: true,
style: 'expanded',
compass: true,
lineNumbers: true
},
files: {
'...css/main.css': '...sass/main.scss',
},
},
dev_customerstyles: {
options: {
sourcemap: true,
trace: true,
style: 'expanded',
compass: true,
lineNumbers: true
},
files: [{
expand: true,
cwd: '.../sass/',
src: ['customers/**/*.scss'],
dest: '.../css/',
ext: '.css'
}],
},
}
I have set up the following tasks for grunt-contrib-watch:
watch: {
sassmain: {
files: ['.../sass/*.scss'],
tasks: ['sass:dev_mainstyles'],
},
sasscustomers: {
files: ['.../sass/customers/**/*.scss'],
tasks: ['sass:dev_customerstyles'],
},
}
By listing both files and directories you can get as specific as you need to and hopefully you'll be able to set up watch tasks that only compile what is needed whenever something changes! Good luck!
We're still looking for suggestions on how to make this whole process even faster, by the way, this is by no means a definitive answer, it's just some tricks we've figured out so far.

Grunt watch livereload not working on MAMP

I am using grunt and I'm trying to get the watch/livereload task to run on my local server (MAMP) but with no success.
I'm calling the task based on HTML5 Boilerplate grunt files (https://github.com/h5bp/html5boilerplate.com/blob/master/Gruntfile.js, https://github.com/h5bp/html5boilerplate.com/blob/master/package.json).
I have also tried implementing Tiny-lr (https://github.com/mklabs/tiny-lr) without success either.
My connect and watch options right now are this
connect: {
options: {
hostname: 'localhost',
livereload: 35729,
port: 8888
},
livereload: {
options: {
base: '../',
open: true
}
},
},
watch: {
files: '<%= settings.dir.src %>/**',
less: {
files: ['src/less/*.less'],
tasks: ['less'],
},
options: {
livereload: '<%= connect.options.livereload %>'
},
scripts: {
files: ['<%= settings.dir.src %>/js/*.js', 'css/**/*.scss' ],
tasks: 'default',
options: {
spawn: false,
}
}
}
And here I declare the dev task:
// development task
grunt.registerTask('dev', [
'connect:livereload',
'watch'
]);
When I run 'grunt dev' my browser opens at http://127.0.0.1:8888/ and displays only this: Cannot GET /
I need my browser to open http://localhost:8888/ctrl/ (ctrl being the name of the folder project on MAMP, could be anything), I thought that changing the "base" option was the way to go but nope, it is not, and I cannot add "/ctrl" to host name either, nor to the port.
Any ideas?
Thank you
Here is a link to my whole code: https://github.com/zolitariuz/ctrl
i think you are misunderstanding 2 tasks in grunt,
the connect task is used to create a http server spawned by node js, so no php nor mysql support, you DON'T want to run you WP site thru that.
the watch task is looking for changes in files on YOUR computer, launching the according task after a file change, then trigger the live reload.
you should remove connect completely after you copied the live reload object in your watch task.
the you should run your local lamp stack for running wp then start the watch task for file changes.
on the wp side you should enqueue the live reload script, or use a browser extension that will inject it for you.

Yeoman: Triggering LiveReload on change of SCSS files

I've got the latest yeoman stack, and I just upgraded generator-webapp to master as per: https://github.com/yeoman/generator-webapp/pull/67 to get livereload working properly.
HTML files and css files seem to be working with livereload just fine, but scss files don't trigger a reload. Here's a snippet of output:
OK
>> File "app/index.html" changed.
Running "watch" task
... Reload app/index.html ...
... Reload app/index.html ...
Completed in 0.005s at Wed Jun 05 2013 22:45:46 GMT+0100 (BST) - Waiting...
OK
>> File "app/styles/main.scss" changed.
Running "compass:server" (compass) task
overwrite .tmp/styles/main.css
Running "watch" task
Completed in 1.101s at Wed Jun 05 2013 22:45:57 GMT+0100 (BST) - Waiting...
The scss file is being watched and compiled, but it looks as though the outputted css in .tmp is being ignored. This is despite the following in the (default) Gruntfile.
livereload: {
options: {
livereload: LIVERELOAD_PORT
},
files: [
'<%= yeoman.app %>/*.html',
'{.tmp,<%= yeoman.app %>}/styles/{,*/}*.css',
'{.tmp,<%= yeoman.app %>}/scripts/{,*/}*.js',
'<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
]
}
I would post this as a bug on github, but it's difficult to know which part of the stack is responsible.
Try setting
watch: {
options: {
nospawn: false
}
}
Let me know if this does the trick!

Resources