Changelog: Feed Improvements
Tags: changelog, meta
Published: 2020-03-05 17:09:42

We recently completed our first [six week cycle](https://basecamp.com/shapeup/2.2-chapter-08#six-week-cycles) here at DEV, and one change I'm particular excited about is making it easier to test and change the way the home page article feed is generated. 

First, some background: at the end of January [Justin](https://dev.to/piannaf) wrote a [fantastic deep dive](https://dev.to/piannaf/the-dev-to-feed-algorithm-5em5) on how the home page article feed is generated. Improving the relevancy of the feed is a big priority for us, but before we could even attempt that there was some housekeeping work to be done. [Nick](https://dev.to/nickytonline) spent a majority of his time this cycle implementing [Preact](https://preactjs.com) components on the homepage and getting the feed to a place were we (and you!) can make changes to it more easily.

## Previously On The Feed

In the past logic to construct the feed existed in both the Rails backend as well as client side JavaScript. [`StoriesController`](https://github.com/thepracticaldev/dev.to/blob/master/app/controllers/stories_controller.rb) made an initial query to get some [`Article`](https://github.com/thepracticaldev/dev.to/blob/master/app/models/article.rb) objects and ordered them, and [`initializeFetchFollowedArticles.js.erb`](https://github.com/thepracticaldev/dev.to/blob/master/app/assets/javascripts/initializers/initializeFetchFollowedArticles.js.erb) did some additional ranking and scoring on that same set of articles. As a result: if one wanted to change the feed to prioritize posts with emojis in their title, changes would need to be made in both `StoriesController` as well as `initializeFetchFollowedArticles.js.erb`. Depending on which version of the home page feed a user was looking at (the plain feed versus a time based feed, and if the user is logged in or not), changes might need to be made in additional JavaScript files. 

Definitely not ideal for rapid change and experimentation: it's no wonder the home page feed composition has been changed infrequently, and only in small amounts.

## Getting it Together

To help make it easier to change how the feed is constructed, we've started to consolidate feed generation logic to a service class: [`Articles::Feed`](https://github.com/thepracticaldev/dev.to/blob/master/app/services/articles/feed.rb). Both the legacy `StoriesController` and a new controller ([`Stories::FeedController`](https://github.com/thepracticaldev/dev.to/blob/master/app/controllers/stories/feeds_controller.rb)) consume the output of this service when rendering the home page article feed. We've usage of the ranking that happens in `initializeFetchFollowedArticles.js.erb` from the main home page article feeds for logged in users (the logged out user path and non-preactified feed components still use it. Baby steps!)

TL;DR: if you want to experiment with composition of the home page feed, `Articles::Feed` is your one stop shop going forward!

## Evaluating Feed Performance

It's not enough to simply change how the feed is generated: the goal is to produce a feed that is more relevant and engaging for users. [Ben](https://dev.to/ben) has implemented Andrew Kane's excellent [Field Test](https://github.com/ankane/field_test) gem for A/B Testing. This bit of code in `Stories::FeedController` is where a test is selected:

```ruby
  def ab_test_user_signed_in_feed(feed)
    test_variant = field_test(:user_home_feed, participant: current_user)
    case test_variant
    when "base"
      feed.default_home_feed(user_signed_in: true)
    when "more_random"
      feed.default_home_feed_with_more_randomness
    when "mix_base_more_random"
      feed.mix_default_and_more_random
    when "more_tag_weight"
      feed.more_tag_weight
    when "more_tag_weight_more_random"
      feed.more_tag_weight_more_random
    else
      feed.default_home_feed(user_signed_in: true)
    end
  end
```

Each "experiment" gets it's own method in the `Articles::Feed` service, and users are routed based on the percentage values in [`field_test.yml`](https://github.com/thepracticaldev/dev.to/blob/master/config/field_test.yml). Even better: Field Test tracks which users are getting which home page version, and how often those users are visiting the page and commenting on articles. We're using this information to evaluate which variables of the home page are resonating with users. **Always** bring data to the conversation!

## Up Next

In the coming weeks, we'll monitor and continue to adjust the home page feed algorithm. I'd also like to pull even more instances of feed generation into the `Articles::Feed` service: feel free to pitch in if you're at all interested!

Happy Coding! ❤️