SlideShare a Scribd company logo
Understanding
the Performance
Impact of
Generated
JavaScript
DeveloperWeek 2023
Shana
Matthews
- DevRel at Sentry.io
- Fun facts
- Every version of Windows since
2016 has shipped with code I’ve
written
- I once delayed a Windows 10 major
release
Abhijeet
Prasad
- SDK engineer at Sentry.io
- Maintains Sentry JavaScript SDKs
- Cool dude
- Largely responsible for making all
this happen
1
The background
2
Why & how to minify your JS
3 The results
Agenda
What is Sentry?
CONFIDENTIAL
The problem
SDK too big.
CONFIDENTIAL
The problem
SDK too big.
● V6 JavaScript SDK was 74.47kb (minified, un-gzipped)
● New performance features would increase package size further
● “Package size is massive” issue filed on the SDK
CONFIDENTIAL
The goal
Reduce SDK size by 30% and improve tree shaking
CONFIDENTIAL
The goal
Reduce SDK size by 30% and improve tree shaking
Measure minified CDN bundle, not gzipped
Track bundle size using the size-limit library
CONFIDENTIAL
Understanding generated JavaScript
Minified
CONFIDENTIAL
Categories of optimizations
1. Optimizations for down-compiling & transpiling
2. Optimizations for minification
CONFIDENTIAL
Categories of optimizations
1. Optimizations for down-compiling & transpiling
2. Optimizations for minification
CONFIDENTIAL
1. Down-compiling & transpiling
● Removing usages of optional chaining
● Using const enums or string constants instead of
TypeScript enums
CONFIDENTIAL
1. Down-compiling & transpiling
● Removing usages of optional chaining
● Using const enums or string constants instead of TypeScript
enums
CONFIDENTIAL
Optional chaining
CONFIDENTIAL
Optional chaining
CONFIDENTIAL
Optional chaining
example PRs
CONFIDENTIAL
1. Down-compiling & transpiling
● Removing usages of optional chaining
● Using const enums or string constants instead of
TypeScript enums
CONFIDENTIAL
TypeScript enums to…
CONFIDENTIAL
TypeScript enums to const enums
CONFIDENTIAL
TypeScript enums to const enums
CONFIDENTIAL
TypeScript enums to string constants
CONFIDENTIAL
TypeScript enums to string constants
CONFIDENTIAL
TypeScript enums to string constants
example PR
CONFIDENTIAL
Categories of optimizations
1. Optimizations for down-compiling & transpiling
2. Optimizations for minification
CONFIDENTIAL
2. Optimizations for minification
Minification = making your JavaScript assets as small as possible
● Remove whitespace, comments, unnecessary tokens
● Shorten variable, function names
Sentry uses terser.
CONFIDENTIAL
CONFIDENTIAL
2. Optimizations for minification
● Using try-catch blocks to simplify code requiring nested
object access
● Local aliases for object keys to improve minification
● Converting classes to objects and functions
CONFIDENTIAL
2. Optimizations for minification
● Using try-catch blocks to simplify code requiring nested
object access
● Local aliases for object keys to improve minification
● Converting classes to objects and functions
CONFIDENTIAL
Nested
object
access
CONFIDENTIAL
Nested object access in our codebase
CONFIDENTIAL
Simplify with a try catch
example PR
CONFIDENTIAL
2. Optimizations for minification
● Using try-catch blocks to simplify code requiring nested
object access
● Local aliases for object keys to improve minification
● Converting classes to objects and functions
CONFIDENTIAL
Aliasing object keys to local variables
CONFIDENTIAL
Aliasing object keys to local variables
CONFIDENTIAL
After
minification
CONFIDENTIAL
2. Optimizations for minification
● Using try-catch blocks to simplify code requiring nested
object access
● Local aliases for object keys to improve minification
● Converting classes to objects and functions
CONFIDENTIAL
Converting classes to objects and
functions
CONFIDENTIAL
CONFIDENTIAL
CONFIDENTIAL
Example 1: convert Memo class to function
Example 2: convert Logger class to functions
CONFIDENTIAL
Converting classes to objects and functions
Example 1: convert Memo class to function
Example 2: convert Logger class to functions
CONFIDENTIAL
Let’s review!
CONFIDENTIAL
Techniques to optimize your JS
1. Optimizations for down-compiling & transpiling
○ Removing usages of optional chaining
○ Using const enums or string constants instead of TypeScript enums
2. Optimizations for minification
○ Using try-catch blocks to simplify code requiring nested object access
○ Local aliases for object keys to improve minification
○ Converting classes to objects and functions
CONFIDENTIAL
Our results
Version Minified unzipped size
version 6.16.1 74.47kb
version 7.3.1 52.67kb
29% decrease
CONFIDENTIAL
Our results
29% bundle size decrease out of the box
Plus tree-shaking related improvements, like…
Next.js 30kb reduction in run-time JS
Finally closed: Package size is massive #2707
“We have been very impressed with the new
Sentry JS SDK. Not only is the bundle size
significantly smaller out of the box, but we were
able to reduce it further through tree shaking.”
Shu Ding
Software Engineer, Vercel
Thank you 💖
Read more in our blog post:
bit.ly/generated-javascript-blog
GitHub discussion for the changes:
bit.ly/js-v7-gh-discussion
Sentry JavaScript docs:
bit.ly/sentry-js-docs
Check out our Sandbox:
bit.ly/sentry-sandbox

