patrick lightbody presentation tae slides
DESCRIPTION
TRANSCRIPT
http://browsermob.com
Design Tips for Dynamic UIs Under
Heavy Load
Patrick LightbodyFounder, BrowserMob
http://browsermob.com
Patrick & the ‘MobOpen source contributor- Apache Struts 2.0 (previously WebWork)
- Founder of OpenQA.org and SeleniumHQ.org
- Creator of Selenium Remote Control
Founder of BrowserMob- On-demand load testing and monitoring services
- Uses real web browsers in various cloud environments (EC2, GoGrid, Rackspace, etc)
http://browsermob.com
The ProblemAJAX => Faster (Perceived) Experience- More logic on front-end with asynchronous calls
to server logic on back-end
But when the back-end is slow or error prone, the experience tends to be worse- Non AJAX => Full page load => spinning “e” for IE
Most complex UIs built in isolation- Tested on localhost (no load, infinite bandwidth)
http://browsermob.com
Recent ExampleLoad test for a UK-based car insurance providerFrequent errors in which the the browser was showing a registration form claiming that field X was not filled outA real head-scratcher... we were 110% positive that field was being filled out by the testFinally figured it out: reproduced by hand
http://browsermob.com
UI DesignFirst Name Patrick
Last Name Lightbody
Company BrowserMob
Home Phone 4158305488
Cell Phone
First Name Patrick
Last Name Lightbody
Company BrowserMob
Email Email is required
Home Phone (415) 830-5488
Cell Phone
Web Server
Form Representation
(JSON)
Form Representation
(JSON)
onchangeinject form data back in
http://browsermob.com
Typical Sequence
First Name Patrick
Last Name Lightbody
Company BrowserMob
Home Phone
Cell Phone
http://browsermob.com
Typical Sequence
First Name Patrick
Last Name Lightbody
Company BrowserMob
Email patrick@browsermob
Home Phone
Cell Phone
http://browsermob.com
Typical Sequence
Web Server
Form Representation
(JSON)
First Name Patrick
Last Name Lightbody
Company BrowserMob
Email patrick@browsermob
Home Phone
Cell Phone
AJAX Request #1
http://browsermob.com
Typical Sequence
Web Server
Form Representation
(JSON)
First Name Patrick
Last Name Lightbody
Company BrowserMob
Email patrick@browsermob
Home Phone
Cell Phone
AJAX Request #1
http://browsermob.com
Typical Sequence
Web Server
Form Representation
(JSON)
First Name Patrick
Last Name Lightbody
Company BrowserMob
Email patrick@browsermob
Home Phone
Cell Phone
AJAX Request #1
http://browsermob.com
Typical Sequence
First Name Patrick
Last Name Lightbody
Company BrowserMob
Email patrick@browsermob
Home Phone
Cell Phone
http://browsermob.com
Typical Sequence
First Name Patrick
Last Name Lightbody
Company BrowserMob
Email patrick@browsermob
Home Phone 4158305488
Cell Phone
http://browsermob.com
Typical Sequence
First Name Patrick
Last Name Lightbody
Company BrowserMob
Email patrick@browsermob
Home Phone 4158305488
Cell Phone
Web Server
Form Representation
(JSON)
AJAX Request #2
http://browsermob.com
Typical Sequence
First Name Patrick
Last Name Lightbody
Company BrowserMob
Email patrick@browsermob
Home Phone 4158305488
Cell Phone
Web Server
Form Representation
(JSON)
AJAX Request #2
http://browsermob.com
Typical Sequence
First Name Patrick
Last Name Lightbody
Company BrowserMob
Email patrick@browsermob
Home Phone (415) 830-5488
Cell Phone
http://browsermob.com
First Name Patrick
Last Name Lightbody
Company BrowserMob
Home Phone
Cell Phone
Problem Sequence
http://browsermob.com
Problem Sequence
First Name Patrick
Last Name Lightbody
Company BrowserMob
Email patrick@browsermob
Home Phone
Cell Phone
http://browsermob.com
Problem Sequence
First Name Patrick
Last Name Lightbody
Company BrowserMob
Email patrick@browsermob
Home Phone
Cell Phone
Web Server
Form Representation
(JSON)
AJAX Request #1
http://browsermob.com
Problem Sequence
First Name Patrick
Last Name Lightbody
Company BrowserMob
Email patrick@browsermob
Home Phone
Cell Phone
http://browsermob.com
Problem Sequence
First Name Patrick
Last Name Lightbody
Company BrowserMob
Email patrick@browsermob
Home Phone 4158305488
Cell Phone
http://browsermob.com
Problem Sequence
First Name Patrick
Last Name Lightbody
Company BrowserMob
Email patrick@browsermob
Home Phone 4158305488
Cell Phone
Web Server
Form Representation
(JSON)
AJAX Request #2
http://browsermob.com
Problem Sequence
First Name Patrick
Last Name Lightbody
Company BrowserMob
Email patrick@browsermob
Home Phone 4158305488
Cell Phone
Web Server
Form Representation
(JSON)
AJAX Request #2
http://browsermob.com
Problem Sequence
First Name Patrick
Last Name Lightbody
Company BrowserMob
Email patrick@browsermob
Home Phone (415) 830-5488
Cell Phone
http://browsermob.com
Problem Sequence
First Name Patrick
Last Name Lightbody
Company BrowserMob
Email patrick@browsermob
Home Phone (415) 830-5488
Cell Phone
Web Server
Form Representation
(JSON)
AJAX Request #1First Name Patrick
Last Name Lightbody
Company BrowserMob
Email patrick@browsermob
Home Phone
Cell Phone
http://browsermob.com
Problem Sequence
First Name Patrick
Last Name Lightbody
Company BrowserMob
Email patrick@browsermob
Home Phone (415) 830-5488
Cell Phone
First Name Patrick
Last Name Lightbody
Company BrowserMob
Email patrick@browsermob
Home Phone
Cell Phone
Whoops!
No more Home Phone!
http://browsermob.com
ReproducingRe-create the slowdown/error in your code- Can be turned on/off with a “test” flag in your app
Run load tests simultaneously with browser tests- Run a Selenium test on loop while using JMeter
Run your browser through a network simulator- Simulate bandwidth, latency, response codes, etc
http://browsermob.com
Mocking out FailureAdd simple if statement in the server code that sleep for X seconds or throw an errorAttach a debugger, break on a line, and just sit there before you resume executionIf you’re feeling especially adventurous, make a generic “filter” for your app- In Java this would be a “Servlet Filter”
- Could be made very advanced
http://browsermob.com
public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
String uri = req.getRequestURI();
Random r = new Random(); if (r.nextInt(100) > 80) { res.sendError(500, "20% chance of failure!"); return; }
// sleep between 0 and 5 seconds Thread.sleep(r.nextInt(1000) * 5);
chain.doFilter(req, res);
}
http://browsermob.com
Selenium During LoadHard to predict all ways in which things can go wrong- Easier to simulate the ways things should go right
Run a standard load test against the REST interfaces- Ideally, this should “realistically” slow them down
Simultaneously, play back Selenium scripts- Check for functionality over performance
http://browsermob.com
Selenium as LoadSimilar approach as before, but on steroidsRun hundreds or thousands of Selenium scripts in parallel- This means you need hundreds or thousands of
browsers!
- Checking performance and functionality concurrently
Produces hyper-realistic load scenarios and almost always uncovers unexpected problems
http://browsermob.com
Automatically provisionbrowsers from the cloud
How It Works
http://browsermob.com
Automatically provisionbrowsers from the cloud
How It Works
http://browsermob.com
Automatically provisionbrowsers from the cloud
How It Works4000 CPU Cores3.5TB of RAM
http://browsermob.com
Network SimulatorsAnother approach is to run your browser through a network simulatorUsually done via an HTTP proxy that can be tuned to:- Return fake error codes
- Simulate bandwidth & latency
- Drop packets
- Record network performance
http://browsermob.com
Charles ProxyCharles Proxy- “Web Debugging Proxy Application”
- Windows, OS X, and Linux
- Cost: $50 per user w/ bulk discounts
- http://www.charlesproxy.com
http://browsermob.com
BrowserMob ProxyAnnouncing today: free, open source utilitySupports HTTP and HTTPSProduces Firebug-like results for any browserSimulates different bandwidth, latency, and error conditionsAvailable for download today!- http://proxy.browsermob.com
http://browsermob.com
Design for FailureNever forget: AJAX is still a network call- Networks fail for a lot of different reasons
- Networks can be unpredictable (ie: request #1 can take longer than request #2)
Add hooks to AJAX requests for the unexpected- Write your code to store request params & retry
Test for failure too!
http://browsermob.com
Be Careful w/ DOMOnly change the DOM state if it’s absolutely necessary- Avoid aggressive “synchronization” common in
some AJAX toolkits (ex: our form sync example)
Merge data together rather than replace- Partial page loads (div.innerHTML = ...) is also bad
- Involves more work, but results in a much better experience when things don’t work well
http://browsermob.com
Lock the UIDon’t give the user a chance to change things that might also get changed by you- In our form example: disable the form elements!
- If necessary, use a modal dialog box to lock the entire UI
But remember: have a recovery plan!- Test for failure and ensure that the UI unlocks
when unexpected behavior occurs
http://browsermob.com
Inform the UserAlways keep the user informed about what is happeningIdeally give them an “escape hatch” if things go terrible wrong- Set thresholds for when to present the escape
hatch
- GMail is a good example of this
At minimum, simple “loading” indicator
http://browsermob.com
Questions?Patrick Lightbody
Founder, [email protected]
BrowserMob Proxy (Open Source)http://proxy.browsermob.com
BrowserMob Serviceshttp://browsermob.com