Slide 1

Slide 1 text

Turbocharging Walmart.com: Speed without compromise Vasanth Krishnamoorthy v a s a n t h _ k v a s a n t h k

Slide 2

Slide 2 text

Focus Areas 7 Key Optimizations Approaching Performance Guardrails for Performance

Slide 3

Slide 3 text

Over 30% growth YoY 100 million+ customers per month

Slide 4

Slide 4 text

Performance as a Measure Of User Happiness

Slide 5

Slide 5 text

Home Page Search Product Page Cart Checkout Tech Stack Typical Customer Journey

Slide 6

Slide 6 text

Customer Journey TTI - 95th %ile mobile web 42% Improvement

Slide 7

Slide 7 text

PART 1 Approaching Performance

Slide 8

Slide 8 text

Where do you start?

Slide 9

Slide 9 text

“You can’t improve what you don’t measure”

Slide 10

Slide 10 text

Measure What Matters TTI – Time to interactive (custom) TTFB – Time to first byte TLOAD - Page is fully loaded (custom) TTFB TTI TLOAD

Slide 11

Slide 11 text

Define Your Scope

Slide 12

Slide 12 text

Define Your Scope & Constraints 01 02 03 No compromise to existing product features No slowdown on new product features being built No big rewrites or tech stack changes

Slide 13

Slide 13 text

Identify The Right Opportunities

Slide 14

Slide 14 text

Empathize With Your Users Use data to understand user pain points Understand common user flows Step progression User distribution by browsers/devices/connection Revenue distribution by browsers & platform

Slide 15

Slide 15 text

Audit Your Application Chrome’s Dev Tools WebPageTest & Lighthouse Webpack Bundle Analyzer Make visible the invisible

Slide 16

Slide 16 text

Apply First Principles

Slide 17

Slide 17 text

Principles of Web Performance 1 2 3 Do only what is needed Minimize round trip time Optimize Perceived Performance

Slide 18

Slide 18 text

PART 2 7 Key Optimizations

Slide 19

Slide 19 text

Do only what is needed

Slide 20

Slide 20 text

Reduce Bundle Size

Slide 21

Slide 21 text

Code Splitting & Lazy Loading Cumulative TTI Improvement 18.2% “Get it when you need it” Component centric code splitting via dynamic imports (ES2020) Code split user/item specific feature code Lazy load components which are below the fold TTI 18.2% 1

Slide 22

Slide 22 text

Code Splitting - Learnings Duplicates in chunks Our sweet spot < 15 split bundles Aggressive code splitting increased overall bytes downloaded Reduced Compression Cumulative TTI Improvement 18.2% 1

Slide 23

Slide 23 text

Slim Down Libraries Recompose React API / Hooks 5KB Upgrade from Webpack v3 to v4 reduced bundle size by 10% Cumulative TTI Improvement 18.2% TTI 9.7% From Switch To Gains (compressed) Moment.js date-fns 50KB React v15 React v16 15KB React-Intl Custom utility 14KB 26.1% 2

Slide 24

Slide 24 text

26.1% Differential Serving Enables us to serve modern JS code to users Why do we need it? • Transformed ES5 code is verbose (more KB) • Cut down on polyfills needed (~35KB for us) Cumulative TTI Improvement TTI 3.3% 28.5% 3

Slide 25

Slide 25 text

Differential Serving Module No-Module Pattern 3 26.1% Cumulative TTI Improvement 28.5%

Slide 26

Slide 26 text

Differential Serving - Learnings On a few browser versions both ES5 & ES6 scripts were downloaded/executed leading to degraded experience for those customers Problem 3 26.1% Cumulative TTI Improvement 28.5%

Slide 27

Slide 27 text

Differential Serving - Learnings On Server side, we check for the user agent passed and depending on whether the browser supports modern syntax or not we include the right bundle into the page. Solution 3 26.1% Cumulative TTI Improvement 28.5%

Slide 28

Slide 28 text

Minimize round trip time

Slide 29

Slide 29 text

Sharing is caring for our users

Slide 30

Slide 30 text

Shared Bundles 1P/3P bundles • Shared across whole site Webpack DLL Plugin Functional shared bundles • Shared across Cart & Checkout TTI 10.2% 25.8% Cumulative TTI Improvement 35.8% 4

Slide 31

Slide 31 text

Shared Bundles - Learnings Needs unification of package versions across applications Updates to shared bundles require coordination with multiple teams Functional shared bundles Updates frequently and requires changes across all shared web-apps Testing/validations & Release effort 1P/3P shared bundle Cumulative TTI Improvement 28.5% 35.8% 4

Slide 32

Slide 32 text

Shared Header/Footer Header/Footer package was bundled into each app leading to bloat Any change required testing/validation & deployments across for all teams Problem 5

Slide 33

Slide 33 text

Shared Header/Footer Solution Endpoint returning header/footer HTML Fragment Markup & bundles get cached Render Header/Footer & rest of the App in parallel during SSR 5