More Related Content

Similar to Understanding the Performance Impact of Generated JavaScript.pptx

Application Architecture April 2014
Application Architecture April 2014Application Architecture April 2014
Application Architecture April 2014Lars-Erik Kindblad
 
Elephant Carpaccio
Elephant CarpaccioElephant Carpaccio
Elephant CarpaccioLars Thorup
 
ATAGTR2017 Protractor Cucumber BDD Approach
ATAGTR2017 Protractor Cucumber BDD ApproachATAGTR2017 Protractor Cucumber BDD Approach
ATAGTR2017 Protractor Cucumber BDD ApproachAgile Testing Alliance
 
Test driven development - Zombie proof your code
Test driven development - Zombie proof your codeTest driven development - Zombie proof your code
Test driven development - Zombie proof your codePascal Larocque
 
Journey of Kubernetes Scaling
Journey of Kubernetes ScalingJourney of Kubernetes Scaling
Journey of Kubernetes ScalingOpsta
 
Prod-Like Integration Testing for Distributed Containerized Applications
Prod-Like Integration Testing for Distributed Containerized ApplicationsProd-Like Integration Testing for Distributed Containerized Applications
Prod-Like Integration Testing for Distributed Containerized ApplicationsVMware Tanzu
 
Developer Night Opticon 2017
Developer Night Opticon 2017Developer Night Opticon 2017
Developer Night Opticon 2017Optimizely
 
API workshop by AWS and 3scale
API workshop by AWS and 3scaleAPI workshop by AWS and 3scale
API workshop by AWS and 3scale3scale
 
2016 07 - CloudBridge Python library (XSEDE16)
2016 07 - CloudBridge Python library (XSEDE16)2016 07 - CloudBridge Python library (XSEDE16)
2016 07 - CloudBridge Python library (XSEDE16)Enis Afgan
 
TypeScript and Angular2 (Love at first sight)
TypeScript and Angular2 (Love at first sight)TypeScript and Angular2 (Love at first sight)
TypeScript and Angular2 (Love at first sight)Igor Talevski
 
Best Angular JS training in Hyderabad, India
Best Angular JS training in Hyderabad, IndiaBest Angular JS training in Hyderabad, India
Best Angular JS training in Hyderabad, IndiaN Benchmark IT Solutions
 
Ultimate Guide to Microservice Architecture on Kubernetes
Ultimate Guide to Microservice Architecture on KubernetesUltimate Guide to Microservice Architecture on Kubernetes
Ultimate Guide to Microservice Architecture on Kuberneteskloia
 
Why Upgrade to v8.6?
Why Upgrade to v8.6?Why Upgrade to v8.6?
Why Upgrade to v8.6?BillCavaUs
 
How to Create Your Own Product-Modeling Environment
How to Create Your Own Product-Modeling EnvironmentHow to Create Your Own Product-Modeling Environment
How to Create Your Own Product-Modeling EnvironmentTim Geisler
 
