HomePhabricator

Improved caching for LESS file compilation

Authored by ori.

Description

Improved caching for LESS file compilation

Caching the output of a LESS compiler is tricky, because a LESS file may
include additional LESS files via @imports, in which case the cache needs
to vary as the contents of those files vary (and not just the contents of
the primary LESS file).

To solve this, we first introduce a utility class, FileContentsHasher. This
class is essentially a smart version of md5_file() -- given one or more file
names, it computes a hash digest of their contents. It tries to avoid
re-reading files by caching the hash digest in APC and re-using it as long as
the files' mtimes have not changed. This is the same approach I used in
I5ceb8537c.

Next, we use this class in ResourceLoaderFileModule in the following way:
whenever we compile a LESS file, we cache the result as an associative array
with the following keys:

  • files : the list of files whose contents influenced the compiled CSS.
  • hash : a hash digest of the combined contents of those files.
  • css : the CSS output of the compiler itself.

Before using a cached value, we verify that it is still current by asking
FileContentHasher for a hash of the combined contents of all referenced files,
and we compare that against the value of the hash key of the cached entry.

Bug: T112035
Change-Id: I1ff61153ddb95ed17e543bd4af7dd13fa3352861