Closed Knagis closed 1 year ago
in-memory cache to disk to avoid this
require()
should already have this cache. require()
the module next time took less time (if there is no hacks around require()
).
How do you plan to add better cache?
i want the cache to be persisted between compilation runs. so restarting compilation process would be slightly faster. it can also thus be shared between different processes (like production webpack runs and storybook builds etc.)
const started = Date.now();
let { agents } = require('caniuse-lite')
let dataPrefixes = require('../data/prefixes')
console.log("caniuse require took", (Date.now() - started), "ms");
Running node node_modules\autoprefixer\lib\autoprefixer.js
(node 16.19.0):
caniuse require took 423 ms
caniuse require took 327 ms
caniuse require took 324 ms
caniuse require took 320 ms
caniuse require took 331 ms
caniuse require took 334 ms
caniuse require took 338 ms
Yes, I understand the problem (honestly, it mostly came from ts-node
because it parses all require
files, and Can I Use DB has a big JSONs).
What solution do you suggest?
the times above are plain node, without ts-node.
The let autoprefixerData = { browsers: agents, prefixes: dataPrefixes }
object serialized to JSON takes around 285KB in my case. So I was thinking of writing this to disk (probably, just based on caniuse-lite/package.json version) and reading when available.
First small thing - changing
let { agents } = require('caniuse-lite')
to
let { agents } = require('caniuse-lite/dist/unpacker/agents')
removes the big cost to load whole caniuse-lite for loading just browser stats - this same import is used by browserslist to calculate usage.
So that leaves only the feature require.
So I was thinking of writing this to disk (probably, just based on caniuse-lite/package.json version) and reading when available
You need to think about cache invalidation on caniuse-lite
update. And about working in the environment without fs
(for instance, in the browser).
It could be much more complex, than you think.
let { agents } = require('caniuse-lite/dist/unpacker/agents')
Yes, we can change it. Send PR.
And changing
let unpack = require('caniuse-lite').feature
to
let unpack = require('caniuse-lite/dist/unpacker/feature');
results in total time of 100ms.
So without any caching, these two imports reduce startup time from ~300ms to ~100ms.
PR incoming.
The fix was released in 10.4.14.
On my machine the require("caniuse-lite") can take around 450ms. This is relatively noticeable slowdown every time some compilation is started. This might be more than usual because i have ts-node etc. but overall my setup is rather straight forward webpack+postcss. Building the prefixes list takes another ~50ms.
I am planning to patch autoprefixer to persist the current in-memory cache to disk to avoid this. Would you be willing to consider this as a PR as well? (just so i know if i can cut corners or if i should make things properly, with configuration options etc.)