Object Oriented Concepts and Principles
Object Oriented Concepts and PrinciplesObject Oriented Concepts and Principles
Object Oriented Concepts and Principlesdeonpmeyer
 
Data Day Seattle 2017: Scaling Data Science at Stitch Fix
Data Day Seattle 2017: Scaling Data Science at Stitch FixData Day Seattle 2017: Scaling Data Science at Stitch Fix
Data Day Seattle 2017: Scaling Data Science at Stitch FixStefan Krawczyk
 

Similar to Understanding the Performance Impact of Generated JavaScript.pptx (20)

Devops Online Training.pdf
Devops Online Training.pdfDevops Online Training.pdf
Devops Online Training.pdf
 
Devops Online Training.pdf
Devops Online Training.pdfDevops Online Training.pdf
Devops Online Training.pdf
 
Devops Online Training.pdf
Devops Online Training.pdfDevops Online Training.pdf
Devops Online Training.pdf
 
Application Architecture April 2014
Application Architecture April 2014Application Architecture April 2014
Application Architecture April 2014
 
Elephant Carpaccio
Elephant CarpaccioElephant Carpaccio
Elephant Carpaccio
 
ATAGTR2017 Protractor Cucumber BDD Approach
ATAGTR2017 Protractor Cucumber BDD ApproachATAGTR2017 Protractor Cucumber BDD Approach
ATAGTR2017 Protractor Cucumber BDD Approach
 
Test driven development - Zombie proof your code
Test driven development - Zombie proof your codeTest driven development - Zombie proof your code
Test driven development - Zombie proof your code
 
Journey of Kubernetes Scaling
Journey of Kubernetes ScalingJourney of Kubernetes Scaling
Journey of Kubernetes Scaling
 
Prod-Like Integration Testing for Distributed Containerized Applications
Prod-Like Integration Testing for Distributed Containerized ApplicationsProd-Like Integration Testing for Distributed Containerized Applications
Prod-Like Integration Testing for Distributed Containerized Applications
 
Developer Night Opticon 2017
Developer Night Opticon 2017Developer Night Opticon 2017
Developer Night Opticon 2017
 
API workshop by AWS and 3scale
API workshop by AWS and 3scaleAPI workshop by AWS and 3scale
API workshop by AWS and 3scale
 
Dust.js
Dust.jsDust.js
Dust.js
 
2016 07 - CloudBridge Python library (XSEDE16)
2016 07 - CloudBridge Python library (XSEDE16)2016 07 - CloudBridge Python library (XSEDE16)
2016 07 - CloudBridge Python library (XSEDE16)
 
TypeScript and Angular2 (Love at first sight)
TypeScript and Angular2 (Love at first sight)TypeScript and Angular2 (Love at first sight)
TypeScript and Angular2 (Love at first sight)
 
Best Angular JS training in Hyderabad, India
Best Angular JS training in Hyderabad, IndiaBest Angular JS training in Hyderabad, India
Best Angular JS training in Hyderabad, India
 
Ultimate Guide to Microservice Architecture on Kubernetes
Ultimate Guide to Microservice Architecture on KubernetesUltimate Guide to Microservice Architecture on Kubernetes
Ultimate Guide to Microservice Architecture on Kubernetes
 
Why Upgrade to v8.6?
Why Upgrade to v8.6?Why Upgrade to v8.6?
Why Upgrade to v8.6?
 
How to Create Your Own Product-Modeling Environment
How to Create Your Own Product-Modeling EnvironmentHow to Create Your Own Product-Modeling Environment
How to Create Your Own Product-Modeling Environment
 
Object Oriented Concepts and Principles
Object Oriented Concepts and PrinciplesObject Oriented Concepts and Principles
Object Oriented Concepts and Principles
 
Data Day Seattle 2017: Scaling Data Science at Stitch Fix
Data Day Seattle 2017: Scaling Data Science at Stitch FixData Day Seattle 2017: Scaling Data Science at Stitch Fix
Data Day Seattle 2017: Scaling Data Science at Stitch Fix
 

Recently uploaded

Agentic RAG What it is its types applications and implementation.pdf
Agentic RAG What it is its types applications and implementation.pdfAgentic RAG What it is its types applications and implementation.pdf
Agentic RAG What it is its types applications and implementation.pdfChristopherTHyatt
 
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...CzechDreamin
 
Speed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in MinutesSpeed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in Minutesconfluent
 
Demystifying gRPC in .Net by John Staveley
Demystifying gRPC in .Net by John StaveleyDemystifying gRPC in .Net by John Staveley
Demystifying gRPC in .Net by John StaveleyJohn Staveley
 
Powerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara LaskowskaPowerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara LaskowskaCzechDreamin
 
AI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří KarpíšekAI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří KarpíšekCzechDreamin
 
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...FIDO Alliance
 
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdf
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdfHow Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdf
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdfFIDO Alliance
 
Top 10 Symfony Development Companies 2024
Top 10 Symfony Development Companies 2024Top 10 Symfony Development Companies 2024
Top 10 Symfony Development Companies 2024TopCSSGallery
 
Enterprise Knowledge Graphs - Data Summit 2024
Enterprise Knowledge Graphs - Data Summit 2024Enterprise Knowledge Graphs - Data Summit 2024
Enterprise Knowledge Graphs - Data Summit 2024Enterprise Knowledge
 
Connecting the Dots in Product Design at KAYAK
Connecting the Dots in Product Design at KAYAKConnecting the Dots in Product Design at KAYAK
Connecting the Dots in Product Design at KAYAKUXDXConf
 
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptxUnpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptxDavid Michel
 
IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024IoTAnalytics
 
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdfWhere to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdfFIDO Alliance
 
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdfThe Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdfFIDO Alliance
 
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...FIDO Alliance
 
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdfIntroduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdfFIDO Alliance
 
Optimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through ObservabilityOptimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through ObservabilityScyllaDB
 
Structuring Teams and Portfolios for Success
Structuring Teams and Portfolios for SuccessStructuring Teams and Portfolios for Success
Structuring Teams and Portfolios for SuccessUXDXConf
 
Strategic AI Integration in Engineering Teams
Strategic AI Integration in Engineering TeamsStrategic AI Integration in Engineering Teams
Strategic AI Integration in Engineering TeamsUXDXConf
 

Recently uploaded (20)

Agentic RAG What it is its types applications and implementation.pdf
Agentic RAG What it is its types applications and implementation.pdfAgentic RAG What it is its types applications and implementation.pdf
Agentic RAG What it is its types applications and implementation.pdf
 
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
 
Speed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in MinutesSpeed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in Minutes
 
Demystifying gRPC in .Net by John Staveley
Demystifying gRPC in .Net by John StaveleyDemystifying gRPC in .Net by John Staveley
Demystifying gRPC in .Net by John Staveley
 
Powerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara LaskowskaPowerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara Laskowska
 
AI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří KarpíšekAI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří Karpíšek
 
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
 
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdf
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdfHow Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdf
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdf
 
Top 10 Symfony Development Companies 2024
Top 10 Symfony Development Companies 2024Top 10 Symfony Development Companies 2024
Top 10 Symfony Development Companies 2024
 
Enterprise Knowledge Graphs - Data Summit 2024
Enterprise Knowledge Graphs - Data Summit 2024Enterprise Knowledge Graphs - Data Summit 2024
Enterprise Knowledge Graphs - Data Summit 2024
 
Connecting the Dots in Product Design at KAYAK
Connecting the Dots in Product Design at KAYAKConnecting the Dots in Product Design at KAYAK
Connecting the Dots in Product Design at KAYAK
 
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptxUnpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
 
IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024
 
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdfWhere to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
 
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdfThe Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
 
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
 
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdfIntroduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
 
Optimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through ObservabilityOptimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through Observability
 
Structuring Teams and Portfolios for Success
Structuring Teams and Portfolios for SuccessStructuring Teams and Portfolios for Success
Structuring Teams and Portfolios for Success
 
Strategic AI Integration in Engineering Teams
Strategic AI Integration in Engineering TeamsStrategic AI Integration in Engineering Teams
Strategic AI Integration in Engineering Teams
 

Understanding the Performance Impact of Generated JavaScript.pptx

