To participate you must create an account on apostrophenow.org. If you have already done so, click Login.

Ticket #1089 (accepted enhancement)

Opened 11 months ago

Last modified 11 months ago

Unique asset group names & far future expires headers: easy performance gain

Reported by: jeremy Owned by: tboutell
Priority: minor Milestone: 1.5.2
Component: apostrophePlugin Version: 1.5
Keywords: Cc:
Symfony version: 1.4

Description

When aHelper combines asset groups, it generates the group file name solely on the names of the included files. As a result, the group name is not a unique with respects to the content of the individual files. In turn, this prevents setting a far future expires header, a Yahoo! best practice for performance  (link).

An easy fix for this is to append the filemtime to the end of the compiled file name, which would make the hash of the group file name unique with respect to content.

Attachments

example.diff Download (1.1 KB) - added by jeremy 11 months ago.

Change History

Changed 11 months ago by tboutell

  • status changed from new to accepted

We're thinking about it. It's not *quite* that easy (: The site then has to go looking for that file without prior knowledge of what the newest mtime is, which implies overhead (glob calls). The right fix isprobably an asset revision number or guid in a PHP file that's updated by symfony cc. I wish I could figure out how to shoehorn this into the configuration cascade in such a way that it's compiled in with all the other settings and thus effectively "free."

Changed 11 months ago by jeremy

I was under the mistaken impression that aHelper or aAssets was already calling filemtime every iteration and I see now that it is not.

If filemtime is too much of a performance hit to on every file, would one file be okay? If so, here's a solution:

Every time an asset is compiled, touch a key/version file (e.g. <root>/asset-cache/asset-version). Then append the filemtime of the key/version file to the group name. A similar version of this could be done via APC, falling back to the file version if APC isn't present.

Changed 11 months ago by jeremy

Happy to submit a patch if you like this approach.

Changed 11 months ago by tboutell

It's viable, but I'm concerned that we have to read "yet one more file" on every page view to determine what the current version is. I held off on doing it this way because I was hoping to find a solution that would not require that. I'm beginning to think we should be using sfCache, since that gives you the option of sfAPCCache if performance is an issue.

Changed 11 months ago by jeremy

I think avoiding this approach for performance reasons would be a mistake.

filemtime is extremely fast, as it's equivalent to calling stat on a file (which is already happening hundreds - thousands? - of times on every execution even with a standard APC setup). filemtime is significantly faster than reading a file.

However, I think any debate here is largely irrelevant. The performance of either option would be more than adequate.

Changed 11 months ago by tboutell

I'm not talking about the performance of *building* the files. I'm talking about the performance of *reusing* the files on every subsequent page load. When we read one more file on every page load (to find out what the current asset revision # is), we add to the cost of a typical pageview. It's worthwhile to think about ways to avoid that. Everying in app.yml, settings.yml, etc. gets compiled into a PHP file that is already being read. Can we get stuff into that, or is it just not practical in Symfony 1?

Changed 11 months ago by jeremy

Changed 11 months ago by jeremy

I've attached a patch so you can see a simple version of what I'm talking about.

The overhead of this solution is a single filemtime call, which is not equivalent to reading a file; it is significantly faster (much less than 1 ms). This exact call is easily happening hundreds of times on every execution already.

Note: See TracTickets for help on using tickets.