Beta
×

Welcome to the Slashdot Beta site -- learn more here. Use the link in the footer or click here to return to the Classic version of Slashdot.

Thank you!

Before you choose to head back to the Classic look of the site, we'd appreciate it if you share your thoughts on the Beta; your feedback is what drives our ongoing development.

Beta is different and we value you taking the time to try it out. Please take a look at the changes we've made in Beta and  learn more about it. Thanks for reading, and for making the site better!

Tuning Slashdot, part 1: Relationship CSS

Just Some Guy (3352) writes | more than 6 years ago

User Journal 11

Refactoring relationships

Right now, relationships are embedded into the comments section of story pages with tags like:

<span class="zooicon"><a href="//science.slashdot.org/zoo.pl?op=check&amp;uid=198669"><img src="//images.slashdot.org/fof.gif" alt="Friend of a Friend" title="Friend of a Friend"></a></span>

Refactoring relationships

Right now, relationships are embedded into the comments section of story pages with tags like:

<span class="zooicon"><a href="//science.slashdot.org/zoo.pl?op=check&amp;uid=198669"><img src="//images.slashdot.org/fof.gif" alt="Friend of a Friend" title="Friend of a Friend"></a></span>

This is ugly for a few reasons. First, it's a mess. Second, it means that every visitor has to have their own custom-rendered comments sections so you can't apply aggressive caching to the page-generation code. I would replace this with per-user CSS.

First, create a CSS file for each user like this:

/* Default class */
a.relationship {
background: url(neutral.gif);
width: 12px;
height: 12px;
display: inline-block;
text-decoration: none;
}

/* User-specific values start here: */

/* Friends */
a.user3352,a.user42 { background: url(friend.gif); }

/* Foes */
a.user666 { background: url(foe.gif); }

Next, replace the HTML in the comments section with generic relationship information such as:

<link rel="stylesheet" type="text/css" href="relationships.css">
[...]
<p>by neutral (1234) <a href="bar" class="user1234 relationship">&nbsp;</a> on 2008-01-20</p>
<p>by Just Some Guy (3352) <a href="bar" class="user3352 relationship">&nbsp;</a> on 2008-01-20</p>
<p>by foe (666) <a href="bar" class="user666 relationship">&nbsp;</a> on 2008-01-20</p>

All "a" tags with the "relationship" class get the default CSS values. If there is also a corresponding "user*" selector in the visitor's stylesheet, then the values in that selector override the defaults. For a sad user with no friends, this means that everyone gets the neutral.gif icon. As that user accumulates more specific relationships, those CSS definitions are applied instead.

This benefits Slashdot because suddenly they don't have to generate a brand new comments section for every visitor. The per-user CSS would also be extremely simple to generate. In any case, it would be no more difficult than the current method of embedding all that information directly into the comments section.

Finally, those CSS files could also be cached very easily. Since they would only change whenever a user's relationships are modified, Slashdot would no longer have to query that information every single time it creates a page.

There are two drawbacks to this idea. First, there are no more alt attributes on images, so users don't see a "Friend" popup if they hover over the relationship button. If that's a problem, replace the icons with little smiley or frowny faces as appropriate. Second, it would take slightly more work to support putting users in multiple categories at the same time ("Friend" + "Freak"). The fix is to create a whole set of graphics like "friend_freak.gif" and "foe_friendoffriend.gif" and corresponding CSS classes. There aren't that many categories, though, so it would require only minimal extra work to cover every possible combination.

How 'bout it, Taco - could you use something like that? Less code, less bandwidth, and less processing should be pretty easily reachable goals.

cancel ×

11 comments

Sorry! There are no comments related to the filter you selected.

Devil's Advocate (1)