Editor's Notes

  1. This talk is mostly about looking at your TypeScript and finding ways to write that TypeScript better so that when it’s converted into JavaScript and run in the browser, it’s smaller and runs faster. If that sounds interesting, you’re in the right spot!
  2. From Iowa, majored in CS because I liked math but wanted to get a job Before Sentry I mostly worked at Microsoft Dev at Microsoft until I was lured to the dark side of DevRel, switched into Azure to do that Fun facts - I suspect my code will live on inside of Windows until the the AI singularity happens. Wrote SDKs for maps. I personally delayed a Windows 10 major release (every 6 months), Redstone 2 1703 by not testing a senior dev’s suggested simplification to an equation for transforming colors. This was some work related to accessibility which was a huge priority in that release. So the work was coming in late but we were NOT going to ship without this. I was rushing, I accepted the change without testing it fully, and there you go! Literally only worked on things for developers. SDKs, sample apps, tutorials, docs, talks. I’m in too deep ya’ll.
  3. I’m here talking about this today, but I have to give credit to my coworker Abhi. He’s one of the main maintainers to our JavaScript SDKs. Lots of people work on our JS SDKs and lots of people helped with this effort of reducing our SDK size, but Abhi gets a special callout since really led the charge on the refactor.
  4. This is the super high-level agenda of the talk, basically I’ll intro myself and the problem we were running into at Sentry, then we’ll spend the majority of the talk in the meat of how we actually reduced our JavaScript bundle size, then finally we’ll wrap up at the end with seeing how our efforts paid off.
  5. I’m going to super briefly tell you what Sentry is, for context, but this talk really has very little to do with what our product does, other than that we have a bunch of JavaScript SDKs for the product and they were getting super bloated. Sentry is an open source tool for application and performance monitoring. That means devs use Sentry to get alerted & help debug when their code crashes or is slow. We also have awesome artists – we love our creative team. So, Sentry do this for many, many languages and frameworks. Each of which has an SDK that devs have to use in their app. So we have like a million SDKs (actually like 94 we support + more community-supported). Our JavaScript SDKs are some of the most important and most complicated
  6. So, what was the problem? Our JavaScript SDK’s size was getting out of hand.
  7. So the SDK was at 74.47kb (minified, un-gzipped) On top of that, we were planning to ship some new features around performance and managing release health that we knew would increase package size further if we kept going the way we were. Not surprisingly our users also noticed, and filed this very nice issue on the repo (we love you, it’s fine, keep filing issues)
  8. For our next major release, v7 we knew we wanted to refactor our SDK so we took the opportunity to also ship a reduced bundle size and expand our tree shaking (dead code elimination) capabilities. We came up with 30% through some rough analysis. We figured we could get about a 15% improvement from quick wins and 15% would take more substantial refactoring. This talk is mostly about that first 15%, which we think is applicable to many TypeScript projects!
  9. So, how to measure that 30% improvement? We decided to measure by tracking the size of our minified CDN bundle. The minified bundle is most closely representative of what's actually executed at runtime, which has a direct relationship with parse and execution time. We wanted to minimize the amount of time Sentry blocks the main thread. This talk is scoped down to just minimizing bundle size, so we won’t talk specifically about our tree shaking improvements, but they were good. Also, I’ve tried to include links to relevant PRs that actually made the changes I describe in this talk, so click on those if you’re watching this later with slide access!
  10. We decided to track this using the size-limit library, which checks your commits as part of CI to calculate the bundle size of every PR. This worked well to keep devs accountable and motivated when working on bundle size improvements. Here’s what one of the size-limit reports looked like on a PR to our JavaScript SDK repo
  11. Our SDK for JavaScript was written in TypeScript and if we wanted to decrease our bundle size, we needed to understand what was happening with our final generated javascript. As a super brief review, when you use TypeScript, it must be transpilled into JavaScript. And if you want to support older browsers, you also need to down compile your javascript, which means compiling it to a backwards-compatible version of javascript. Sentry uses the Babel compiler to do these steps. Additionally, you likely want to minifiy your JavaScript as part of your build step. That’s not shown super well in this diagram, but it’s important to make your JavaScript run as fast as possible in the browser. We minify using the Terser package.
  12. Here we define transpilation as the process of converting source code of one language to another language, and down-compilation to be the process of converting source code to a more backward-compatible version of that source code. Understanding how your code is being transpiled and downcompiled is important, because your bundle size is affected by your final generated JavaScript. Our SDK for JavaScript was written in TypeScript and if we wanted to decrease our bundle size, we needed to understand what was happening with our final generated javascript. As a super brief review, when you use TypeScript (like Sentry SDKs do), it must be turned into javascript to run in your browser, which is called transpiling. And if you want to support older browsers, you also need to down compile your javascript, which means compiling it to a backwards-compatible version of javascript Now, before we get into specifics about how we reduced our bundle size, I want to give a very very short review of how modern JavaScript runs in the browser so we’re all on the same page about why this mattered. In the modern web, the JavaScript you write is often down-compiled using a compiler like Babel to make sure your JavaScript is compatible with older browsers or environments. In addition, if you are using TypeScript (like the Sentry SDK’s do) or something similar, you’ll have to transpile your TypeScript to JavaScript. This talk is all about the technical prep work needed to ship a 0 bug reported major issue. In the modern web, the JavaScript you write is often down-compiled using a compiler like Babel to make sure your JavaScript is compatible with older browsers or environments. In addition, if you are using TypeScript (like the Sentry SDK’s do) or something similar, you’ll have to transpile your TypeScript to JavaScript. Both of these processes affect what your final generated JavaScript looks like. And your final generated JavaScript is what makes up your bundle size. This talk is all about the technical prep work needed to ship a 0 bug reported major issue.
  13. 0 confirmed bug reports due to extensive integration testing and not changing public API The JavaScript SDKs are the largest set of SDKs at Sentry, with thousands of organizations relying on them to instrument their applications. As such, we need to make sure that the changes we make to the SDK do not introduce behavior regressions or crashes in user code. Before the major release, we completely revamped our integration testing setup. We introduced brand new browser based integration tests that ran on Playwright, allowing us to test on Chrome, Safari and Firefox at the same time. We also introduced brand new node integration tests that ran on a custom framework we built out that used the Node.js Nock library. Having this integration test setup gave us the confidence to make large scale refactors that were required to try to reduce bundle size.
  14. 0 confirmed bug reports due to extensive integration testing and not changing public API The JavaScript SDKs are the largest set of SDKs at Sentry, with thousands of organizations relying on them to instrument their applications. As such, we need to make sure that the changes we make to the SDK do not introduce behavior regressions or crashes in user code. Before the major release, we completely revamped our integration testing setup. We introduced brand new browser based integration tests that ran on Playwright, allowing us to test on Chrome, Safari and Firefox at the same time. We also introduced brand new node integration tests that ran on a custom framework we built out that used the Node.js Nock library. Having this integration test setup gave us the confidence to make large scale refactors that were required to try to reduce bundle size.
  15. So let’s get into the optimizations we made to our TypeScript and how they affected our generated, minified JavaScript! We’re going to talk about 2 main types of optimizations we made today Optimizing our TypeScript so that when it was downcompiled and transpiled to JavaScript, it would take up fewer bytes Optimizing our TypeScript so that our minifier was able to minify it more effectively, so it took up fewer bytes
  16. First, we’ll dive into our first category: optimizations around down-compiling and transpiling
  17. We were able to work on a couple types of quick wins within the realm of optimizations for down-compiling and transpiling. These were an easy place to get started decreasing bundle size.
  18. Up first, optional chaining
  19. The optional chaining operator (?.) is a newer JavaScript feature introduced with ES2020 in June 2020. So if “hey” was null here, instead of throwing an error, the expression evaluates to undefined. Super handy, but since its so new, it must be down-compiled to work with older browsers. When down-compiled, this particular feature tends to produce a lot of extra bytes.
  20. This is what the downcompiled result of that previous snippet looks like when targeting ES6, which takes up a LOT more bytes than the optional chaining version and even more than the old-fashioned way of doing this, the Boolean short circuit.
  21. This is way more bytes than the equivalent boolean short circuit: Like I mentioned, the Sentry SDK is written in TypeScript, so we were able to switch to the Boolean short circuit expression everywhere we were using optional chaining. With TypeScript, we could rely on type coercion to make sure everything was typed correctly. That link shows some example PRs of switching optional chaining to Boolean short circuits. I don’t think anyone did the exact math on how much we saved total by getting rid of optional chaining, but a couple percent, for sure.
  22. Next, changing the way we used enums in the SDK
  23. We were using TypeScript enums everywhere in the SDK. TypeScript enums are great because they provide reverse mapping, the ability to map enum values to enum names if they’re not already a string enum, which, again can be very handy if you’re taking advantage of it. BUT, they take up a lot of bytes. For example a regular enum like this one showing states: Would map to something like:
  24. For example a regular enum like this one showing states: Would map to something like: In this case, this was a lot of extra generated code that we wanted to optimize.
  25. One way we optimized these TypeScript enums was to convert them to const enums for any that were only used interally. Here's showing that same States enum as a const enum. Const enums automatically inline enum members when they’re used. This means the enum doesn’t generate any extra code! Unfortunately this only works for internal-only enums, since const enums are removed at transpile time. The space-saving benefit means that they can’t be imported and used by users of the SDK.
  26. For those other public-facing enums, we still wanted to optimize them. Here’s a public-facing TypeScript string enum for Severity levels and it’s transpiled JavaScript version. That’s a lot of extra code
  27. For these public, exported enums, we deprecated them in favor of using string constants, as much as it made sense. That looked something like changing this to…
  28. That looked something like changing this to… To this. Which saved a ton of bytes. I’ve also linked a PR that shows an example of making this enum to string constant change in the SDK. This was another easy win that gave us some really good bundle size improvements. The linked PR alone, from deprecating the severity enum dropped our non-gizpped bundle size by almost 2% as measured by the size-limit library we were using
  29. Ok we’ve covered the first category of optimizations that relate to transpilation and down-compiling. Another important part of getting the bundle as small as possible is minification, which is the second category of improvements we made.
  30. Minification is exactly what it sounds like: making your JavaScript assets as small as possible. In the minification process, we remove white space, comments, and other unnecessary tokens, and shorten variable and function names. Sentry minifies our JS SDK by using the terser library.
  31. I’m sure many of you are familiar, but here’s an example of minification. This example shows how terser minified this code specifically. I’ve tried to fit both the before and after code on one slide so forgive me here. In this example, Terser reduces the number of bytes by 60% - which is amazing. But we’re already minifying our code, and you probably are too. Modern bundlers like Webpack will minify your code by default in production mode. To do better than this automatic minification, we need to get a little more complicated and manual with our optimizations for minification.
  32. In this category of minification-related optimizations, we’re going to go through 3 examples of how we rewrote our TypeScript to work better with minification. Simplifying nested object access by using try-catch blocks to catch undefined objects, instead of chained undefined checks Using local variables instead of object keys Minifying private class and method names and moving towards functions and objects
  33. First up, using try-catch blocks instead of chaining undefined checks or using optional chaining.
  34. Let’s return to that previous example function and its minified version. What is and isn’t being minified? Reserved keywords (like export, function, return) here are used by the JavaScript language themselves, so they can’t be minified. In addition, identifiers that are required for code to work properly like object keys or class methods are not minified. In this example, the veryVeryLongKey property of the bestObject object cannot be minified because users need to be able to access the { nestedKey: arg2 } value using the veryVeryLongKey. So nested keys cannot get minified because they are needed to index the various nested objects. And we had examples of this throughout the SDK codebase, where we would do undefined checks to make sure we didn’t throw any errors.
  35. We had examples of this throughout the SDK codebase, where we would do undefined checks to make sure we didn’t throw any errors. This is a real example from our SDK code, where these nested keys can never get minified, just based on how minification works, so automatic minification isn’t doing a lot for us here. In order to reduce some bytes, we’ll have to make a manual simplification. Instead of preventing type errors with these undefined checks, or using optional chaining, which would work nicely here, but as we’ve already discussed, it is also super size wasteful because of down-compilation, we can simply take advantage of the existing try catch block…
  36. We’re already in a try catch block, so we can actually shorten this to a single line and ignore the resulting TypeError that would occur if values were undefined. Again, I’ve linked to an actual PR in our SDK that shows an example of doing this kind of optimization.
  37. The previous trick of simplifying code with try/catch statements is useful in some situations, but isn’t going to work for everything. Another strategy we took to deal with these nested object keys that can’t be minified is to create local aliases for object keys to make minification work better.
  38. Here’s an example of another function in our actual SDK. We have all these nested object keys that can’t be minified. What we can do is alias these object keys to local variables that CAN get minified. So we edited this code to
  39. So we edited this code to this code Can't show you on one slide I added comments above each line to show what it was in the previous slide, which hopefully helps. You can see that we’re creating these local aliases every time we get a layer deeper in the object. Ok, so let’s compare the first version (no aliases) and this second version after minifying
  40. After minification, you can see that the second version, that used local aliases saves quite a few bytes.
  41. We’re on to the third and final minification-related optimization! This one is mostly here as a bonus for interested parties, because it’s very hard to show with slides.
  42. So, just like object properties, class methods and identifiers generally can’t minified.
  43. Let’s look at a simplified example from the Sentry codebase, the API class, which the SDK uses to manage how it sends data to a Sentry instance. We’re just showing a tiny bit of this class. 2 example methods, the getStoreEndpointWithUrlEncodedAuth () method and the _encodedAuth() method. This SDK uses terser, and we’ve configured terser to minify private field and method names. This is great and definitely saves bytes, but public field and methods can’t be minified.
  44. So here’s the minified version of that snippet. You can see _encodedAuth() is minified to h() but getStoreEndpointWithUrlEncodedAuth () is still getStoreEndpointWithUrlEncodedAuth (). The fact that we can’t minify public method names becomes a real problem with very long method names, or even kinda long method names that are used very frequently. On top of that, trying to work around it can cause even more problems, because now you have to start paying attention to how long your method names are.
  45. The way we worked around this was by converting internal classes to objects and functions. Naturally, showing this is basically impossible on a slide, but essentially the public fields on the class become keys on an object, and then you use functions to operate on those objects. Since those functions are just top level exports, they can be minified. Here’s an example of this in our Memo class - you can’t see the public fields becoming object keys
  46. Again, here are some PR examples of doing this. The first one is that Memo class I had the screenshot of on the previous slide and the second is for our Logger class. Although we ended up converting some more internal classes to use a more functional style to save on bytes, we couldn’t convert the biggest classes in the Sentry SDK, the Client and the Hub This was because many users were manually importing and using these classes, so converting them would make it difficult for those users to upgrade.
  47. Ok, this has been a lot! Let’s quickly review the categories of optimizations we were able to make and reveal our final results!
  48. There are major package size benefits to reducing the amount of generated JavaScript your package is creating. As part of our larger Javascript SDK package reduction, we spent a considerable effort to minify as much of our code as possible. If you’re looking to do the same, here are 2 categories of improvements to consider: First, optimizing the way we wrote our TypeScript so that when it was downcompiled and transpiled to JavaScript, it would take up fewer bytes Which involved removing uses of optional chaining and switching to const enums and string constants over regular TypeScript enums Second, optimizing the way we wrote our TypeScript so that we were able to minify it more effectively. This involved using try-catch blocks to simplify nested object access, adding local aliases for object keys, and converting classes to objects and functions.
  49. So what were the results? When we started making changes with version 6.16.1, our minified un-gzipped browser SDK was 74.47kb. As of Browser JavaScript version 7.3.1, the bundle size of the minified un-gzipped browser SDK is 52.67kb. This represents a 29% decrease in bundle size, as measured by the size-limit library. Our goal was 30%, but we were very, very pleased with 29%
  50. In addition, our v7SDK also came with some great tree shaking improvements that users really appreciated. For example, some of our Next.js SDK users have reported a 30kb reduction in run-time JavaScript size. Our tests internally have shown similar wins, but the final numbers will vary based on your specific SDK being used and what features you are using from the SDK. In addition, we were finally able to close the “Package size is massive” issue that was filed. Now that’s a win.
  51. Here’s a quote from one of the devs at Vercel who appreciated the effort.
  52. This talk also exists in blog post form - if you want to read more, go there If you want to dig in further to the types of bundle size improvements, tree shaking improvements, and other refactoring we did on the v7 SDK, the second link is where you can go for that. That links you to a discussion on GitHub where we talk about all of this and link to even more PRs. Finally, if you want to learn more about Sentry, you can check out our JavaScript docs or we have a pretty nice Sandbox where you can see what Sentry can do in terms of helping you see and debug errors and performance problems. That’s it! Any questions?