Slide 34

Slide 34 text

35.8% Shared Header/Footer 70% reduction in client side JS Cumulative TTI improvement TTI 8.1% Reuse existing code and render with React on Server Side Use Vanilla JS for handling events on client Optimization 41% 5

Slide 35

Slide 35 text

41% Brotli Compression 12% smaller bundles than GZIP Cumulative TTI Improvement TTI 9.8% “It’s like GZIP on steroids” 46.7% 6

Slide 36

Slide 36 text

Brotli Compression – Learnings For Best Perf - Pre-build compressed assets and serve it from a CDN to save the runtime cost. Dynamic compression can be slow 41% Cumulative TTI Improvement 46.7% 6

Slide 37

Slide 37 text

For Differential Serving Brotli compressed ES5 bundles pretty well ES6 vs ES5 bundle difference dropped from 10% to 4%* *YMMV Brotli Compression - Learnings 41% Cumulative TTI Improvement 46.7% 6

Slide 38

Slide 38 text

Optimize Perceived Performance

Slide 39

Slide 39 text

46.7% Leverage Priorities & Resource Hints <script async> <script defer> TTI 5.7% Cumulative TTI improvement HTML parsing HTML parsing paused Script download Script execution 49.7% 7

Slide 40

Slide 40 text

Leverage Priorities & Resource Hints Tells the browser to download and cache a resource to have them available for execution when it is needed 46.7% Cumulative TTI Improvement 49.7% 7

Slide 41

Slide 41 text

Leverage Priorities & Resource Hints dns-prefetch DNS lookup preconnect DNS lookup, TLS negotiation, and TCP handshake 46.7% Cumulative TTI Improvement 49.7% 7

Slide 42

Slide 42 text

Can we make it faster?

Slide 43

Slide 43 text

“The fastest HTTP request is the one not made”

Slide 44

Slide 44 text

Prefetch Downloads scripts with lower priority & stores it in prefetch cache Cached for at least 5mins Does not execute JS Cumulative TTI Improvement 49.7% TTI 12.1% 55.8% 8

Slide 45

Slide 45 text

Prefetch - Learnings Problem Impacts current page’s load times Workaround • We include prefetch tags into the page after onLoad event is fired • We do not prefetch if the user has data saver on Cumulative TTI Improvement 49.7% 55.8% 8

Slide 46

Slide 46 text

Video Comparison Before After

Slide 47

Slide 47 text

Key Takeaways

Slide 48

Slide 48 text

Perf Optimizations – Key Takeaways Reduce Bundle Size • Code Splitting & Lazy Loading • Slim down libraries • Differential Serving Shared bundles • 1P/3P & functional shared bundles • Header/Footer HTML fragment Better compression • Brotli Priorities & resource hints • Prefer defer over async • dns-prefetch & preconnect • Prefetch Font Optimization • Remove unused glyphs & styles • WOFF & WOFF2 for better compression Image • Lazy load images • WEBP • SVG Redux State transfer optimization • Send state to client in an inert tag Other Cleanup • Code which you have always wanted to delete. You know what they are J Cumulative TTI Improvement 55.8% 60%

Slide 49

Slide 49 text

Perf Improvements Over Time TTI Time (months) What you think it was What it actually was

Slide 50

Slide 50 text

Challenges 3rd Party Scripts: Ads, Marketing Tags Cross-team initiatives Time to complete A/B Tests Performance Regressions

Slide 51

Slide 51 text

Guardrails For Performance PART 3

Slide 52

Slide 52 text

Performance Budgets TTFB Speed Index TTI Page Complete

Slide 53

Slide 53 text

Performance Metrics Per PR Bundle Size check at PR

Slide 54

Slide 54 text

Performance Metrics Per PR View perf metrics over time Lighthouse metrics for each PR

Slide 55

Slide 55 text

Compare Metrics Across Branches Teams can compare branch performance to production performance Click through commits and see what caused the degradation Results used to accept or reject release

Slide 56

Slide 56 text

Sustaining A Performance Culture Embed performance thinking early in the product development process Use tooling and data to help drive decisions on performance tradeoffs Maintain gains by monitoring key metrics, tooling and having guardrails Recognize performance is hard and there will be tradeoffs

Slide 57

Slide 57 text

The Team Bryan Morgan Ah Hyun Cho Hiren Patel Madhav Deverkonda Test Armada & Torbit Team Denys Mikhalenko Gauri Shankar Rodrigo Delgado Jon Campbell Uma Mahesh Cory Dang Meet Parikh Megha Gupta Patrick Stapleton Vijay Muniswamy

Slide 58

Slide 58 text

Future Plans 01 03 04 02 Progressive Web App (PWA) Experimenting with alternative UI libraries Streaming SSR Different experiences based on Speed Profiles

Slide 59

Slide 59 text

Performance Is A Journey, Not A Destination

Slide 60

Slide 60 text

THANK YOU va s a nth_ k va s a nthk