firebase / firebase/firebase-js-sdk

License blocks in every file produce large bundles by default and inflate package sizes

Open
#7,500 2 comments 4 reactions 0 assignees View on GitHub
api: auth feature request
Dominant language
TypeScript
Stars
5.1k
Forks
1k
Avg merge
2d 21h
Merged PRs (30d)
37

Description

### Operating System

any

### Browser Version

any

### Firebase SDK Version

10.1.0

### Firebase SDK Product:

Auth, Database

### Describe your project's tooling

Vite 4.4.7 with default settings, reproduced with vuejs & vanilla templates but assumed likely to affect all frameworks

### Describe the problem

#### Background
We have always seen that the firebase SDK forms a large part of our production JS bundle. This was the case with Vue2 / Webpack / SDK v8 where it adds roughly 407kB (for just auth with app-issued tokens & realtime database). I'd assumed this was unchangeable and due to the known behaviour of the old namespaced JS.

I've just upgraded to SDK v10 and the modular API, alongside upgrading the app to use Vite & Vue3. The new API and the improved tree-shaking did reduce the bundle size, but by less than hoped. By splitting firebase to a separate chunk I can see that it is still contributing 292kB.

I therefore went to review the built JS and discovered that it contained **146 occurrences** of this license comment, all identical other than for dates:

```
/**
* @license
* Copyright 2019 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
```

At 604 bytes long, these license statements are contributing **88.2 kB** to the final production bundle size.

`vite` uses `esbuild` for code minification. After investigation I discovered that by default esbuild is configured to strip most comments but **keep "legal" comments** which include blocks with a `@license` tag. I couldn't easily find clear examples of configuring this through vite, but in the end identified the following:

```js
// vite.config.js
export default defineConfig({
// ... other vite config
esbuild: { legalComments: 'none'}
// ... other vite config
})
```

Adding this config option reduced my `firebase` chunk from 292.13 kB to 203.95 kB - a **saving of 88 kB / 30%!**.

#### Cause
firebase-js-sdk places a separate `@license` block at the top of every source file. This is unlike the majority of JS projects I've seen, where the license information is only provided in the top-level entrypoint script or as a separate file within the repository itself.

In particular when using the modular import style, importing code from multiple source files therefore imports multiple copies of the license block. And by default esbuild (and I think most minifiers) will keep all these license blocks in the output.

#### Proposed resolution
It is possible to workaround this issue by telling esbuild to strip all legal comments. However, there are obviously legal & ethical concerns about doing so universally / arbitrarily as a consumer of licensed code.

Therefore I think the proper resolution is for you to remove the duplicate `@license` blocks from the individual files in the distribution packages.

#### Related considerations

As well as inflating the size of end-user bundles, the repeated license statements also significantly increase the size of the node_modules themselves. If I run `grep -R -Fo '@license' . | wc -l` in the `node_modules/@firebase` directory I get 13,116 results. Assuming all of these are the same 604 byte string, that means roughly ~8Mb of the 91Mb on disk comprises duplicate license statements. There will obviously be compression involved when transferred over the network, but with 1.5 million weekly downloads plus presence of the packages in caches / container registries / runtime images it seems reasonable to assume the duplicate license blocks will be having a measurable impact on CPU and bandwidth for platform & network providers, and in turn avoidable costs & carbon emissions.

### Steps and code to reproduce issue

I have created a minimal example at Stackblitz https://stackblitz.com/edit/vitejs-vite-eplzmz?file=vite.config.js&view=editor

This uses only the following imports in a vanilla JS script:

```js
import { initializeApp } from 'firebase/app';
import { initializeAuth, onAuthStateChanged } from 'firebase/auth';
```

It then builds the package with default config, and with `legalComments: 'none'`. The output is very clear:
![image](https://github.com/firebase/firebase-js-sdk/assets/416566/fd21a1d7-77d8-4ff6-be3d-eac64c4378b8)

So even with only those three imports, the additional @license comments contribute an extra 33.8 kB to the final bundle.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.