Proposal: frint-experiments for A/B testing and more...
See original GitHub issue(Intended to be done in a separate repositiory)
What
Guidelines and API spec on how we can run experiments in the UI with FrintJS.
Extracted our usage out of the internal PoC we did recently.
/cc @AlexDudar, @juliamaksimchik, @discosultan, @viacheslaff
Proposed packages
frint-experiments
Will export:
ExperimentsService
- will be set as a provider in Apps
- will provide access to the collection
ExperimentsCollection
: will contain the experiments dataExperiment
: Individual experiment item as a modelcreateExperiments
: Generates a new configuredExperimentsService
class
Example usage:
import { createApp } from 'frint';
import { createExperiments } from 'frint-experiments';
const App = createApp({
name: 'MyApp',
providers: [
{
name: 'experiments',
useFactory() {
const ExperimentsService = createExperiments({
activate(model, attributes = {}) {
// implement activation logic
},
track(model, eventTags = {}) {
// implement tracking logic
},
});
return new ExperimentsService([]); // feed it with Experiments collection
}
}
]
});
The model can have this schema:
// Experiment.js
import { createModel, Types } from 'frint-data';
export default createModel({
schema: {
name: Types.string,
variant: Types.string,
},
});
The service:
class ExperimentsService {
constructor(experimentsArray) {
this.experiments = new ExperimentsCollection(experimentsArray);
}
findByName(name) {
return Experiment;
}
findByName$(name) {
return Observable;
}
activate(model, attributes = {}) {
}
track(model, eventTags = {}) {
}
}
frint-experiments-react
This package will be exporting React components, for implementing our experiments at UI-level.
import React from 'react';
import { Experiment, Variant } from 'frint-experiments-react';
export default function MyComponent(props) {
return (
<div>
<Experiment name="my-experiment-name">
<Variant when="b" render={() => 'foo'} />
<Variant when="c" render={() => 'bar'} />
<Variant render={() => 'default'} />
</Experiment>
</div>
);
}
Experiment
component will receive either a name
(String
) or model
(Experiment
) as prop.
Benefits
- Declarative experiments
- Always defined at code-level
- No external manipulation with JS code
- Can go for aggressive code-splitting at Component-level, so that users only download the code they need for their own experiments only
Issue Analytics
- State:
- Created 6 years ago
- Reactions:5
- Comments:8 (8 by maintainers)
Top Results From Across the Web
What is A/B Testing? A Practical Guide With Examples | VWO
A/B testing, also known as split testing, refers to a randomized experimentation process wherein two or more versions of a variable (web page,...
Read more >How to Do A/B Testing: 15 Steps for the Perfect Split Test
A/B testing, also known as split testing, is a marketing experiment wherein you split your audience to test a number of variations of...
Read more >71 A/B testing ideas - Optimizely
Here are a few tests you can perform on a split testing tool to increase likes, retweets, and +1s on your content: Change...
Read more >Here Are 10 Fascinating A/B Testing Examples That Will Blow ...
We found 10 AB testing examples that prove user testing is super important in getting conversions for your growing business. These case studies...
Read more >The Amazon A/B Testing Guide: Examples and Best Practices
A/B testing allows you to compare two different versions of your brand's listing content to find which one performs better. Then you can...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
One small addition. When talking of A/B testing, as far as I know, variant A represents what we already have. So not using
<Variant when="a" render={() => 'foo'} />
will make more sense:Then from
b
on, more variants can be added if needed (c
,d
, etc.)Thanks for your questions, @asci! I am responding to each one below:
Yes. In FrintJS, rendering is an optional thing to do. You first define Apps, that can later be optionally rendered on demand.
The instance of
ExperimentsService
class will be set as a provider in a FrintJS App, which means you can access it, along with the Collection/Models by doing:Could you please give me an example scenario? Would help me understand and answer better.
If using CSS Modules, why not just render different Components that can have their own variations in styling?
Activation/Tracking would require more thoughts. In this proposal, I am limiting the activation/tracking part by defining them in the
ExperimentsService
interface only.Based on a particular application’s requirements in a given environment (client OR server), we can always decide what to do with the incoming experiment Model.
FrintJS Apps have Providers, and when the Apps are rendered with
frint-react
, the App instance is made available in the React’s context.The higher-order component then deals with React’s context API and gives us access to the
app
instance:If we really want to enable developers to write less code, we can additionally support a
name
prop in the<Experiment>
Component:The
Experiment
component’s behaviour would then be:model
prop is available, use that Experiment modelname
prop is available, get the model from ExperimentService, and then use that