Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

File size #29

Open
RWOverdijk opened this issue Jul 3, 2020 · 5 comments
Open

File size #29

RWOverdijk opened this issue Jul 3, 2020 · 5 comments

Comments

@RWOverdijk
Copy link

馃挰 Question

Looking at my bundle size on web a large part of it is eva icons.

image

Another large part of it is @ui-kitten/components, specifically ui (and of course mapping).

I was wondering if there's something that can be done to reduce this. I only use 4 icons in total, so it seems a bit much to have all of it in the bundle.

React Native Eva Icons Version

"@ui-kitten/components": "^5.0.0",
"@ui-kitten/eva-icons": "^5.0.0",
"@eva-design/eva": "^2.0.0",

@artyorsh
Copy link
Collaborator

artyorsh commented Jul 3, 2020

You may use this package + this guide to create an icon pack for your app without installing @ui-kitten/eva-icons

@artyorsh
Copy link
Collaborator

artyorsh commented Jul 3, 2020

Or...

@artyorsh
Copy link
Collaborator

artyorsh commented Jul 3, 2020

Seems you can鈥檛. The large file size will come from the generated index.js of this package, which contains a switch clause for accessing icons by name.

I don鈥檛 see any solution for it by now

@RWOverdijk
Copy link
Author

RWOverdijk commented Jul 3, 2020

Maybe it can change to the way material icons work? They need to be imported directly which allows for smaller bundle sizes.

This could work? There's a convenience when importing everything from the same file (index) but you also lose a lot of optimizations. Same goes for UI Kitten I suppose. That's why you can import specific parts from firebase, material and even lodash. I believe it's called "tree shaking" but I'm not super familiar with that yet.

In any case, that could reduce file size by a lot, and would make for a pretty awesome update. I can help! 馃槃

@marklawlor
Copy link

marklawlor commented Nov 26, 2020

@RWOverdijk This is slightly off topic for react-native-eva-icons, but I hacked a solution into ui-kitten

For my use case I want individual components to register their required icons, which can then be duduped and tree-shaken per bundle.

import { SvgProps } from "react-native-svg";
import { IconProps } from "@ui-kitten/components/ui/icon/icon.component";
import { IconRegistryService } from "@ui-kitten/components/ui/icon/service/iconRegistry.service";
import { IconPack } from "@ui-kitten/components/ui/icon/service/type";
import { EvaIcon } from "@ui-kitten/eva-icons/evaIcon.component";
import { kebabCase } from "src/utilities/string";

// Override the register function to allow partial pack registers
Object.getPrototypeOf(IconRegistryService).register = function register<T>(
  this: typeof IconRegistryService,
  ...packs: IconPack<T>[]
) {
  packs.forEach((pack: IconPack<IconProps>) => {
    this.registerIconPack({
      name: pack.name,
      icons: {
        ...this.getIconPack(pack.name)?.icons,
        ...pack.icons,
        
      },
    });
  });
};

export function registerIconPacks<T>(...packs: IconPack<T>[]): void {
  IconRegistryService.register(...packs);
}

export function registerIcons(
  icons: Record<string, React.ComponentType<SvgProps>>,
  name?: string
): void {
  IconRegistryService.register({
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- Need to access protected function
    // @ts-ignore
    name: name || IconRegistryService.getDefaultPack().name,
    icons: Object.fromEntries(
      Object.entries(icons).map(([key, icon]) => [
        kebabCase(key),
        new EvaIcon(icon),
      ])
    ),
  });
}

This then allows my React components to register their icons

import CalendarOutline from "react-native-eva-icons/icons/CalendarOutline";
import { registerIcons } from "src/IconRegistryHack";

registerIcons({
  CalendarOutline,
});

I'm using NextJS as my framework, so I can simply include the hack in the _app.tsx file and everything works out. I haven't really tested this, so there might be some issues - but hopefully this gives you some ideas.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants