LoginSignup
19
10

More than 5 years have passed since last update.

Reactベースになったmobile.twitter.comのABテスト周りを探る

Last updated at Posted at 2017-03-28

※ 2017/02/24のgistメモより

調査対象

Twitter(モバイルサイト) - https://mobile.twitter.com

動機

最近、サーバーサイドのフィーチャートグルで遊んでて、その一機能としてABテストがあるんだけど、React + Reduxのフロント側はどんなやり方がベターかと調べてみてた。
(フィーチャートグル機能を提供するJavaライブラリFF4Jへ加えた最近の修正)

↓ これを見てABテストはどうしてるのか作りが気になったのでコードを読んで見た。
TwitterによるReactベースのモバイルWebスタックはネイティブのパフォーマンスに匹敵する
https://www.infoq.com/jp/news/2017/02/twitter-react-mobile-stack

React, Expressな作り。

analytics.jsが使われてるけど、ウェブテスト(ABテスト)は使ってないと思われる。

気になったけど謎が残る

ABテスト周りを探してたら EXPERIMENT_OVERRIDE_COOKIE: "ab_decider", という記述があった。
調査してみたところ、Matt Knox氏のチームで作ったFeature Toggleライブラリ AB_decider が使われてた?昔?

Matt Knox氏:

I was the tech lead for retweet, which required the first significant change to the backend of the twitter home timeline in years.  
I also wrote twitter's dynamic feature-switching library (decider) and its AB-testing framework (AB_decider).  
I worked on the growth team, delivering millions of incremental active users.

コード読んでわかったこと

Featureをごにょごにょ

getFeatureSwitch で検索するとスイッチ可能と思われるフィーチャーが多く見つかって面白い。

Featureたち

  • responsive_web_external_referer_scribing_enabled
  • responsive_web_push_notifications_enabled
  • responsive_web_mute_keywords_enabled
  • responsive_web_mute_keywords_v2_enabled
  • ...

ABテスト対象はxxxxx_5741みたいにナンバリングされてるみたい。
例:responsive_web_modern_search_navigation_5741

        isExperimentKey: function(e) {
            return 0 === e.search(/^.+_[\d]{4,5}$/)
        },

こんな感じでAB判定して

, function(e, t) {
    "use strict";
    Object.defineProperty(t, "__esModule", {
        value: !0
    });
    t.shouldUseModernSearchNavigation = function(e) {
        return e.hasValue("responsive_web_modern_search_navigation_5741", "modern_search_navigation")
    }
}

react-abと同じように、こんな感じにレンダリングを切り替えてる。

OptimizelyみたいなサービスのVisual Editorは使えないから、やはりエンジニアが各パターンを実装する。

[{
            key: "render",
            value: function() {
                var e = this.props
                  , t = e.focusSearch
                  , n = e.forceShow
                  , r = e.location;
                return this._shouldUseModernSearchNavigation || n ? O.default.createElement(g.Link, {
                    "aria-label": S,
                    className: A.default.root,
                    to: {
                        pathname: "/search",
                        state: {
                            previousLocation: r,
                            searchFocused: t
                        }
                    }
                }, O.default.createElement(v.default, {
                    className: A.default.icon
                })) : null
            }
        }]

送ってるログ

ログはこんなのを送ってるっぽい。とにかくイベントを送りまくってる。
scribeExperimentImpression = function() {} の中で。

"action": "experiment" が含まれるのはネーミング的にABテストしてるやつじゃなかろうか?

Request URL:https://api.twitter.com/1.1/jot/client_event.json

log:[{
  "_category_": "client_event",
  "event_namespace": {
    "client": "m5",
    "page": "ddg",
    "section": "responsive_web_amp_links_5811",
    "action": "experiment"
  },
  "format_version": 2,
  "triggered_on": 1487859936366,
  "bucket": "amp_enabled",
  "version": 4,
  "experiment_key": "responsive_web_amp_links_5811"
}]

参考情報

19
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
10