Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Performance and Maintainability with Continuous...
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Seth Walker
April 24, 2014
Technology
1.4k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Performance and Maintainability with Continuous Experimentation
Seth Walker
April 24, 2014
More Decks by Seth Walker
See All by Seth Walker
A Public Commitment to Performance
sethwalker
0
3.8k
Other Decks in Technology
See All in Technology
構造で守らせる データ・法務・セキュリティ・開発チームとつくる AI時代のデータガバナンスとデータ基盤のリアル
legalontechnologies
PRO
1
460
Claude Code on Bedrock で統制をかける小ネタ集/claude-code-bedrock-governance-tips
emiki
1
12k
BacklogのRAG 今ならこう作る - S3 Vectorsと自前パイプラインの勘所
revsystem
0
130
プロダクトが成長すると、 プロダクトマネージャーの仕事はどう変わるのか - 「まず作る」から「小さく学び、確かめながら進む」へ
sansantech
PRO
0
350
AWSセキュリティで活用するAI機能
cmusudakeisuke
1
300
「私が一番顧客に詳しい」を捨てる~ 全員が一次情報に精通する開発チームをつくり、PMが次のボトルネックへ染み出すまで
kaminashi
4
2.4k
Temporal 最高!でも改めて「日付」について調べたら人類の負債すぎる件
riyaamemiya
0
230
顧客価値を追いかけたら、プライシングにたどり着いた
sansantech
PRO
2
1k
導入から定着へ ~コーディングエージェントを日常業務に組み込む実践知~
yukisakai1225
0
230
AI駆動開発における開発環境のセキュリティの考え方
yamahiro
2
610
【データ横丁主催】AI エージェント時代のTranslytical Data Platform
shisyu_gaku
0
290
Filter What the LLM Reads: RAG Governance with AgentCore Gateway
yakumo
0
110
Featured
See All Featured
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.8k
Automating Front-end Workflow
addyosmani
1370
210k
Making the Leap to Tech Lead
cromwellryan
135
10k
エンジニアに許された特別な時間の終わり
watany
109
250k
The Mindset for Success: Future Career Progression
greggifford
PRO
0
550
Documentation Writing (for coders)
carmenintech
77
5.6k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
2
2.1k
The untapped power of vector embeddings
frankvandijk
2
2k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
53k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
Mind Mapping
helmedeiros
1
410
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
300
Transcript
Performance and Maintainability with Continuous Experimentation @sethwalker sethwalker.me/talks/continuous-experimentation
@sethwalker Seth Walker Allison McKnight Jonathan Klein @sethwalker @aemcknig @jonathanklein
Daniel Espeset @danielespeset @dxna Daniel Na Lara Swanson @laraswanson
None
@sethwalker
@sethwalker 175 committers
@sethwalker 100 committers touch CSS & JS
@sethwalker
@sethwalker Confidence?
Operations
@sethwalker Feature Flags
@sethwalker $cfg['save_everything'] = 'staff'; // ... snip ... if (isEnabled('save_everything'))
{ writeToDB($everything); } else { throwAway($everything); }
@sethwalker $cfg['save_everything'] = '1%'; // ... snip ... if (isEnabled('save_everything'))
{ writeToDB($everything); } else { throwAway($everything); }
@sethwalker $cfg['save_everything'] = '5%'; // ... snip ... if (isEnabled('save_everything'))
{ writeToDB($everything); } else { throwAway($everything); }
@sethwalker $cfg['save_everything'] = '1%'; // ... snip ... if (isEnabled('save_everything'))
{ writeToDB($everything); } else { throwAway($everything); }
@sethwalker $cfg['save_everything'] = '5%'; // ... snip ... if (isEnabled('save_everything'))
{ writeToDB($everything); } else { throwAway($everything); }
@sethwalker $cfg['save_everything'] = '10%'; // ... snip ... if (isEnabled('save_everything'))
{ writeToDB($everything); } else { throwAway($everything); }
@sethwalker $cfg['jquery_1_11'] = 'staff'; // ... snip ... if (isEnabled("jquery_1_11"))
{ <script src="/js/lib/jquery-1.11.0.js"></script> } else { <script src="/js/lib/jquery-1.8.2.js"></script> }
@sethwalker $cfg['jquery_1_11'] = '5%'; // ... snip ... if (isEnabled("jquery_1_11"))
{ <script src="/js/lib/jquery-1.11.0.js"></script> } else { <script src="/js/lib/jquery-1.8.2.js"></script> }
@sethwalker $cfg['jquery_1_11'] = '50%'; // ... snip ... if (isEnabled("jquery_1_11"))
{ <script src="/js/lib/jquery-1.11.0.js"></script> } else { <script src="/js/lib/jquery-1.8.2.js"></script> }
None
None
None
None
None
@sethwalker $cfg['jquery_1_11'] = '5%'; // ... snip ... if (isEnabled("jquery_1_11"))
{ <script src="/js/lib/jquery-1.11.0.js"></script> } else { <script src="/js/lib/jquery-1.8.2.js"></script> }
None
None
None
None
@sethwalker $cfg['jquery_1_11'] = '50%'; // ... snip ... if (isEnabled("jquery_1_11"))
{ <script src="/js/lib/jquery-1.11.0.js"></script> } else { <script src="/js/lib/jquery-1.8.2.js"></script> }
@sethwalker $cfg['jquery_1_11'] = '100%'; // ... snip ... if (isEnabled("jquery_1_11"))
{ <script src="/js/lib/jquery-1.11.0.js"></script> } else { <script src="/js/lib/jquery-1.8.2.js"></script> }
None
@sethwalker
@sethwalker window.Etsy.Context = { // ... snip ... "feature":{ "conversations.rejuvination":true,
"activity.dynamic_load_on_scroll":true, "overlays.buttery_smooth":true, "collections.perf_render_fix":true, } };
@sethwalker if (Etsy.Context.feature["overlays.buttery_smooth"]) { doSmooth(); } else { doJanky(); }
@sethwalker TODO: Feature Flags for the asset pipeline
@sethwalker $cfg['js_debug_build'] = 'staff'; // ... snip ... if (isEnabled("js_debug_build"))
{ <script src="/js-debug/main.js"></script> } else { <script src="/js/main.js"></script> }
@sethwalker + Analytics
Continuous Experimentation
@sethwalker Small, measurable changes Dan McKinley - http://mcfunley.com/design-for-continuous-experimentation
@sethwalker Validate hypotheses
@sethwalker Invalidate hypotheses
None
None
@sethwalker
None
:(
@sethwalker 100+ active flags
@sethwalker 60+ active experiments
@sethwalker 14 experimental iterations on listing page redesign
None
None
None
None
None
None
None
None
None
None
None
None
None
@sethwalker N inactive experiments
@sethwalker N inactive experiments N > 0
@sethwalker Cruft
@sethwalker if (isEnabled("new_listing_page")) { <script src="/js/listing/new-listing.js"></script> } if (isEnabled("new_favorite_button")) {
<script src="/js/new-favorites.js"></script> } if (isEnabled("cart2")) { <script src="/js/add-to-cart2.js"></script> }
@sethwalker $cfg["new_listing_page"] = "100%"; $cfg["new_favorite_button"] = "5%"; $cfg["cart2"] = "50%";
@sethwalker define("foo", ["logger"], function(Logger) { Logger.warn("foo is deprecated!"); doFoo(); });
@sethwalker <link rel="stylesheet" href="/css/base.css" /> <link rel="stylesheet" href="/css/listing.css" /> if
(isEnabled("new_listing_page")) { <link rel="stylesheet" href="/css/new-listing.css" /> } if (isEnabled("new_favorite_button")) { <link rel="stylesheet" href="/css/new-favorites.css" /> } if (isEnabled("cart2")) { <link rel="stylesheet" href="/css/add-to-cart2.css" /> }
@sethwalker Let's clean up!
Fear
@sethwalker Throw away
@sethwalker Throw away ability
@sethwalker Design for Throwaway-ability Bill Scott - http://www.looksgoodworkswell.com/the-experimentation-layer/
@sethwalker Tools
@sethwalker Needs More Visibility
None
None
None
None
None
None
None
@sethwalker selectorText = document.styleSheets[i].cssRules[j].selectorText; selected = document.querySelector(selectorText); results.push({ selector: selectorText,
found: !!selected ? 1 : 0}); // ... snip ... log(results);
@sethwalker Existing code - Seen in the wild = SUSPECT
@sethwalker Instrumentation
@sethwalker Increasing confidence
@sethwalker Adapting tools and process
Thanks! @sethwalker sethwalker.me/talks/continuous-experimentation