13 ms·
What's TypeScript compiling? Use a treemap to find out
- deleted 4y ago[deleted]
- deleted 4y ago[deleted]
- afavour 4y agoSurely this is not shaving from the build? It's shaving from the source. The build would never have 80MB of TypeScript types included.
- Karellen 4y agoThe article is clearly talking about the build process, which was reading 80MB of TypeScript sources. You seem to be confusing that with the build output, aka object code or target.
- returningfory2 4y agoNot the parent, but my interpretation of "my Typescript build" would be the build output, not the input to the build process.
- OJFord 4y ago'Build' is commonly used both ways, and not just in software.
- Karellen 4y agoBut the article is very clear about what it means by "build". The three places that it uses the term wrt software, in context, are: > would you rather have TypeScript build your code 20% faster? > did this make my build faster? > You might be surprised what's making it into your build! which are clearly talking about the build process and inputs, not its output.
- afavour 4y agoI think my confusion was the use of MB. If the headline had been "I shaved 200ms from my build" it would be very clear it was about the build process. But when I see MB I immediately think about output.
- tshaddox 4y agoThat interpretation doesn’t even make sense in TypeScript though, does it? You don’t build a “TypeScript app bundle” and send it off to be installed on your TypeScript executor. The only interpretations I can think of for “TypeScript build” would be 1) the typechecking process, which just outputs a list of type errors and warnings or 2) the transpilation process which strips out all the TypeScript syntax from your code leaving you with valid JavaScript.
- geewee 4y agoYes, the title is just misleading and a little clickbaity
- mstudio 4y agoThis was my question as well. The article does answer the question, but off the bat I'd assumed the author was talking about output/dist. The web treemap cli is a great tip. If you are using webpack, webpack-bundle-analyzer is a helpful tool for quickly finding bloated packages. It's definitely helped me cut down my build times: https://github.com/webpack-contrib/webpack-bundle-analyzer https://github.com/webpack-contrib/webpack-bundle-analyzer
- judge2020 4y agoAWS used to have this problem, which is why their JS framework now recommends only installing and importing parts of the API you need: https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/migrating-to-v3.html https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-...
- quackware 4y agoAnd yet aws cdk has migrated to a monopackage design :( https://docs.aws.amazon.com/cdk/v2/guide/migrating-v2.html https://docs.aws.amazon.com/cdk/v2/guide/migrating-v2.html
- sondr3 4y agoYou will rarely, if ever, deploy an application running CDK, so the bundle size is more or less irrelevant. It’s basically a glorified YAML compiler used to bundle infrastructure.
- oneplane 4y agoNot only that, but you'll also not really be running it anywhere that isn't "on AWS", like a browser.
- crazysim 4y agoThe cloudformation job will more than likely dwarf the tsc overhead from cdk stuff being a mono package.
- hinkley 4y agoYou still have to police your coworkers to keep them from importing the whole goddamned thing just for the auth or s3 code...
- richthegeek 4y agoThat's what a linter is for!
- UI_at_80x24 4y agoNot only that, but you will substantially improve your lighthouse/pagerank score by removing GoogleTag/API/AdSense/etc.. scripts.
- mankyd 4y agoI used to work on Pagespeed. People were always so puzzled that adding Google Analytics or Maps to their page would lower their score. "This is your own company's tools! They shouldn't count! Make them fast!" We always responded that adding any extra "weight" to a page made it slower. We didn't give our own tools any special treatment. It was up to the site owners to decided what costs were worth their corresponding benefit. Put another way: the fastest page is an empty one, but that's not terribly useful. Optimize for not just for speed but for utility. (Disclosure: I still work for Google, but haven't worked on Pagespeed - or anything remotely related - in many years).
- leeoniya 4y ago> We didn't give our own tools any special treatment. but you also didn't "Make them fast!" in response to the criticism. i know because i've profiled and purged plenty of google's JS from sites in the past. in most cases, this analytics/tag-manager JS far outweighed the site's own JS, to the tune of 5:1. always found it odd how a company that makes V8, Blink, Chrome's DevTools, LightHouse, Closure Compiler, then evangelizes and blogs about performance but in the end doesnt take its own medicine.
- DJeuxg 4y agoYeah, because page speed under 3 seconds doesn't make a difference to pagerank.
- jefftk 4y agoIt's the same speed/utility tradeoff that mankyd is describing. There was a whole team staffed primarily to improve speed here, but you run into issues where functionality that is very important to publishers (or that makes money for them and so is indirectly important) just needs a lot of client-side javascript. (I used to work in this area when I was at Google)
- bigjoemuffaraw 4y agoIn projects where the node_modules folder starts to get out of hand, I set `"skipLibCheck": true,` in the compilerOptions of my tsconfig file (at least for dev builds). In my understanding, it skips type-checking any d.ts files (which most packages include by now) which dramatically lowers compile time. In the authors case it looks like their project is about 400kb of their own code and then 30mb of node_modules libraries. I think it also skips your own d.ts files (it isn't limited to node_modules), so this might just be a way to dramatically speed up your footgun. I have literally never written my own d.ts file though so it works for my purposes
- geraldwhen 4y agoThat’s not how that works. All imported type files are checked. Skip lib check skips checking types that aren’t imported.
- danvk 4y agoMy understanding is that skipLibCheck skips _type checking_ .d.ts files, i.e. looking for type errors in them. But tsc still has to read those files since you might refer to their types in your own code, which TypeScript will type check.
- lsbehe 4y agoThat treemap looks neat. Knowing which dependencies pull in a lot of code is very useful. What confuses me though is how much space these libraries take. 321kb for a router? 3.4mb for material ui? 1mb for jquery?
- robertoandred 4y agoI'm on a long-term project and we're slowing shifting away from Material UI. So much bloat for not much utility.
- vgel 4y agoAre you shifting to another component library or rolling your own?
- mhoad 4y agoThere is a new “official” one in the works here [1] that uses lots of the “latest and greatest stuff” and should be very fast when it’s finished (later this year). As far as I know it’s set to become the new default company wide implementation of Material on web. [1] https://github.com/material-components/material-web https://github.com/material-components/material-web
- robertoandred 4y agoShifting to a combination of rolling our own and using headless component libraries, which focus strictly on functionality and let you handle all styling. So much of the original bloat comes from the libraries' built-in styles that you then have to override creating a mess of styles; this is totally avoided with headless libraries.
- nwienert 4y agoNot to shamelessly plug, but if you check what I’m working on in my profile it should be relevant. Mostly headless, dramatically more modern, and focused on performance.
- nicoburns 4y agoThe googleapis package is absolutely ridiculously large (and the design is such that you can't import only part of it which is how it should work). I was able to remove it by depending on `google-auth-library` (an official package that googleapis uses under the hood) instead, but YMMV.
- tpxl 4y agoDoesn't this PR https://github.com/googleapis/google-api-nodejs-client/pull/2557 https://github.com/googleapis/google-api-nodejs-client/pull/... , linked in the article, address this issue (its only ~1.5 years old).
- nicoburns 4y agoHmm... it seems to. Pretty sure I dealt with this issue less than 1.5 years ago, so not sure why this didn't come up.
- danvk 4y agoYes, the underlying issue has been resolved and so this should be a relatively easy fix for any project using `googleapis`. It's not mentioned in the article, but we also added an eslint rule to ban importing `googleapis` so that this won't happen again in the future.
- janpot 4y agoYep, typechecking performance will be drastically improved. Using the trace generator [0], I discovered tsc spent more than three seconds [1] to locate and parse all source files googleapis pulls in during type checking. Replacing it with the individual packages almost completely eliminated that overhead. [0] https://github.com/microsoft/TypeScript/wiki/Performance#performance-tracing https://github.com/microsoft/TypeScript/wiki/Performance#per... [1] https://user-images.githubusercontent.com/2109932/176479729-501d68c3-0c26-4d16-98df-c8ef3f23a290.png https://user-images.githubusercontent.com/2109932/176479729-...
- h1fra 4y agooh wow, I'm definitely trying ! Thanks for sharing. edit: It removed 85mb and saves 8 seconds of build time (about 17%). Less impact in build time than I thought but still the easiest win I got lately.
- bambam24 4y ago
- whalesalad 4y agoOh so it’s not just the google ads grpc Python library that is brutal to live with
- seabrookmx 4y agoAll the Google Python libs are pretty brutal. They use lots of code generation techniques IIRC and have their own home rolled future implementation that is annoying to work with from standard python async.
- rubenfiszel 4y agoSo we are building a hub for task specific scripts for the needs of Windmill and hitting exactly this. We ended up not being able to use googleapis because it was too hard to import reliably with Deno. So in the end, we are ending up reimplementing a collection of per-task importable collection of googleapis. Example: https://hub.windmill.dev/scripts/gdrive/1279/delete-shared-drive-gdrive https://hub.windmill.dev/scripts/gdrive/1279/delete-shared-d... that have permalink so you can use them in your own scripts: https://hub.windmill.dev/raw/101/delete_shared_drive_gdrive.ts https://hub.windmill.dev/raw/101/delete_shared_drive_gdrive....
- endisneigh 4y agoIn general you should remove things you don’t need.
- deleted 4y ago[deleted]
- pasc1878 4y agoNo. In general you should only load things you need Ie opt out is the default.
- endisneigh 4y agoSure, but requirements change, so the two actions are independently necessary.
- helloguillecl 4y agoAfter years of testing different JS frameworks and build systems, I became convinced that heavy Javascript frontends are generally a bad model for the web. One thing is to generate a build and ship it once over the wire in the form of an Installer or bytecode executable. Another thing is to ship the entire package and/or parts of it with every launch event, plus the complexity of shipping transpiled code to different interpreters (different browser in this case) which adds more complexity to the model until it finally explodes. The server side with HTML generated at the backend is a more predictable, faster and simpler approach. Bandwidth is not the issue anymore, but latency. Heavy API consumption from the client, leaves data exposed and increases the latter. Hotwire/Turboframes/StimulusJS removed the need of generating HTML code at the client, leaving a single source of truth while still having a dynamic/friendly frontend. I consider it to be a better model for the web. Plus, new Page Transition API and Navigation API are possibly game changers for a lot of use cases out here.
- wil421 4y agoThis is why I am convinced part of the reason Google and Facebook create JS frameworks is so they can move computation out their data centers and onto your computer.
- helloguillecl 4y agoI think that is in the case of Facebook they were trying to solve their own use case, and in the case of Google, they saw it as a way of strengthening the strategic position of the web in general vs apps.
- hiptobecubic 4y agoEh, i think you're thinking too small here. This whole thread is full of people saying things like, "When _I'm_ building a webapp," and "_My_ projects end up loading slowly," etc. Google is saying things like, "When 400 people are working on a web app, how can we avoid it turning into a shit show."
- no_wizard 4y agoIt should all be down the applications need for client side interactions. Even with hotwire/turboframes, phoenix liveview or other websocket / real time server driven update patterns, it can be suboptimal for many catagories of applications as these rely on (albeit smart) whole replacement of DOM nodes. In heavy applications, or applications that have a lot of represented state, its not the panacea it might seem at first glance. I always tell people, "mileage may vary, there's no silver bullets in this industry". I think it holds true especially when talking about stuff like this.
- no_wizard 4y agoThis is a neat summary of how they shaved some source and developer time! A trick I've used to shave bundle sizes: re-mapping `babel-runtime/*` to `@babe/runtime` and proper core-js imports and `core-js` imports from V2 to V3 latest imports ones. This shaved tons off of my bundles (unfortunately have some libraries we rely on that are both substantial but old) Another one is library deduping. I've re-mapped all of the `lodash.*` to be direct default imports, e.g. `lodash.merge` to `lodash/merge`. Also shaved a ton off my bundle sizes.
- gandreani 4y agoDid you do the re-mapping using webpack? I haven't heard of this approach before and it sounds really promising
- no_wizard 4y agoI did! Was pretty painless, just followed their documentation on configuring resolve settings
- lhnz 4y agoDoesn't this risk the possibility that a new version of these libraries either behaves slightly differently or has different public exports?
- no_wizard 4y agoTests can cover this really well. I also find that lodash and Babel runtime packages were extremely stable APIs. If an API changes a lot it’s not the best strategy. You have to know your dependency chain
- lobo_tuerto 4y agoWouldn't lodash-es and tree-shaking take care of that?
- hinkley 4y agoGetting hammered to reduce page load time during development only to have people slather a bunch of 3rd party APIs on at deployment time may not take the gold medal for soul crushing experiences, but it ranks at least an honorable mention, possibly a bronze. You just undid 3 months worth of work that will take 6 to replicate. Congratulations. We're all really impressed down here.
- stefanfisk 4y agowhat are you talking about?
- hinkley 4y agoSchizophrenia from the business side who want metrics on TTFB and TTI but also want to have a firehose of information about users and don't connect that there are real performance costs to gathering this information. Giant dependencies and time to interactive have been battling each other for decades. It's not just how much code you run on first paint, that's a discipline in its own right. But until the javascript and CSS load you don't really control much of anything in the browser lifecycle. So you work and work on those, and you've gotten through a bunch of performance-as-feature gates, but then someone throws three analytics packages on that together are proportional to the code you sweated to carve out of the initial payloads. You can usually defer those, but how easy that was depends on which generation of web browser you're talking about. What you can't control is how much work those libraries due on the page while they bootstrap. As recently as the last project I worked on in my current job, I discovered that something like 60% of the event loop blocking was coming from some analytics library that was stuck in a reflow loop that was taking longer than we had saved on code that a couple of my poor coworkers had been working on for ages, to the point you could hear the exhaustion in their voices in standup. That one was mostly tripping up due to a performance bug in an old version of jquery (mutation on read), but other examples in this problem domain are often not so simple to fix. Ultimately this is a social problem, but I've seen it way too many times.Someone high in the org chart didn't insist that we run the application exactly as it would run in production. In a Saas situation a customer may say "I want to be able to add stuff to my pages, can you do that?" and nobody catches on that they want to run analytics, and not just for one dashboard, but for the old one they can't let go of and the new one that is cooler but only answers 80% of their questions. And then they want a third party live chat which is somehow as slow as the two analytics libraries combined.
- IceDane 4y agoIncidentally, I also ran into this exact problem with the same package. I briefly thought, "they should let us download individual packages", but since I was already about to bundle everything with esbuild, I didn't look into it. So that's what I ended up doing: using esbuild. It should only be including what is in use, and the result was fine, even though this service was the largest of the services. But I'm still going to install the separate package and see how much that brings the bundle size down.
- danvk 4y agoI'm curious about the results, but remember that this article is talking about the type declarations files that tsc has to read (.d.ts files), not the JS that winds up in your bundle.
- nsxwolf 4y agoEighty. Million. Bytes.
- vijaybritto 4y agoI wonder if it would be consistently faster if we replace a few hot paths with WASM in tsc.
- malinens 4y agoPHP has native way via composer to clean up unneeded google APIs: https://github.com/googleapis/google-api-php-client#cleaning-up-unused-services https://github.com/googleapis/google-api-php-client#cleaning...
- Navarr 4y agoThis is a wildly incorrect approach. Ideally, they would separate the core of what's necessary for any one thing into one composer package, and then everything else into their own (e.g. a youtube package, a drive package, etc.) This way.. I can see you having a code dependency that needs Drive, but b/c you've cleaned out everything except YouTube it's going to fail - and that's sort of breaking the way Composer is supposed to work.
- deleted 4y ago[deleted]
- 2c2c2c 4y agoyup. i had a project consisting of 3 node/ts services where each tsc instance would balloon to 4gb+ memory usage due to googleapis, ooming my 12gb thinkpad
- aabbcc1241 4y agoThe types of aws-sdk is also non trivial. So I always suggest to remove typescript during build phrase (only deploy in js)