Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic "plugin" options #316

Merged
merged 4 commits into from
Sep 30, 2016
Merged

Basic "plugin" options #316

merged 4 commits into from
Sep 30, 2016

Conversation

nitriques
Copy link
Contributor

When usign the api, it is sometime necessary to act on the ast object
between csso operations. Instead of having to deal with options and calls to
parse and compress, this change makes it easy to edit the ast object
after csso's parse (afterParse) and compress (afterCompress) operation.

This is especially good for task runner, which can accept those
parameters to be able to speed task execution.


The new for a plugin came in view when I was copy/pasting code from csso or grunt-csso into my grunt task.
This is the experiment I've made: https://gist.github.com/nitriques/9d3b05c530a54c3a885c6bf41b46dbae

It's a re-implementation of purifycss but using async streams and csso instead of sync reads and rework. As per my tests (I've tested it on 4 productions sites) it's 45 times faster. Purify css yields saving of ~5%, while my grunt task saves more that 45% using the same config. Those are big wins.

I can live with the current experiment I've made, but feel like it would live better as a csso plugin, hence the PR.


If you want, I can create the release for you. All tests (both old and new) are passing. I would also happy to send a PR to the grunt-csso project too.

When usign the api, it is sometime necessary to act on the ast object
between csso operations. Instead of having to deal with options and calls to
parse and compress, this change makes it easy to edit the ast object
after csso's parse (afterParse) and compress (afterCompress) operation.

This is especially good for task runner, which can accept those
parameters to be able to speed task execution.
@coveralls
Copy link

Coverage Status

Coverage increased (+0.008%) to 98.258% when pulling 3eebcc1 on DeuxHuitHuit:plugins into 62bf720 on css:master.

1 similar comment
@coveralls
Copy link

coveralls commented Sep 29, 2016

Coverage Status

Coverage increased (+0.008%) to 98.258% when pulling 3eebcc1 on DeuxHuitHuit:plugins into 62bf720 on css:master.

@lahmatiy
Copy link
Member

Thank you for your contribution!
I thought about the plugins system. This may allow further optimizations between steps. But it also may cause to less stability or performance penalty. Since now we are guaranteed to know the state of AST at each step but plugins can change it unpredictably.
Your sugestion is pretty much simple. But solves just few use cases. I'm not sure we should implement it that way. But I have no strong position here and need some time to make a decision.

@@ -60,6 +60,18 @@ function buildCompressOptions(options) {
return options;
}

function runPlugins(ast, options, plugin) {
var plugins = [];
if (typeof options[plugin] === 'object' && options[plugin].length) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (Array.isArray(options[plugin])) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh. Yeah, old habits are tough to lose..

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 69256e2

// after parse plugins
if (options.afterParse) {
debugOutput('afterParse', options, Date.now(),
runPlugins(ast, options, 'afterParse')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to pass options.afterParse instead of property name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hum indeed we could. I'll rewrite it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 1174a7e

@@ -75,11 +87,25 @@ function minify(context, source, options) {
})
);

// after parse plugins
if (options.afterParse) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think beforeCompress is much better name

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed.

Copy link
Contributor Author

@nitriques nitriques Sep 30, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 87f1413

@nitriques
Copy link
Contributor Author

But it also may cause to less stability or performance penalty. Since now we are guaranteed to know the state of AST at each step but plugins can change it unpredictably.

Understood. Maybe we could add a warning in the docs ? Is there a way to validate the AST after each plugin call ?

But solves just few use cases.

Which other case do you have in mind ?

@coveralls
Copy link

Coverage Status

Coverage increased (+0.008%) to 98.258% when pulling 1174a7e on DeuxHuitHuit:plugins into 62bf720 on css:master.

1 similar comment
@coveralls
Copy link

coveralls commented Sep 30, 2016

Coverage Status

Coverage increased (+0.008%) to 98.258% when pulling 1174a7e on DeuxHuitHuit:plugins into 62bf720 on css:master.

@nitriques
Copy link
Contributor Author

But it also may cause to less stability or performance penalty.

I've thought about it and I can't see how to simple if clause can slow things down. Adding plugins into a system always has a tradeoff, but current usage would not notice it. But I am available to talk about other options, like doing this change directly in grunt-csso, where it should only stop using minify and issue manual parse and compress operation. Thanks for this amazing little piece of code btw. ❤️ the List object.

@nitriques
Copy link
Contributor Author

And I see this feature primarily used by runners... anything more complex would directly call parse and compress.

@lahmatiy
Copy link
Member

Maybe we could add a warning in the docs ?

I thought about it. But I checked source and looks like adding beforeCompress is not so dangerous (I thought some things are not performing).

Which other case do you have in mind ?

Well some things may needs to be done after clean or compress steps, e.g. normalization, renaming and so on.

I've thought about it and I can't see how to simple if clause can slow things down.

Not directly but via adding more checking before or during step performing.

❤️ the List object.

It was desinged to avoid using arrays and better performance (see details). Parser and related things including List are moving to separate project - csstree. When csstree stabilizes csso will migrate on it.

@lahmatiy lahmatiy merged commit c382cf5 into css:master Sep 30, 2016
@nitriques
Copy link
Contributor Author

This is great thanks! Any ETA about publishing a new version on npm ?
Awesome slides BTW, read it all ;)

@lahmatiy
Copy link
Member

lahmatiy commented Oct 3, 2016

I'm not sure this changes enough for release. I'll see what we can add and probably publish new version this week.

@nitriques
Copy link
Contributor Author

Ok. Let's wait until I've tested a complete integration then. Working on the grunt-csso PR anyhow. Thanks again.

nitriques added a commit to DeuxHuitHuit/grunt-csso that referenced this pull request Oct 5, 2016
CSSO now supports callbacks to be able to poke with the AST before and
afer compression. This allows developers to add more optimization on the
AST before the file is written while avoiding to parse the css from
disk.

See css/csso#316 for details
@lahmatiy
Copy link
Member

lahmatiy commented Oct 5, 2016

Keep in mind AST format will change soon. When format will be stabilized in csstree and csso migrates on it. Current work on migration in csstree branch.

@nitriques
Copy link
Contributor Author

Perfect, thanks.

Should I send a new PR on the csstree branch ?

@lahmatiy
Copy link
Member

lahmatiy commented Oct 6, 2016

Nope, I've already merge master to this branch.

@nitriques
Copy link
Contributor Author

👍

@nitriques
Copy link
Contributor Author

Well, I would finally need a release in order to be able to ship a passing test suite on the grunt plugin. If you could do it when you have a chance, that would be appreciated. Thanks :)

@lahmatiy
Copy link
Member

Sorry for the wait. Published as 2.3.0

@nitriques
Copy link
Contributor Author

No problems. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants