JavaScript(浏览器)SDK 快速入门
JavaScript(浏览器)SDK 快速入门
欢迎阅读云眼灰度发布(特性标帜)AB实验 JavaScript(浏览器)SDK 的快速入门指南。
按照本指南中的步骤创建灰度发布(特性标帜)、推出标帜传递,并使用简单的命令行应用程序运行 A/B 测试。
第一部分:创建示例应用
1. 获取免费帐户
需要一个 云眼 帐户才能遵循本指南。如果没有帐户,可以注册一个免费帐户。如果已有帐户,请导航到启用了标帜的项目。
2. 获取开发工具包密钥
要在云眼项目中查找开发工具包密钥,请执行以下操作:
- 转到“设置”>“主环境”。
- 复制并保存主环境的 SDK 密钥。
📘 注意
每个环境都有自己的开发工具包密钥。
3. 复制示例代码
要快速试用 SDK,请执行以下操作:
- 优化安装。有以下几种选择:
无需安装即可运行
本地运行
如果要在不在本地安装 SDK 的情况下在演示环境(例如 CodePen)中运行,请使用以下 HTML 脚本标记示例。
如果要使用 Node(生产中的最佳实践)运行,请使用以下 NPM 示例。
<html>
<head>
<!--install Eyeofcloud-->
<script src="https://unpkg.com/@eyeofcloud/eyeofcloud-sdk/dist/eyeofcloud.browser.umd.min.js"></script>
</head>
<body>
</body>
</html>
# From an empty project directory, create an optydemo.js file, and run the terminal command below to install Eyeofcloud Full Stack:
npm install --save @eyeofcloud/eyeofcloud-sdk
# From your project directory, run the terminal command below to install Eyeofcloud Full Stack:
yarn add @eyeofcloud/eyeofcloud-sdk
- 在 CodePen 中创建空白项目或创建名为 local 的空白文件。
eyeofcloud-js-quickstart.html
- 将以下代码示例复制到在上一步中创建的文件中。
- 替换为在上一步中找到的 SDK 密钥。
<Your_SDK_Key>
<!DOCTYPE html>
<html>
<head>
<title>Quickstart Guide</title>
<script src="https://unpkg.com/@eyeofcloud/eyeofcloud-sdk/dist/eyeofcloud.browser.umd.min.js"></script>
</head>
<body>
<pre>Welcome to our Quickstart Guide!</pre>
<pre id="errors"></pre>
<pre id="experiences"></pre>
<pre id="result"></pre>
<script>
var eyeofcloudClient = window.eyeofcloudSdk.createInstance({
sdkKey: '<YOUR_SDK_KEY>'
});
eyeofcloudClient.onReady().then(() => {
var errors = document.getElementById('errors');
if (!eyeofcloudClient.isValidInstance()) {
errors.innerText = 'Eyeofcloud client invalid. Verify in Settings>Environments that you used the primary environment\'s SDK key';
return;
}
var experiences = document.getElementById('experiences');
let hasOnFlags = false;
for (let i = 0; i < 10; i++) {
// to get rapid demo results, generate random users. Each user always sees the same variation unless you reconfigure the flag rule.
let userId = (Math.floor(Math.random() * (10000 - 1000) + 1000)).toString();
// Create hardcoded user & bucket user into a flag variation
let user = eyeofcloudClient.createUserContext(userId);
// "product_sort" corresponds to a flag key in your Eyeofcloud project
let decision = user.decide('product_sort');
let variationKey = decision.variationKey;
// did decision fail with a critical error?
if (variationKey === null) {
errors.innerText += `\n\ndecision error: ${decision['reasons']}`;
}
// get a dynamic configuration variable
// "sort_method" corresponds to a variable key in your Eyeofcloud project
let sortMethod = decision.variables['sort_method'];
if (decision.enabled) {
hasOnFlags = true;
}
// Mock what the users sees with print statements (in production, use flag variables to implement feature configuration)
// always returns false until you enable a flag rule in your Eyeofcloud project
experiences.innerText += `\n\nFlag ${decision.enabled ? 'on' : 'off'}. User number ${user.getUserId()} saw flag variation: ${variationKey} and got products sorted by: ${sortMethod} config variable as part of flag rule: ${decision.ruleKey}`;
}
var result = document.getElementById('result');
if (!hasOnFlags) {
result.innerText = "\n\nFlag was off for everyone. Some reasons could include:" +
"\n1. Your sample size of visitors was too small. Rerun, or increase the iterations in the FOR loop" +
"\n2. By default you have 2 keys for 2 project environments (dev/prod). Verify in Settings>Environments that you used the right key for the environment where your flag is toggled to ON." +
"\n\nCheck your key at https://app.eyeofcloud.com/v2/projects/" + eyeofcloudClient.projectConfigManager.getConfig().projectId + "/settings/implementation";
};
});
</script>
</body>
</html>
const eyeofcloudSdk = require('@eyeofcloud/eyeofcloud-sdk');
const eyeofcloudClient = eyeofcloudSdk.createInstance({
sdkKey: '<YOUR_SDK_KEY>'
});
eyeofcloudClient.onReady().then(() => {
console.log('***eyeofcloudClient is valid instance 2****', eyeofcloudClient.isValidInstance());
if (!eyeofcloudClient.isValidInstance()) {
console.log('Eyeofcloud client invalid. Verify in Settings>Environments that you used the primary environment\'s SDK key');
return;
}
let hasOnFlags = false;
for (let i = 0; i < 10; i++) {
// to get rapid demo results, generate random users. Each user always sees the same variation unless you reconfigure the flag rule.
let userId = (Math.floor(Math.random() * (10000 - 1000) + 1000)).toString();
// Create hardcoded user & bucket user into a flag variation
let user = eyeofcloudClient.createUserContext(userId);
// "product_sort" corresponds to a flag key in your Eyeofcloud project
let decision = user.decide('product_sort');
let variationKey = decision.variationKey;
// did decision fail with a critical error?
if (variationKey === null) {
console.log(' decision error: ', decision['reasons']);
}
let sortMethod = decision.variables['sort_method'];
// get a dynamic configuration variable
// "sort_method" corresponds to a variable key in your Eyeofcloud project
if (decision.enabled) {
hasOnFlags = true;
}
// Mock what the users sees with print statements (in production, use flag variables to implement feature configuration)
// always returns false until you enable a flag rule in your Eyeofcloud project
console.log(`\nFlag ${decision.enabled ? 'on' : 'off'}. User number ${user.getUserId()} saw flag variation: ${variationKey} and got products sorted by: ${sortMethod} config variable as part of flag rule: ${decision.ruleKey}`);
}
if (!hasOnFlags) {
console.log("\n\nFlag was off for everyone. Some reasons could include:" +
"\n1. Your sample size of visitors was too small. Rerun, or increase the iterations in the FOR loop" +
"\n2. By default you have 2 keys for 2 project environments (dev/prod). Verify in Settings>Environments that you used the right key for the environment where your flag is toggled to ON." +
"\nCheck your key at https://app.eyeofcloud.com/v2/projects/" + eyeofcloudClient.projectConfigManager.getConfig().projectId + "/settings/implementation");
};
});
🚧 重要
暂时不要运行应用程序,因为仍然需要在 云眼 应用程序中设置标帜。
第二部分:运行应用
完成第一部分后,应用将不执行任何操作。需要在 云眼 应用程序中创建标帜和标帜规则才能启用该应用程序。
1. 创建灰度发布(特性标帜)
通过灰度发布(特性标帜),可以控制在应用中看到新功能代码的用户。对于本快速入门,假设你正在推出一个重新设计的排序功能来显示产品。
在 云眼 中创建一个名为 product_sort 的标帜,并为其提供一个名为 sort_method 的变量:
- 转到标帜>创建标帜。
- 将标帜键命名为_product_sort_,然后单击**“创建标帜**”,该标帜对应于示例应用中的标帜键。
- 转到默认变量,然后单击新建 (+)。
- 将变量类型设置为“字符串”。
- 将变量命名_为 sort_method_,该名称对应于示例应用中的变量键。
- 将变量默认值设置为_字母顺序_,表示旧的排序方法。
- 单击右下角的保存以保存变量。
- 转到变体**,**然后点击默认的“开启”变体。变体是变量值集合的包装器。
- 将sort_method变量值设置为 popular_first,表示新的排序方法。
- 单击保存。
2. 创建标帜传递规则
示例应用仍不执行任何操作,因为需要在应用中创建并启用标帜规则。
为_product_sort_标帜的“开启”变体制定有针对性的投放规则。有针对性的交付允许逐步向用户发布灰度发布(特性标帜),但可以灵活地在遇到错误时将其回滚。
- 验证您是否在主环境中(因为您使用的是主环境 SDK 密钥):
- 点击添加规则,然后选择定向投放。
- 将流量滑块设置为 50%。这会将标帜传递给在此环境中触发标帜的每个人的 50%。可以随时将product_sort标帜推出或回滚到流量的百分比。
- 从“传递”下拉列表中,选择“打开”。
- 单击保存。
- 为标帜规则启用标帜:
3. 运行示例应用
如果使用 CodePan 创建实验,则应该已看到输出。否则,请打开您之前使用浏览器菜单创建的文件(文件>打开文件...)。输出类似于以下内容:eyeofcloud-js-quickstart.html
Flag on. User number 6998 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery
Flag on. User number 1177 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery
Flag on. User number 9714 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery
Flag on. User number 4140 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery
Flag on. User number 4994 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery
Flag off. User number 8700 saw flag variation: off and got products sorted by: alphabetical config variable as part of flag rule: default-rollout-208-19963693913
Flag off. User number 9912 saw flag variation: off and got products sorted by: alphabetical config variable as part of flag rule: default-rollout-208-19963693913
Flag on. User number 6560 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery
Flag on. User number 9252 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery
Flag on. User number 6582 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: targeted_delivery
📘 注意
在“开启”变体中,您不会获得恰好 50% 的用户流量,因为您正在与如此少量的访问者合作。此外,获得“关闭”标帜的用户没有进入您设置的 50% 流量,因此他们跌落到默认的“关闭”规则(前面的打印语句中的_默认推出_):
4. 工作原理
到目前为止,您:
- 在 云眼 应用程序中创建了标帜、标帜变量和标帜变体(变量的包装器)
- 使用 Decide 方法在应用中实现了标帜
示例应用中发生了什么?
工作原理:决定向用户显示标帜
SDK 的 Decision(决定)方法确定是显示还是隐藏特定用户的灰度发布(特性标帜)。
📘 注意
可以将此方法重用于不同的标帜规则,无论是向更多流量投放,还是运行实验以仅向部分用户展示不同的排序方法。
了解哪种排序方法最能提高销售额后,请将产品排序标帜推广到所有流量,并将该方法设置为最佳值。
在示例应用中:
var user = eyeofcloudClient.createUserContext(userID);
// "product_sort" corresponds to the flag key you create in the Eyeofcloud app
var decision = user.decide('product_sort');
📘 注意
(可选)在创建用户时包括属性(未显示在示例应用中),以便可以定位特定受众。例如:
var attributes = { logged_in: true }; var user = eyeofcloud.createUserContext('user123', attributes);
工作原理:配置标帜变体
可以使用标帜变量动态配置标帜变体。在示例应用中:
// always returns false until you enable a flag rule in the Eyeofcloud app
if (decision.enabled)
{
// "sort_method" corresponds to variable key you define in Eyeofcloud app
var sortMethod = decision.variables['sort_method'];
console.log('sort_method: ', sortMethod);
}
对于product_sort标帜,可以配置具有不同sort_method值的变体,按热门产品、相关产品、推广产品等进行排序。可以随时在 云眼 应用程序中为排序方法设置不同的值。
第三部分:运行 A/B 测试
本教程只是指导您完成有针对性的交付,因为它是最简单的标帜规则。但是,在推出灰度发布(特性标帜)传递之前,你通常需要对用户_对_灰度发布(特性标帜)变体的反应进行 A/B 测试。
下表显示了标帜传递和 A/B 测试之间的差异:
目标投放规则
A/B 测试规则
可以将标帜推广到一定比例的一般用户群(或特定受众),或者在遇到错误时回滚。
在投资交付之前,通过 A/B 测试标帜进行实验,这样您就知道要构建什么。跟踪用户在标帜变体中的行为,然后使用 云眼 统计引擎解释实验结果。
现在,A / B测试product_sort标帜的“on”变体。
1. 添加事件跟踪
需要将跟踪事件方法添加到示例应用,以便可以模拟用户事件,然后查看指标。
- 删除旧的示例代码,并粘贴以下代码。
- 请记得再次更换开发工具包密钥。
- 不要运行应用程序,因为仍然需要在 云眼 应用程序中设置 A/B 测试。
<!DOCTYPE html>
<html>
<head>
<title>Quickstart Guide</title>
<script src="https://unpkg.com/@eyeofcloud/eyeofcloud-sdk/dist/eyeofcloud.browser.umd.min.js"></script>
</head>
<body>
<pre>Welcome to our Quickstart Guide!</pre>
<pre id="errors"></pre>
<pre id="experiences"></pre>
<pre id="result"></pre>
<script>
// For more instantiation configuration, see the Javascript SDK reference
var eyeofcloudClient = window.eyeofcloudSdk.createInstance({
sdkKey: '<YOUR_SDK_KEY>'
});
eyeofcloudClient.onReady().then(() => {
var errors = document.getElementById('errors');
if (!eyeofcloudClient.isValidInstance()) {
errors.innerText = 'Eyeofcloud client invalid. Verify in Settings>Environments that you used the primary environment\'s SDK key';
return;
}
var experiences = document.getElementById('experiences');
let hasOnFlags = false;
for (let i = 0; i < 4; i++) {
// to get rapid demo results, generate random users. Each user always sees the same variation unless you reconfigure the flag rule.
let userId = (Math.floor(Math.random() * (10000 - 1000) + 1000)).toString();
// Create hardcoded user & bucket user into a flag variation
let user = eyeofcloudClient.createUserContext(userId);
// "product_sort" corresponds to a flag key in your Eyeofcloud project
let decision = user.decide('product_sort');
let variationKey = decision.variationKey;
// did decision fail with a critical error?
if (variationKey === null) {
errors.innerText += `\n\ndecision error: ${decision['reasons']}`;
}
// get a dynamic configuration variable
// "sort_method" corresponds to a variable key in your Eyeofcloud project
let sortMethod = decision.variables['sort_method'];
if (decision.enabled) {
hasOnFlags = true;
}
// Mock what the users sees with print statements (in production, use flag variables to implement feature configuration)
// always returns false until you enable a flag rule in your Eyeofcloud project
experiences.innerText += `\n\n\nFlag ${decision.enabled ? 'on' : 'off'}. User number ${user.getUserId()} saw flag variation: ${variationKey} and got products sorted by: ${sortMethod} config variable as part of flag rule: ${decision.ruleKey}`;
mockPurchase(user, experiences);
}
// mock tracking a user event so you can see some experiment reports
function mockPurchase(user, experiences) {
var question = '\nPretend that user ' + user.getUserId() + ' made a purchase? y/n';
experiences.innerText += question;
var answer = prompt(question);
experiences.innerText += ("\n" + answer);
// track a user event you defined in the Eyeofcloud app
if (answer == 'y') {
user.trackEvent('purchase');
experiences.innerText += ("\nEyeofcloud recorded a purchase in experiment results for user " + user.getUserId());
}
else {
experiences.innerText += ("\nEyeofcloud didn't record a purchase in experiment results for user " + user.getUserId());
}
}
var result = document.getElementById('result');
if (!hasOnFlags) {
result.innerText = "\nFlag was off for everyone. Some reasons could include:" +
"\n1. Your sample size of visitors was too small. Rerun, or increase the iterations in the FOR loop" +
"\n2. By default you have 2 keys for 2 project environments (dev/prod). Verify in Settings>Environments that you used the right key for the environment where your flag is toggled to ON." +
"\n\nCheck your key at https://app.eyeofcloud.com/v2/projects/" + eyeofcloudClient.projectConfigManager.getConfig().projectId + "/settings/implementation";
} else {
result.innerText = "\nDone with your mocked A/B test. " +
"\nCheck out your report at https://app.eyeofcloud.com/v2/projects/" + eyeofcloudClient.projectConfigManager.getConfig().projectId + "/reports" +
"\nBe sure to select the environment that corresponds to your SDK key"
}
});
</script>
</body>
</html>
const eyeofcloudSdk = require('@eyeofcloud/eyeofcloud-sdk');
const readline = require("readline");
// For more instantiation configuration, see the Javascript SDK reference
const eyeofcloudClient = eyeofcloudSdk.createInstance({
sdkKey: '<YOUR_SDK_KEY>'
});
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
eyeofcloudClient.onReady().then(() => {
if (!eyeofcloudClient.isValidInstance()) {
console.log('Eyeofcloud client invalid. Verify in Settings>Environments that you used the primary environment\'s SDK key');
return;
}
runExperiment();
// mock tracking a user event so you can see some experiment reports
function mockPurchase(user) {
return new Promise(function (resolve) {
rl.question('Pretend that user ' + user.getUserId() + ' made a purchase? y/n\n', function(answer) {
// track a user event you defined in the Eyeofcloud app
if (answer === 'y') {
user.trackEvent('purchase');
console.log("Eyeofcloud recorded a purchase in experiment results for user " + user.getUserId());
} else {
console.log("Eyeofcloud didn't record a purchase in experiment results for user " + user.getUserId());
}
resolve(answer);
});
});
};
async function runExperiment() {
let hasOnFlags = false;
for (let i = 0; i < 4; i++) {
// to get rapid demo results, generate random users. Each user always sees the same variation unless you reconfigure the flag rule.
let userId = (Math.floor(Math.random() * (10000 - 1000) + 1000)).toString();
// Create hardcoded user & bucket user into a flag variation
let user = eyeofcloudClient.createUserContext(userId);
// "product_sort" corresponds to a flag key in your Eyeofcloud project
let decision = user.decide('product_sort');
let variationKey = decision.variationKey;
// did decision fail with a critical error?
if (variationKey === null) {
console.log(' decision error: ', decision['reasons']);
}
// get a dynamic configuration variable
// "sort_method" corresponds to a variable key in your Eyeofcloud project
let sortMethod = decision.variables['sort_method'];
if (decision.enabled) {
hasOnFlags = true;
}
// Mock what the users sees with print statements (in production, use flag variables to implement feature configuration)
// always returns false until you enable a flag rule in your Eyeofcloud project
console.log(`\n\nFlag ${decision.enabled ? 'on' : 'off'}. User number ${user.getUserId()} saw flag variation: ${variationKey} and got products sorted by: ${sortMethod} config variable as part of flag rule: ${decision.ruleKey}`);
await mockPurchase(user);
}
if (!hasOnFlags) {
console.log("\n\nFlag was off for everyone. Some reasons could include:" +
"\n1. Your sample size of visitors was too small. Rerun, or increase the iterations in the FOR loop" +
"\n2. By default you have 2 keys for 2 project environments (dev/prod). Verify in Settings>Environments that you used the right key for the environment where your flag is toggled to ON." +
"\nCheck your key at https://app.eyeofcloud.com/v2/projects/" + eyeofcloudClient.projectConfigManager.getConfig().projectId + "/settings/implementation");
} else {
console.log("\n\nDone with your mocked A/B test. " +
"\nCheck out your report at https://app.eyeofcloud.com/v2/projects/" + eyeofcloudClient.projectConfigManager.getConfig().projectId + "/reports" +
"\nBe sure to select the environment that corresponds to your SDK key");
}
}
});
2. 暂停免费帐户中的其他规则
如果你有免费帐户,则需要在保存 A/B 测试之前暂停之前在本快速入门中创建的目标交付:
- 选择包含您计划暂停的目标投放的特定标帜。
- 选择要暂停的环境和目标投放。
- 单击右上角的禁用规则按钮。
3. 创建 A/B 测试
要在云眼项目中创建和启动实验,请执行以下操作:
- 转到标帜的规则。
- 单击“> A/B 测试添加规则”。
4. 添加事件
在实验中,将跟踪用户的相关操作,以衡量用户对灰度发布(特性标帜)变体的反应。需要定义要跟踪的操作:
- 单击**“指标**”字段。
- 点击创建新活动。
- 对于事件密钥,输入_购买_并单击创建事件。(您想知道新的排序标帜是否帮助客户确定要购买什么,因此请跟踪用户在新订单中显示产品后是否进行了购买。
- 保留默认值(衡量_唯一身份转化_次数_的增加_)。
- 点击添加指标。
- 将默认的“关闭”变体保留为控件。选择您在上一步中配置的**“开”**变体:
- 单击保存。
📘 注意
您不限于两种变体;还可以创建具有多个变体的 A/B 测试。
仔细检查标帜以确保它处于开启状态,以便实验可以运行:
5. 运行 A/B 测试
使用浏览器,使用浏览器菜单(文件>打开文件...)打开 html 文件。输出应类似于以下内容:
Flag on. User number 1496 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: experiment_1
Pretend that user 1496 made a purchase? y/n
n
Eyeofcloud didn't record a purchase in experiment results for user 1496
Flag off. User number 1194 saw flag variation: off and got products sorted by: alphabetical config variable as part of flag rule: experiment_1
Pretend that user 1194 made a purchase? y/n
y
Eyeofcloud recorded a purchase in experiment results for user 1194
Flag off. User number 5815 saw flag variation: off and got products sorted by: alphabetical config variable as part of flag rule: experiment_1
Pretend that user 5815 made a purchase? y/n
y
Eyeofcloud recorded a purchase in experiment results for user 5815
Flag on. User number 1248 saw flag variation: on and got products sorted by: popular_first config variable as part of flag rule: experiment_1
Pretend that user 1248 made a purchase? y/n
y
Eyeofcloud recorded a purchase in experiment results for user 1248
Flag off. User number 9580 saw flag variation: off and got products sorted by: alphabetical config variable as part of flag rule: experiment_1
Pretend that user 9580 made a purchase? y/n
n
Eyeofcloud didn't record a purchase in experiment results for user 9580
Done with your mocked A/B test.
Check out your report at https://app.eyeofcloud.com/v2/projects/19957465438/reports
Be sure to select the environment that corresponds to your SDK key
6. 查看 A/B 测试结果
转到“报告”标签以查看实验结果。
结果应如下所示:
📘 注意
- 在拥有更多用户之前,开发者可能不会看到为标帜变体配置的确切用户流量百分比。
- 开发者可能不会立即看到用户流量。刷新浏览器以刷新流量。
- 在有大量访问者(大约 100,000 人)之前,实验结果不会告诉您获胜变体。
7. 工作原理
对于 A/B 测试,需要一种方法来告知 云眼 用户何时在应用中进行了购买,并将应用代码中的此事件映射到您在 云眼 中创建的特定事件。幸运的是,SDK有一种方法!使用 Track Event 方法并传入所创建事件的密钥 ()。在示例应用中:purchase
// Track how users behave when they see a flag variation
// e.g., after your app processed a purchase, let Eyeofcloud know what happened:
user.trackEvent('purchased');
📘 注意
(可选)向事件添加标签以丰富事件(未显示在示例应用中)。还可以使用收入等备用标签键来跟踪定量结果。例如:
@tab JavaScript
var tags = { category: 'shoes', revenue: 6432, }; user.trackEvent('purchase', tags);
:::
目前仅实验规则支持事件跟踪,不支持投放规则。未来变体将支持跟踪交货。
无论哪种方式,在实现标帜时都应包括事件跟踪,因为它可以帮助与第三方分析平台集成,并且在创建 A/B 测试时提供灵活性。
结论
祝贺!您已成功设置并启动了第一个云眼灰度发布(特性标帜)AB实验。虽然此示例侧重于优化销售,但 云眼 的实验平台可以支持一组开放式的实验用例。
请参阅我们的整个 JavaScript(浏览器)文档,了解使用实验优化软件的更多方法。