This document summarizes the results of performance testing and experiments on the Etsy mobile listing page. It describes testing lazy loading images, reducing CSS file size, switching to SVGs, and reducing JavaScript file size. Synthetic tests and real user monitoring showed improvements in load times, especially on mobile. Further work is still needed to fully optimize frontend performance and architecture to better match the development culture. Performance directly impacts conversion rates, so continued optimization can increase sales.
20. Performance Best Practices
Great server response times
Minify and gzip static JS and CSS assets
Resize and compress images
Responsive images (mostly)
Use proper headers to take advantage of browser caching
Use dns-prefetch resource hints
Use HTTP/2 when available
In-house RUM monitoring and alerting
3rd party synthetic monitoring service
22. Perceived Performance
How quickly users:
• receive confirmation that the page has started loading?
• see the most important information on the page?
• can interact with the page?
28. WebPageTest Results
iPhone 6 iOS9 - 3GSlow
(this is much worse than our typical user experience)
METRIC BEFORE AFTER CHANGE
TTFB 1.8s
Start Render 8.5s
DOM Content Loaded 12.1s
Speed Index 13,193
Time to First Interactive >19s
CSS size 98KB/0.62MB
JS size 386KB/1.46MB
Images 37
Cost $$$$-
50. Automation to the Rescue?
• Selenium script opens the page(s) in a browser
• Run uncss (https://github.com/uncss/uncss)
• Output a new file with only the CSS in use
… But, we didn’t capture *all* states and had to keep adding
more every time we found a bug.
51. CSS Reduction Synthetic Tests
DOMContentLoaded(ms)
1750
3500
5250
7000
Network Speed
Wifi 4G 3G
Before
After CSS Reduction
After Lazy Loading
59. SVG Switch Synthetic Tests
Logged Out
DOMContentLoadedms
1500
3000
4500
6000
Wifi 4G 3G
Before
After SVGs
Logged In
1500
3000
4500
6000
Wifi 4G 3G
Before
After SVGs
74. A Brief History of JS at Etsy
2010 - jQuery w/Homegrown system to
concatenate and serve JS files
2011 - Dependencies get inlined using rails-style
//=require ‘path/to/dependencies’
window.Etsy.module;
2012 - RequireJS - AMD dependencies
require([‘path/to/dependencies’],
function(dep) { });
2017 - still a mix of everything :(