drachenstern (160456) | more than 6 years ago | (#22085022)

Okay, I'll try the DA approach on this:

How easy would this be to implement considering the website is primarily database driven? I would think that all of that info is tied into the page request (given the tech discussion of October 2007 and given that I haven't had lunch yet, so my brain is a little weak ... damn sugar)

Also, since you are talking about rebuilding the way pages are loaded, would this break functionality with closed discussions, or are those static once they are closed?

What kind of down time would it take to get the new scripts and source-files (.css, etc) in place? Can the changes be made in real-time alongside the current infrastructure?

Would they need to do two re-writes to get rolling on this, one to start using the CSS, and one to start using the new article engine?

Have you written a sample page that allows me to add, move, or remove a friend/foe? I think that would be the best proof of concept, to help that part of the project along.

Those are my $.02. I think it sounds like a great improvement, and agree that it should cut down on a lot of the server needs.

Re:Devil's Advocate (1)

Just Some Guy (3352) | more than 6 years ago | (#22086808)

How easy would this be to implement considering the website is primarily database driven? I would think that all of that info is tied into the page request (given the tech discussion of October 2007 and given that I haven't had lunch yet, so my brain is a little weak ... damn sugar)

Trivially easy. Right now, today, whenever a visitor loads a story, Slash has to build a set of that visitor's relationships. For each comment in the story, it checks to see if the poster has a relationship to the visitor. If they do then it displays the appropriate image. It would almost certainly be much easier to write a script to take that information and write it out as a flat-text file (conveniently formatted as CSS definitions).

Also, since you are talking about rebuilding the way pages are loaded, would this break functionality with closed discussions, or are those static once they are closed?

Actually, I'm not really advocating that (at least not yet). Still, this would help pave the way for a new content engine. As of today, Slash has to generate the comments section every time someone loads a story. Since if you're browing at the same Full/Abbreviated/Hidden levels that I might be, why make Slash do the same work twice when it could just serve us the same cached information? You'd have to embed a little intelligence in the caching layer, but precious little compared to what you'd need to accelerate Slash on today's system.

What kind of down time would it take to get the new scripts and source-files (.css, etc) in place? Can the changes be made in real-time alongside the current infrastructure?

None, and yes. First, write the module that returns the relationships.css file. Remember, 95% percent of it is already written! It just needs to be altered to spit out CSS instead of nested span and img tags. When you're satisfied that it's working OK, change the template of the comments section to print out the new attributes for the CSS tags and skip the span and img tags. When that's tested, remove the relationship code from the comments section. After all that, tune as needed.

Would they need to do two re-writes to get rolling on this, one to start using the CSS, and one to start using the new article engine?

Just one, as per above. It should be very minimal, honestly. None of this requires much new code at all, and a lot of it could probably be achieved just by modifying the comments template.

Have you written a sample page that allows me to add, move, or remove a friend/foe? I think that would be the best proof of concept, to help that part of the project along.

No, because the end user interface wouldn't change at all. It would still look and work exactly the same. The only difference would be a simplified and easier to tweak infrastructure.

The biggest question in my mind would be how best to generate the CSS. Do you cache the CSS for every user in advance? Create it on-the-fly and cache the results? The latter would probably be the easiest and just as quick. Set a lifetime on each file so that you don't get clogged with cached files from people who haven't visited in a year. Delete a cached file whenever someone edits a relationship that affects it. I don't think any part of it would be too challenging.

Re:Devil's Advocate (1)

drachenstern (160456) | more than 6 years ago | (#22087212)

Have you written a sample page that allows me to add, move, or remove a friend/foe? I think that would be the best proof of concept, to help that part of the project along.

No, because the end user interface wouldn't change at all. It would still look and work exactly the same. The only difference would be a simplified and easier to tweak infrastructure.

The biggest question in my mind would be how best to generate the CSS. Do you cache the CSS for every user in advance? Create it on-the-fly and cache the results? The latter would probably be the easiest and just as quick. Set a lifetime on each file so that you don't get clogged with cached files from people who haven't visited in a year. Delete a cached file whenever someone edits a relationship that affects it. I don't think any part of it would be too challenging.

Okay, Guilty. I thought faster than I typed.

My thinking was that this part of the UI might be the more challenging part, and you need a pretty thorough script to manipulate that users lists. The reason why I think it might be difficult to write the script is because you're moving parts of the file around, not necessarily tags within an INI. But then again, I've never tried to write a file parser to move names like what you're describing, so I can't say how difficult it is. The script might be trivially simple. It's just that anytime someone can SAY "trivially move this text from here to here", the operations involved are usually less than trivial.

my point was that the text file manipulation script is most likely to be the most difficult part of the task, if only because it seems to be the most trivial part of the new idea

Overall, I like your answers. It just helps to have a little devil's advocate somewhere in the mix on new ideas, and I was trying to come up with some thought provokers.

Re:Devil's Advocate (1)

Just Some Guy (3352) | more than 6 years ago | (#22088122)

My thinking was that this part of the UI might be the more challenging part, and you need a pretty thorough script to manipulate that users lists. The reason why I think it might be difficult to write the script is because you're moving parts of the file around, not necessarily tags within an INI.

There would be no text file manipulation whatsoever. Right now the page rendering code looks like:

select user's relationships into a hash table
select comments for story
for each comment {
is comment author a friend? print the friend icon.
is comment author a foe? print the foe icon.
is comment author a freak? print the freak icon.
[...]
print the comment
}

The new code would look like:

select comments for story
for each comment {
print the comment
}

and then in an entirely different script to generate the CSS file:

select user's relationships into a hash table
print the default a tag block
print the friends a tag block
print the foes a tag block
print the freaks a tag block

Even without caching, the CSS generator wouldn't take a single cycle more processing time, and probably many fewer. With even the simplest caching, such as putting an imaginary "css.slashdot.org" server behind a reverse Squid proxy, it would talk relatively no processing time at all.

The one and only time any text file would be changed is when the webmaster edited the main template file that's used to render a comment. That would take about 5 minutes to change and test and then would be finished forever.

Re:Devil's Advocate (1)

drachenstern (160456) | more than 6 years ago | (#22088710)

We seem to have gone different ways. I get how the article part is done. I'm talking about when I click the little circle next to your name, and I get three options, one for friend, one for neutral, and one for foe. If I understood your original suggestion (which I probably didn't, seeing as how we've gotten this far) I thought that you intended that the usernames on the individual friend list would be part of the css file.

First, create a CSS file for each user like this:

/* Default class */
a.relationship {
background: url(neutral.gif);
width: 12px;
height: 12px;
display: inline-block;
text-decoration: none;
}

/* User-specific values start here: */

/* Friends */
a.user3352,a.user42 { background: url(friend.gif); }

/* Foes */
a.user666 { background: url(foe.gif); }

For instance drachenstern.css I would want to have something like (based on my real friends/foes list)

/* Friends */
a.Abcd1234,...,a.JustSomeGuy,... { background: url(friend.gif); }

/* Foes */
a.ajs318 { background: url(friend.gif); }

and this whole time, I'm talking about the script to move a.Abcd1234 (or whoever, ignore the name part) from the /* Friends */ to the /* Foes */ section

that's the "trivial" script that I thought you were talking about here:

All "a" tags with the "relationship" class get the default CSS values. If there is also a corresponding "user*" selector in the visitor's stylesheet, then the values in that selector override the defaults. For a sad user with no friends, this means that everyone gets the neutral.gif icon. As that user accumulates more specific relationships, those CSS definitions are applied instead.

I totally get that a css version would be much more server-inexpensive than heavy db lookup and code generation on the fly. In fact, the cacheability of the css on the users computer could reduce some server load that much more, no? The only part I don't immediately see being faster is code for generating friend of friend, but that could be stored on the server and updated "every-so-often", or can eat into those reduced server processing cycles

Re:Devil's Advocate (1)

Just Some Guy (3352) | more than 6 years ago | (#22093672)

and this whole time, I'm talking about the script to move a.Abcd1234 (or whoever, ignore the name part) from the /* Friends */ to the /* Foes */ section

Well, we're on the same page up to that point. The difference is that in my plan, the CSS file would be the output of a program. It would never be edited in any way, just overwritten with new data whenever necessary.

I totally get that a css version would be much more server-inexpensive than heavy db lookup and code generation on the fly. In fact, the cacheability of the css on the users computer could reduce some server load that much more, no?

That's exactly correct. Basically, the CSS would be fetched from the client's browser cache most of the time.

The only part I don't immediately see being faster is code for generating friend of friend, but that could be stored on the server and updated "every-so-often", or can eat into those reduced server processing cycles

But the problem is that right now "friend of friend" is generated for you every single time you load a story. It doesn't matter if that information is identical to when you last read a story. Slash still has to make that graph so that it can embed the data inside the story's comments. The absolute worst case scenario with my plan is where there is no caching whatsoever and the user fetches a dynamically generated CSS file each time they load the story. In that case, Slashdot's servers would have to do the exact same amount of work that they already do with the current system. If any caching whatsoever is involved, either on the client's machine or on Slashdot's filesystem, there would be much less processing involved.

Re:Devil's Advocate (1)

drachenstern (160456) | more than 6 years ago | (#22097240)

and this whole time, I'm talking about the script to move a.Abcd1234 (or whoever, ignore the name part) from the /* Friends */ to the /* Foes */ section

Well, we're on the same page up to that point. The difference is that in my plan, the CSS file would be the output of a program. It would never be edited in any way, just overwritten with new data whenever necessary.

And now the breakdown appears. Okay, clarified!

I just figure a script would be even better than generating it on the fly, but since you would only generate when you saved the configuration, it could actually lead to a better page, in a way, or at least a different version of the page with columns, or something.

see, now I feel a marginal bit better that I helped contribute to a potential resource saving upgrade for slash, by helping to make sure certain ideas were fleshed out, even though I realize that cmdrTaco doesn't always read through all the things we want him to, nor do my comments necessarily help others to have had more clarification, but if it's clearer to me, then it's probably clearer to someone else too.

so when's the Part 2 coming?



Re:Devil's Advocate (1)

Just Some Guy (3352) | more than 6 years ago | (#22097892)

so when's the Part 2 coming?

I am notoriously bad at following through on these things. :-D

Re:Devil's Advocate (1)

drachenstern (160456) | more than 6 years ago | (#22099704)

Yeah, that happens to me A LOT

My family has gone to the trouble of finding a shirt that says:

The top ten reasons I procrastinate:
  1. .
It's quite funny for me, 'cos it is me...

I think this is a pretty bad idea. (1)

bcat24 (914105) | more than 6 years ago | (#22104952)

I like your thoughts on saving bandwidth, but this isn't the way to do it. Whatever happened to accessibility? Moving something that is clearly page content (like user relationships) from the content layer (HTML) to the presentation layer (CSS) is not a good thing.

Re:I think this is a pretty bad idea. (1)

Just Some Guy (3352) | more than 6 years ago | (#22106158)

Good point, although I would still think the relationship information so relatively unimportant compared to other content that it wouldn't be missed. However, now that you bring it up, the same approach would work almost as well if it generated DOM-modifying JavaScript so that the client applied the relationship information instead of the server. Would that work OK with screen readers and such?

Check for New Comments
Slashdot Login

Need an Account?

Forgot your password?

Submission Text Formatting Tips

We support a small subset of HTML, namely these tags:

  • b
  • i
  • p
  • br
  • a
  • ol
  • ul
  • li
  • dl
  • dt
  • dd
  • em
  • strong
  • tt
  • blockquote
  • div
  • quote
  • ecode

"ecode" can be used for code snippets, for example:

<ecode>    while(1) { do_something(); } </ecode>