I'm working on tomorrow's kind of big thing, so will take it easy today, with a stroll down memory lane.
I was clearing up my space at home few days ago and came across this oldish notepad. In there (among the usual amount of lists of todos and ideas in the spirit of i-wanna-do-this-tool/site/experiment!) I found these early sketches of what has since become YSlow 2.0. These are all still pretty relevant, so why not take a minute to review them and get acquainted with the YSlow internals.
Back at the time Steve Souders and I had just released YSlow 0.9 and Steve had moved to Google. It was the right time to have a quick bugfix-or-two release of YSlow 1.0 and in parallel get cranking on a complete YSlow 2.0 rewrite.
The motivation behind the total rewrite was (aside from the usual "I didn't make this mess" ego-driven desire to start fresh and do a better job the second time around) was that we were getting a lot of "meh, these are Yahoo's problems/rules, not yours". For example a normal mere mortal blog with no CDN budget should still try to get an A in most other checks. Another, somewhat forward thinking, as opposed to reactive reason was that I was a big fan of letting others contribute rules and checks of their own. The idea was to make YSlow your own tool, not only Yahoo's. For example if you want to set a rule that there should be no more than 5 images on a page, you should be able to codify this into a rule. And share the rule with the rest of team or the world. (Here's an example). Another thing was also to decouple the tool from Firebug. Make it work without Firebug and even without Firefox. Go back to having a bookmarklet version (Steve's original very first version) and versions for other browsers. (Thanks to Marcel Duran this is also becoming a reality now)
So the new architecture (a big name for a bunch of objects) was conceived on these sketches while en route a red-eye flight to Bulgaria. My little kids were asleep taking over my seat as well, so here I was standing up in the aisle on the plane or sitting on the seat's handrail, scribbling these notes.
The main idea was divide and conquer. Split this monolithic piece of code into smaller components.
When you run YSlow, it starts by "peeling off" the page, extracting all possible information. Hence the
Peeler has methods such as
getDocuments() (as in
document + any frames). This can work most anywhere (bookmarklet too). Then if YSlow is running inside Firebug and has access to Net Panel (or any other browser or environment that lets you access stuff happening on the network, not only DOM crawling), it can also find things such as XHR requests or image beacons, which are not part of the DOM, using a
NetMonitor listener object of some sorts.
Peeler finds, it sticks into a
ComponentSet which is just an array of components along with some convenience methods such as
Moving on, the
Component objects which have all the data, like headers, type, content, URL, the whole thing.
K, now we have a bunch of components waiting and willing to be inspected. To make this inspection as lego-like as possible, there's no big-ass inspector, but there are many little
Rule objects. Each
Rule object has a bunch of properties like
URL with more info, etc, but the main thing is - it needs to implement a
lint() method. The
lint() method takes a reference to the
ComponentSet and then returns a
Result objects are fairly simple - they have a grade/score, message and optionally a list of offending components (e.g. images without
Expires header). A bunch of result objects make a
ResultSet which has methods to get the final total score.
A bunch of
Rule objects go into a
RuleSet. The idea is to mash those up as you wish. So a
Rule object is for example "Use CDN". (it's also configurable, e.g. how many score points to take away for each offender). Also within a
RuleSet you can define what is the relative weight of each
Rule. E.g. is F on "Expires" rule as bad as F on "CSS expressions". You can create your own
RuleSets (e.g. "Small blog") including an configuring any of the existing rules you like and also add more custom
Rules. It's one big happy pool of Rules to pick from and configure. In fact YSlow 2.0 shipped with three rulesets - the new one with more rules, the old yslow1 and a "small site or blog"
At the end there is one central
lint() method which takes a
RuleSet, loops over the
Rules in it, calls each
lint() and collects the results into a
From there it's a question of rendering the
ResultSet, grades, offenders, etc. Additionally there are tools that can run on the
ComponentSet (e.g. JSLint) and stats. In addition to the YSlow UI, you should be able to render these results in any way you like, including exporting a JSON or whathaveyou.
I may have missed some details but that's about all there is to the core of YSlow 2.0
Here's also a presentation that talks about these things and offers some diagrams that hopefully clarify even further
Thanks for reading!
That was it for today, only 4 days to go to Velocity. Hope you learned something you can use and you're ready to start coding your own rules and create rulesets to customize what YSlow can do for you.