ionic-team / ionicons

Premium hand-crafted icons built by Ionic, for Ionic apps and web apps everywhere 🌎
http://ionicons.com
MIT License
17.6k stars 2.06k forks source link

Need a way to filter only Ionicons that are in use - currently account for 5.3MB of space in app deployment #910

Closed lincolnthree closed 1 year ago

lincolnthree commented 3 years ago

Feature Request

Ionic version:

[x] 5.x

Describe the Feature Request

Currently, during the build (as configured by Ionic CLI), ALL ionicons are copied to the assets/ directory during a production build. This results in upwards of 5.3 MB of icons being copied and uploaded or packaged via Capacitor, which is often as big as or larger than all the app code being deployed.

This means that if the service-worker 'precache' / 'eager' mode is used to pre-download all assets for offline use, each client must download all of these unused icons --- resulting in hundreds of network requests, and a LOT of space used by the service-worker cache that could be used on actual application data.

Describe Preferred Solution

There needs to be a pre-build step where the application source-code is analyzed, including a hook for any custom / runtime-generated icon use, that copies only the required icons. This would greatly reduce the size of deployed apps. Even with modern cell networks, most of the world still only has 3G or weak 4G at best, and this optimization could be a huge savings.

As far as I can tell, ionicons is the only part of the build process that has this gap. Most modern tools now provide tree-shaking / dead code removal, and ionicons really needs this feature.

Describe Alternatives

None currently exist other than, I suppose, one could attempt to write a custom script to implement this feature.

Related Code

Additional Context

https://github.com/ionic-team/ionicons/issues/637

liamdebeasi commented 3 years ago

Thanks for the issue. I am going to move this to the ionicons repo. Are you testing this with something like Webpack or Rollup?

lincolnthree commented 3 years ago

@liamdebeasi Sounds good. Sorry about that. But actually I think this is more of an Ionic feature than an Ionicons feature, since this is a build issue in the end.

It's really a result of the Angular build config that ionic creates for a new project, and the lack of a suitable method of filtering Ionicons during the build. Here's the relevant code from the angular.json file.

"schematics": {},
 13       "architect": {
 14         "build": {
 15           "builder": "@angular-devkit/build-angular:browser",
 16           "options": {
 ...
 22             "assets": [
 23              
  ...
 28               {
 29                 "glob": "**/*.svg",
 30                 "input": "node_modules/ionicons/dist/ionicons/svg",
 31                 "output": "./svg"
 32               }
 33             ],

FWIW. I think the only real way to solve this problem is probably to create a registry / config file that lists all ionicons that are in use / should be copied. Otherwise the solution would need to account for people passing icon-names/variants via bindings & generated code. Solution would need to understand the code, otherwise.

liamdebeasi commented 3 years ago

Ionic Framework does not handle bundling ionicons, so I do not think the issue would be there. It could be a matter of updating the angular.json file in the starters: https://github.com/ionic-team/starters/blob/master/angular/base/angular.json but I am probably not the right person to determine that. I will check with the team and see if there is a good solution here.

lincolnthree commented 3 years ago

Fair. I probably should have filed this under the CLI instead. Alas. Next time. Anyway, not important.

I'm playing with a simple grep to try to find likely occurrences... results are not ideal:

grep -r icon src/ | grep \.ts
grep -r icon src/ | grep \.html
liamdebeasi commented 3 years ago

Out of curiosity, have you noticed this with Ionic React or Ionic Vue?

lincolnthree commented 3 years ago

@liamdebeasi Unfortunately no. I don't use either of those currently. But I have to imagine unless they are doing something with resource/asset use-tracing, they would have the same issue.

It did appear however, from the comments in the issue I referenced, that others have (at least with vue). https://github.com/ionic-team/ionicons/issues/637#issuecomment-585754107

liamdebeasi commented 3 years ago

Thanks! I will look into this a bit more.

lincolnthree commented 3 years ago

@liamdebeasi Thank you as always :) I'll keep playing around here as well. If I come up with anything reasonable, I'll let you know. But... it seems brute force listing each icon in the application, and using a post-build hook to delete unused files, is the only option revealing itself right now.

lincolnthree commented 3 years ago

@liamdebeasi I actually just had a passing thought about this. Since you (as ionic devs) have the definitive list of combinations of icon/style/mode settings, you could:

  1. Generate a comprehensive list of icon variants.
  2. Ship a build hook script that searches/greps the entire codebase (including js/ts or configurable file patterns) for references that look like names in the list.
  3. Accepts user overrides via configuration.
  4. Generate a manifest that is used to copy only those resources to the app directory via said build hook.

This could be an opt-in feature in case users prefer the default of shipping all ionicons (and as to preserve backwards compatibility.) Eventually, if it works well enough, it could be made the default.

Just thought I'd pass this along as I'm having issues with ionicons being cached in the Angular Service worker and am sort of in this area again today :)

lincolnthree commented 3 years ago

Update. Attempting to use Ionicons with offline support in a PWA is even more problematic than with Capacitor/bundled app-store apps. When attempting to pre-cache icons for offline use (so pages don't show "holes"/"blank spots" where icons should be if users open the PWA while offline,) the pwa service worker can be used.

However. Right now, to use the service-worker with Ionicons causes over one THOUSAND five hundred requests per install or update (if configured as 'prefetch', which is necessary to support offline mode).

This is because there are 3 variants of every possible ionicon. Without a way to filter this list to what is used by the app, it's really just not realistic to enable true offline PWA prefetch support with Ionicons :

As configured in angular.json generated by ionic-cli:

                  "glob": "**/*.svg",
                  "input": "node_modules/ionicons/dist/ionicons/svg",
                  "output": "./svg"
                }, 

Snippit from ngsw.json after building the Angular project in production mode:

    {
      "name": "svg",
      "installMode": "prefetch",
      "updateMode": "prefetch",
      "cacheQueryOptions": {
        "ignoreVary": true
      },
      "urls": [
        "/svg/accessibility-outline.svg",
        "/svg/accessibility-sharp.svg",
        "/svg/accessibility.svg",
        "/svg/add-circle-outline.svg",
        "/svg/add-circle-sharp.svg",
        "/svg/add-circle.svg",
        "/svg/add-outline.svg",
        "/svg/add-sharp.svg",
        "/svg/add.svg",
        "/svg/airplane-outline.svg",
        "/svg/airplane-sharp.svg",
        "/svg/airplane.svg",
        "/svg/alarm-outline.svg",
        "/svg/alarm-sharp.svg",
        "/svg/alarm.svg",
        "/svg/albums-outline.svg",
        "/svg/albums-sharp.svg",
        "/svg/albums.svg",
        "/svg/alert-circle-outline.svg",
        "/svg/alert-circle-sharp.svg",
        "/svg/alert-circle.svg",
        "/svg/alert-outline.svg",
        "/svg/alert-sharp.svg",
        "/svg/alert.svg",
        "/svg/american-football-outline.svg",
        "/svg/american-football-sharp.svg",
        "/svg/american-football.svg",
        "/svg/analytics-outline.svg",
        "/svg/analytics-sharp.svg",
        "/svg/analytics.svg",
        "/svg/aperture-outline.svg",
        "/svg/aperture-sharp.svg",
        "/svg/aperture.svg",
        "/svg/apps-outline.svg",
        "/svg/apps-sharp.svg",
        "/svg/apps.svg",
        "/svg/archive-outline.svg",
        "/svg/archive-sharp.svg",
        "/svg/archive.svg",
        "/svg/arrow-back-circle-outline.svg",
        "/svg/arrow-back-circle-sharp.svg",
        "/svg/arrow-back-circle.svg",
        "/svg/arrow-back-outline.svg",
        "/svg/arrow-back-sharp.svg",
        "/svg/arrow-back.svg",
        "/svg/arrow-down-circle-outline.svg",
        "/svg/arrow-down-circle-sharp.svg",
        "/svg/arrow-down-circle.svg",
        "/svg/arrow-down-outline.svg",
        "/svg/arrow-down-sharp.svg",
        "/svg/arrow-down.svg",
        "/svg/arrow-forward-circle-outline.svg",
        "/svg/arrow-forward-circle-sharp.svg",
        "/svg/arrow-forward-circle.svg",
        "/svg/arrow-forward-outline.svg",
        "/svg/arrow-forward-sharp.svg",
        "/svg/arrow-forward.svg",
        "/svg/arrow-redo-circle-outline.svg",
        "/svg/arrow-redo-circle-sharp.svg",
        "/svg/arrow-redo-circle.svg",
        "/svg/arrow-redo-outline.svg",
        "/svg/arrow-redo-sharp.svg",
        "/svg/arrow-redo.svg",
        "/svg/arrow-undo-circle-outline.svg",
        "/svg/arrow-undo-circle-sharp.svg",
        "/svg/arrow-undo-circle.svg",
        "/svg/arrow-undo-outline.svg",
        "/svg/arrow-undo-sharp.svg",
        "/svg/arrow-undo.svg",
        "/svg/arrow-up-circle-outline.svg",
        "/svg/arrow-up-circle-sharp.svg",
        "/svg/arrow-up-circle.svg",
        "/svg/arrow-up-outline.svg",
        "/svg/arrow-up-sharp.svg",
        "/svg/arrow-up.svg",
        "/svg/at-circle-outline.svg",
        "/svg/at-circle-sharp.svg",
        "/svg/at-circle.svg",
        "/svg/at-outline.svg",
        "/svg/at-sharp.svg",
        "/svg/at.svg",
        "/svg/attach-outline.svg",
        "/svg/attach-sharp.svg",
        "/svg/attach.svg",
        "/svg/backspace-outline.svg",
        "/svg/backspace-sharp.svg",
        "/svg/backspace.svg",
        "/svg/bag-add-outline.svg",
        "/svg/bag-add-sharp.svg",
        "/svg/bag-add.svg",
        "/svg/bag-check-outline.svg",
        "/svg/bag-check-sharp.svg",
        "/svg/bag-check.svg",
        "/svg/bag-handle-outline.svg",
        "/svg/bag-handle-sharp.svg",
        "/svg/bag-handle.svg",
        "/svg/bag-outline.svg",
        "/svg/bag-remove-outline.svg",
        "/svg/bag-remove-sharp.svg",
        "/svg/bag-remove.svg",
        "/svg/bag-sharp.svg",
        "/svg/bag.svg",
        "/svg/ban-outline.svg",
        "/svg/ban-sharp.svg",
        "/svg/ban.svg",
        "/svg/bandage-outline.svg",
        "/svg/bandage-sharp.svg",
        "/svg/bandage.svg",
        "/svg/bar-chart-outline.svg",
        "/svg/bar-chart-sharp.svg",
        "/svg/bar-chart.svg",
        "/svg/barbell-outline.svg",
        "/svg/barbell-sharp.svg",
        "/svg/barbell.svg",
        "/svg/barcode-outline.svg",
        "/svg/barcode-sharp.svg",
        "/svg/barcode.svg",
        "/svg/baseball-outline.svg",
        "/svg/baseball-sharp.svg",
        "/svg/baseball.svg",
        "/svg/basket-outline.svg",
        "/svg/basket-sharp.svg",
        "/svg/basket.svg",
        "/svg/basketball-outline.svg",
        "/svg/basketball-sharp.svg",
        "/svg/basketball.svg",
        "/svg/battery-charging-outline.svg",
        "/svg/battery-charging-sharp.svg",
        "/svg/battery-charging.svg",
        "/svg/battery-dead-outline.svg",
        "/svg/battery-dead-sharp.svg",
        "/svg/battery-dead.svg",
        "/svg/battery-full-outline.svg",
        "/svg/battery-full-sharp.svg",
        "/svg/battery-full.svg",
        "/svg/battery-half-outline.svg",
        "/svg/battery-half-sharp.svg",
        "/svg/battery-half.svg",
        "/svg/beaker-outline.svg",
        "/svg/beaker-sharp.svg",
        "/svg/beaker.svg",
        "/svg/bed-outline.svg",
        "/svg/bed-sharp.svg",
        "/svg/bed.svg",
        "/svg/beer-outline.svg",
        "/svg/beer-sharp.svg",
        "/svg/beer.svg",
        "/svg/bicycle-outline.svg",
        "/svg/bicycle-sharp.svg",
        "/svg/bicycle.svg",
        "/svg/bluetooth-outline.svg",
        "/svg/bluetooth-sharp.svg",
        "/svg/bluetooth.svg",
        "/svg/boat-outline.svg",
        "/svg/boat-sharp.svg",
        "/svg/boat.svg",
        "/svg/body-outline.svg",
        "/svg/body-sharp.svg",
        "/svg/body.svg",
        "/svg/bonfire-outline.svg",
        "/svg/bonfire-sharp.svg",
        "/svg/bonfire.svg",
        "/svg/book-outline.svg",
        "/svg/book-sharp.svg",
        "/svg/book.svg",
        "/svg/bookmark-outline.svg",
        "/svg/bookmark-sharp.svg",
        "/svg/bookmark.svg",
        "/svg/bookmarks-outline.svg",
        "/svg/bookmarks-sharp.svg",
        "/svg/bookmarks.svg",
        "/svg/briefcase-outline.svg",
        "/svg/briefcase-sharp.svg",
        "/svg/briefcase.svg",
        "/svg/browsers-outline.svg",
        "/svg/browsers-sharp.svg",
        "/svg/browsers.svg",
        "/svg/brush-outline.svg",
        "/svg/brush-sharp.svg",
        "/svg/brush.svg",
        "/svg/bug-outline.svg",
        "/svg/bug-sharp.svg",
        "/svg/bug.svg",
        "/svg/build-outline.svg",
        "/svg/build-sharp.svg",
        "/svg/build.svg",
        "/svg/bulb-outline.svg",
        "/svg/bulb-sharp.svg",
        "/svg/bulb.svg",
        "/svg/bus-outline.svg",
        "/svg/bus-sharp.svg",
        "/svg/bus.svg",
        "/svg/business-outline.svg",
        "/svg/business-sharp.svg",
        "/svg/business.svg",
        "/svg/cafe-outline.svg",
        "/svg/cafe-sharp.svg",
        "/svg/cafe.svg",
        "/svg/calculator-outline.svg",
        "/svg/calculator-sharp.svg",
        "/svg/calculator.svg",
        "/svg/calendar-clear-outline.svg",
        "/svg/calendar-clear-sharp.svg",
        "/svg/calendar-clear.svg",
        "/svg/calendar-outline.svg",
        "/svg/calendar-sharp.svg",
        "/svg/calendar.svg",
        "/svg/call-outline.svg",
        "/svg/call-sharp.svg",
        "/svg/call.svg",
        "/svg/camera-outline.svg",
        "/svg/camera-reverse-outline.svg",
        "/svg/camera-reverse-sharp.svg",
        "/svg/camera-reverse.svg",
        "/svg/camera-sharp.svg",
        "/svg/camera.svg",
        "/svg/car-outline.svg",
        "/svg/car-sharp.svg",
        "/svg/car-sport-outline.svg",
        "/svg/car-sport-sharp.svg",
        "/svg/car-sport.svg",
        "/svg/car.svg",
        "/svg/card-outline.svg",
        "/svg/card-sharp.svg",
        "/svg/card.svg",
        "/svg/caret-back-circle-outline.svg",
        "/svg/caret-back-circle-sharp.svg",
        "/svg/caret-back-circle.svg",
        "/svg/caret-back-outline.svg",
        "/svg/caret-back-sharp.svg",
        "/svg/caret-back.svg",
        "/svg/caret-down-circle-outline.svg",
        "/svg/caret-down-circle-sharp.svg",
        "/svg/caret-down-circle.svg",
        "/svg/caret-down-outline.svg",
        "/svg/caret-down-sharp.svg",
        "/svg/caret-down.svg",
        "/svg/caret-forward-circle-outline.svg",
        "/svg/caret-forward-circle-sharp.svg",
        "/svg/caret-forward-circle.svg",
        "/svg/caret-forward-outline.svg",
        "/svg/caret-forward-sharp.svg",
        "/svg/caret-forward.svg",
        "/svg/caret-up-circle-outline.svg",
        "/svg/caret-up-circle-sharp.svg",
        "/svg/caret-up-circle.svg",
        "/svg/caret-up-outline.svg",
        "/svg/caret-up-sharp.svg",
        "/svg/caret-up.svg",
        "/svg/cart-outline.svg",
        "/svg/cart-sharp.svg",
        "/svg/cart.svg",
        "/svg/cash-outline.svg",
        "/svg/cash-sharp.svg",
        "/svg/cash.svg",
        "/svg/cellular-outline.svg",
        "/svg/cellular-sharp.svg",
        "/svg/cellular.svg",
        "/svg/chatbox-ellipses-outline.svg",
        "/svg/chatbox-ellipses-sharp.svg",
        "/svg/chatbox-ellipses.svg",
        "/svg/chatbox-outline.svg",
        "/svg/chatbox-sharp.svg",
        "/svg/chatbox.svg",
        "/svg/chatbubble-ellipses-outline.svg",
        "/svg/chatbubble-ellipses-sharp.svg",
        "/svg/chatbubble-ellipses.svg",
        "/svg/chatbubble-outline.svg",
        "/svg/chatbubble-sharp.svg",
        "/svg/chatbubble.svg",
        "/svg/chatbubbles-outline.svg",
        "/svg/chatbubbles-sharp.svg",
        "/svg/chatbubbles.svg",
        "/svg/checkbox-outline.svg",
        "/svg/checkbox-sharp.svg",
        "/svg/checkbox.svg",
        "/svg/checkmark-circle-outline.svg",
        "/svg/checkmark-circle-sharp.svg",
        "/svg/checkmark-circle.svg",
        "/svg/checkmark-done-circle-outline.svg",
        "/svg/checkmark-done-circle-sharp.svg",
        "/svg/checkmark-done-circle.svg",
        "/svg/checkmark-done-outline.svg",
        "/svg/checkmark-done-sharp.svg",
        "/svg/checkmark-done.svg",
        "/svg/checkmark-outline.svg",
        "/svg/checkmark-sharp.svg",
        "/svg/checkmark.svg",
        "/svg/chevron-back-circle-outline.svg",
        "/svg/chevron-back-circle-sharp.svg",
        "/svg/chevron-back-circle.svg",
        "/svg/chevron-back-outline.svg",
        "/svg/chevron-back-sharp.svg",
        "/svg/chevron-back.svg",
        "/svg/chevron-down-circle-outline.svg",
        "/svg/chevron-down-circle-sharp.svg",
        "/svg/chevron-down-circle.svg",
        "/svg/chevron-down-outline.svg",
        "/svg/chevron-down-sharp.svg",
        "/svg/chevron-down.svg",
        "/svg/chevron-forward-circle-outline.svg",
        "/svg/chevron-forward-circle-sharp.svg",
        "/svg/chevron-forward-circle.svg",
        "/svg/chevron-forward-outline.svg",
        "/svg/chevron-forward-sharp.svg",
        "/svg/chevron-forward.svg",
        "/svg/chevron-up-circle-outline.svg",
        "/svg/chevron-up-circle-sharp.svg",
        "/svg/chevron-up-circle.svg",
        "/svg/chevron-up-outline.svg",
        "/svg/chevron-up-sharp.svg",
        "/svg/chevron-up.svg",
        "/svg/clipboard-outline.svg",
        "/svg/clipboard-sharp.svg",
        "/svg/clipboard.svg",
        "/svg/close-circle-outline.svg",
        "/svg/close-circle-sharp.svg",
        "/svg/close-circle.svg",
        "/svg/close-outline.svg",
        "/svg/close-sharp.svg",
        "/svg/close.svg",
        "/svg/cloud-circle-outline.svg",
        "/svg/cloud-circle-sharp.svg",
        "/svg/cloud-circle.svg",
        "/svg/cloud-done-outline.svg",
        "/svg/cloud-done-sharp.svg",
        "/svg/cloud-done.svg",
        "/svg/cloud-download-outline.svg",
        "/svg/cloud-download-sharp.svg",
        "/svg/cloud-download.svg",
        "/svg/cloud-offline-outline.svg",
        "/svg/cloud-offline-sharp.svg",
        "/svg/cloud-offline.svg",
        "/svg/cloud-outline.svg",
        "/svg/cloud-sharp.svg",
        "/svg/cloud-upload-outline.svg",
        "/svg/cloud-upload-sharp.svg",
        "/svg/cloud-upload.svg",
        "/svg/cloud.svg",
        "/svg/cloudy-night-outline.svg",
        "/svg/cloudy-night-sharp.svg",
        "/svg/cloudy-night.svg",
        "/svg/cloudy-outline.svg",
        "/svg/cloudy-sharp.svg",
        "/svg/cloudy.svg",
        "/svg/code-download-outline.svg",
        "/svg/code-download-sharp.svg",
        "/svg/code-download.svg",
        "/svg/code-outline.svg",
        "/svg/code-sharp.svg",
        "/svg/code-slash-outline.svg",
        "/svg/code-slash-sharp.svg",
        "/svg/code-slash.svg",
        "/svg/code-working-outline.svg",
        "/svg/code-working-sharp.svg",
        "/svg/code-working.svg",
        "/svg/code.svg",
        "/svg/cog-outline.svg",
        "/svg/cog-sharp.svg",
        "/svg/cog.svg",
        "/svg/color-fill-outline.svg",
        "/svg/color-fill-sharp.svg",
        "/svg/color-fill.svg",
        "/svg/color-filter-outline.svg",
        "/svg/color-filter-sharp.svg",
        "/svg/color-filter.svg",
        "/svg/color-palette-outline.svg",
        "/svg/color-palette-sharp.svg",
        "/svg/color-palette.svg",
        "/svg/color-wand-outline.svg",
        "/svg/color-wand-sharp.svg",
        "/svg/color-wand.svg",
        "/svg/compass-outline.svg",
        "/svg/compass-sharp.svg",
        "/svg/compass.svg",
        "/svg/construct-outline.svg",
        "/svg/construct-sharp.svg",
        "/svg/construct.svg",
        "/svg/contract-outline.svg",
        "/svg/contract-sharp.svg",
        "/svg/contract.svg",
        "/svg/contrast-outline.svg",
        "/svg/contrast-sharp.svg",
        "/svg/contrast.svg",
        "/svg/copy-outline.svg",
        "/svg/copy-sharp.svg",
        "/svg/copy.svg",
        "/svg/create-outline.svg",
        "/svg/create-sharp.svg",
        "/svg/create.svg",
        "/svg/crop-outline.svg",
        "/svg/crop-sharp.svg",
        "/svg/crop.svg",
        "/svg/cube-outline.svg",
        "/svg/cube-sharp.svg",
        "/svg/cube.svg",
        "/svg/cut-outline.svg",
        "/svg/cut-sharp.svg",
        "/svg/cut.svg",
        "/svg/desktop-outline.svg",
        "/svg/desktop-sharp.svg",
        "/svg/desktop.svg",
        "/svg/dice-outline.svg",
        "/svg/dice-sharp.svg",
        "/svg/dice.svg",
        "/svg/disc-outline.svg",
        "/svg/disc-sharp.svg",
        "/svg/disc.svg",
        "/svg/document-attach-outline.svg",
        "/svg/document-attach-sharp.svg",
        "/svg/document-attach.svg",
        "/svg/document-lock-outline.svg",
        "/svg/document-lock-sharp.svg",
        "/svg/document-lock.svg",
        "/svg/document-outline.svg",
        "/svg/document-sharp.svg",
        "/svg/document-text-outline.svg",
        "/svg/document-text-sharp.svg",
        "/svg/document-text.svg",
        "/svg/document.svg",
        "/svg/documents-outline.svg",
        "/svg/documents-sharp.svg",
        "/svg/documents.svg",
        "/svg/download-outline.svg",
        "/svg/download-sharp.svg",
        "/svg/download.svg",
        "/svg/duplicate-outline.svg",
        "/svg/duplicate-sharp.svg",
        "/svg/duplicate.svg",
        "/svg/ear-outline.svg",
        "/svg/ear-sharp.svg",
        "/svg/ear.svg",
        "/svg/earth-outline.svg",
        "/svg/earth-sharp.svg",
        "/svg/earth.svg",
        "/svg/easel-outline.svg",
        "/svg/easel-sharp.svg",
        "/svg/easel.svg",
        "/svg/egg-outline.svg",
        "/svg/egg-sharp.svg",
        "/svg/egg.svg",
        "/svg/ellipse-outline.svg",
        "/svg/ellipse-sharp.svg",
        "/svg/ellipse.svg",
        "/svg/ellipsis-horizontal-circle-outline.svg",
        "/svg/ellipsis-horizontal-circle-sharp.svg",
        "/svg/ellipsis-horizontal-circle.svg",
        "/svg/ellipsis-horizontal-outline.svg",
        "/svg/ellipsis-horizontal-sharp.svg",
        "/svg/ellipsis-horizontal.svg",
        "/svg/ellipsis-vertical-circle-outline.svg",
        "/svg/ellipsis-vertical-circle-sharp.svg",
        "/svg/ellipsis-vertical-circle.svg",
        "/svg/ellipsis-vertical-outline.svg",
        "/svg/ellipsis-vertical-sharp.svg",
        "/svg/ellipsis-vertical.svg",
        "/svg/enter-outline.svg",
        "/svg/enter-sharp.svg",
        "/svg/enter.svg",
        "/svg/exit-outline.svg",
        "/svg/exit-sharp.svg",
        "/svg/exit.svg",
        "/svg/expand-outline.svg",
        "/svg/expand-sharp.svg",
        "/svg/expand.svg",
        "/svg/extension-puzzle-outline.svg",
        "/svg/extension-puzzle-sharp.svg",
        "/svg/extension-puzzle.svg",
        "/svg/eye-off-outline.svg",
        "/svg/eye-off-sharp.svg",
        "/svg/eye-off.svg",
        "/svg/eye-outline.svg",
        "/svg/eye-sharp.svg",
        "/svg/eye.svg",
        "/svg/eyedrop-outline.svg",
        "/svg/eyedrop-sharp.svg",
        "/svg/eyedrop.svg",
        "/svg/fast-food-outline.svg",
        "/svg/fast-food-sharp.svg",
        "/svg/fast-food.svg",
        "/svg/female-outline.svg",
        "/svg/female-sharp.svg",
        "/svg/female.svg",
        "/svg/file-tray-full-outline.svg",
        "/svg/file-tray-full-sharp.svg",
        "/svg/file-tray-full.svg",
        "/svg/file-tray-outline.svg",
        "/svg/file-tray-sharp.svg",
        "/svg/file-tray-stacked-outline.svg",
        "/svg/file-tray-stacked-sharp.svg",
        "/svg/file-tray-stacked.svg",
        "/svg/file-tray.svg",
        "/svg/film-outline.svg",
        "/svg/film-sharp.svg",
        "/svg/film.svg",
        "/svg/filter-circle-outline.svg",
        "/svg/filter-circle-sharp.svg",
        "/svg/filter-circle.svg",
        "/svg/filter-outline.svg",
        "/svg/filter-sharp.svg",
        "/svg/filter.svg",
        "/svg/finger-print-outline.svg",
        "/svg/finger-print-sharp.svg",
        "/svg/finger-print.svg",
        "/svg/fish-outline.svg",
        "/svg/fish-sharp.svg",
        "/svg/fish.svg",
        "/svg/fitness-outline.svg",
        "/svg/fitness-sharp.svg",
        "/svg/fitness.svg",
        "/svg/flag-outline.svg",
        "/svg/flag-sharp.svg",
        "/svg/flag.svg",
        "/svg/flame-outline.svg",
        "/svg/flame-sharp.svg",
        "/svg/flame.svg",
        "/svg/flash-off-outline.svg",
        "/svg/flash-off-sharp.svg",
        "/svg/flash-off.svg",
        "/svg/flash-outline.svg",
        "/svg/flash-sharp.svg",
        "/svg/flash.svg",
        "/svg/flashlight-outline.svg",
        "/svg/flashlight-sharp.svg",
        "/svg/flashlight.svg",
        "/svg/flask-outline.svg",
        "/svg/flask-sharp.svg",
        "/svg/flask.svg",
        "/svg/flower-outline.svg",
        "/svg/flower-sharp.svg",
        "/svg/flower.svg",
        "/svg/folder-open-outline.svg",
        "/svg/folder-open-sharp.svg",
        "/svg/folder-open.svg",
        "/svg/folder-outline.svg",
        "/svg/folder-sharp.svg",
        "/svg/folder.svg",
        "/svg/football-outline.svg",
        "/svg/football-sharp.svg",
        "/svg/football.svg",
        "/svg/funnel-outline.svg",
        "/svg/funnel-sharp.svg",
        "/svg/funnel.svg",
        "/svg/game-controller-outline.svg",
        "/svg/game-controller-sharp.svg",
        "/svg/game-controller.svg",
        "/svg/gift-outline.svg",
        "/svg/gift-sharp.svg",
        "/svg/gift.svg",
        "/svg/git-branch-outline.svg",
        "/svg/git-branch-sharp.svg",
        "/svg/git-branch.svg",
        "/svg/git-commit-outline.svg",
        "/svg/git-commit-sharp.svg",
        "/svg/git-commit.svg",
        "/svg/git-compare-outline.svg",
        "/svg/git-compare-sharp.svg",
        "/svg/git-compare.svg",
        "/svg/git-merge-outline.svg",
        "/svg/git-merge-sharp.svg",
        "/svg/git-merge.svg",
        "/svg/git-network-outline.svg",
        "/svg/git-network-sharp.svg",
        "/svg/git-network.svg",
        "/svg/git-pull-request-outline.svg",
        "/svg/git-pull-request-sharp.svg",
        "/svg/git-pull-request.svg",
        "/svg/glasses-outline.svg",
        "/svg/glasses-sharp.svg",
        "/svg/glasses.svg",
        "/svg/globe-outline.svg",
        "/svg/globe-sharp.svg",
        "/svg/globe.svg",
        "/svg/golf-outline.svg",
        "/svg/golf-sharp.svg",
        "/svg/golf.svg",
        "/svg/grid-outline.svg",
        "/svg/grid-sharp.svg",
        "/svg/grid.svg",
        "/svg/hammer-outline.svg",
        "/svg/hammer-sharp.svg",
        "/svg/hammer.svg",
        "/svg/hand-left-outline.svg",
        "/svg/hand-left-sharp.svg",
        "/svg/hand-left.svg",
        "/svg/hand-right-outline.svg",
        "/svg/hand-right-sharp.svg",
        "/svg/hand-right.svg",
        "/svg/happy-outline.svg",
        "/svg/happy-sharp.svg",
        "/svg/happy.svg",
        "/svg/hardware-chip-outline.svg",
        "/svg/hardware-chip-sharp.svg",
        "/svg/hardware-chip.svg",
        "/svg/headset-outline.svg",
        "/svg/headset-sharp.svg",
        "/svg/headset.svg",
        "/svg/heart-circle-outline.svg",
        "/svg/heart-circle-sharp.svg",
        "/svg/heart-circle.svg",
        "/svg/heart-dislike-circle-outline.svg",
        "/svg/heart-dislike-circle-sharp.svg",
        "/svg/heart-dislike-circle.svg",
        "/svg/heart-dislike-outline.svg",
        "/svg/heart-dislike-sharp.svg",
        "/svg/heart-dislike.svg",
        "/svg/heart-half-outline.svg",
        "/svg/heart-half-sharp.svg",
        "/svg/heart-half.svg",
        "/svg/heart-outline.svg",
        "/svg/heart-sharp.svg",
        "/svg/heart.svg",
        "/svg/help-buoy-outline.svg",
        "/svg/help-buoy-sharp.svg",
        "/svg/help-buoy.svg",
        "/svg/help-circle-outline.svg",
        "/svg/help-circle-sharp.svg",
        "/svg/help-circle.svg",
        "/svg/help-outline.svg",
        "/svg/help-sharp.svg",
        "/svg/help.svg",
        "/svg/home-outline.svg",
        "/svg/home-sharp.svg",
        "/svg/home.svg",
        "/svg/hourglass-outline.svg",
        "/svg/hourglass-sharp.svg",
        "/svg/hourglass.svg",
        "/svg/ice-cream-outline.svg",
        "/svg/ice-cream-sharp.svg",
        "/svg/ice-cream.svg",
        "/svg/image-outline.svg",
        "/svg/image-sharp.svg",
        "/svg/image.svg",
        "/svg/images-outline.svg",
        "/svg/images-sharp.svg",
        "/svg/images.svg",
        "/svg/infinite-outline.svg",
        "/svg/infinite-sharp.svg",
        "/svg/infinite.svg",
        "/svg/information-circle-outline.svg",
        "/svg/information-circle-sharp.svg",
        "/svg/information-circle.svg",
        "/svg/information-outline.svg",
        "/svg/information-sharp.svg",
        "/svg/information.svg",
        "/svg/invert-mode-outline.svg",
        "/svg/invert-mode-sharp.svg",
        "/svg/invert-mode.svg",
        "/svg/journal-outline.svg",
        "/svg/journal-sharp.svg",
        "/svg/journal.svg",
        "/svg/key-outline.svg",
        "/svg/key-sharp.svg",
        "/svg/key.svg",
        "/svg/keypad-outline.svg",
        "/svg/keypad-sharp.svg",
        "/svg/keypad.svg",
        "/svg/language-outline.svg",
        "/svg/language-sharp.svg",
        "/svg/language.svg",
        "/svg/laptop-outline.svg",
        "/svg/laptop-sharp.svg",
        "/svg/laptop.svg",
        "/svg/layers-outline.svg",
        "/svg/layers-sharp.svg",
        "/svg/layers.svg",
        "/svg/leaf-outline.svg",
        "/svg/leaf-sharp.svg",
        "/svg/leaf.svg",
        "/svg/library-outline.svg",
        "/svg/library-sharp.svg",
        "/svg/library.svg",
        "/svg/link-outline.svg",
        "/svg/link-sharp.svg",
        "/svg/link.svg",
        "/svg/list-circle-outline.svg",
        "/svg/list-circle-sharp.svg",
        "/svg/list-circle.svg",
        "/svg/list-outline.svg",
        "/svg/list-sharp.svg",
        "/svg/list.svg",
        "/svg/locate-outline.svg",
        "/svg/locate-sharp.svg",
        "/svg/locate.svg",
        "/svg/location-outline.svg",
        "/svg/location-sharp.svg",
        "/svg/location.svg",
        "/svg/lock-closed-outline.svg",
        "/svg/lock-closed-sharp.svg",
        "/svg/lock-closed.svg",
        "/svg/lock-open-outline.svg",
        "/svg/lock-open-sharp.svg",
        "/svg/lock-open.svg",
        "/svg/log-in-outline.svg",
        "/svg/log-in-sharp.svg",
        "/svg/log-in.svg",
        "/svg/log-out-outline.svg",
        "/svg/log-out-sharp.svg",
        "/svg/log-out.svg",
        "/svg/logo-alipay.svg",
        "/svg/logo-amazon.svg",
        "/svg/logo-amplify.svg",
        "/svg/logo-android.svg",
        "/svg/logo-angular.svg",
        "/svg/logo-apple-appstore.svg",
        "/svg/logo-apple.svg",
        "/svg/logo-behance.svg",
        "/svg/logo-bitbucket.svg",
        "/svg/logo-bitcoin.svg",
        "/svg/logo-buffer.svg",
        "/svg/logo-capacitor.svg",
        "/svg/logo-chrome.svg",
        "/svg/logo-closed-captioning.svg",
        "/svg/logo-codepen.svg",
        "/svg/logo-css3.svg",
        "/svg/logo-designernews.svg",
        "/svg/logo-deviantart.svg",
        "/svg/logo-discord.svg",
        "/svg/logo-docker.svg",
        "/svg/logo-dribbble.svg",
        "/svg/logo-dropbox.svg",
        "/svg/logo-edge.svg",
        "/svg/logo-electron.svg",
        "/svg/logo-euro.svg",
        "/svg/logo-facebook.svg",
        "/svg/logo-figma.svg",
        "/svg/logo-firebase.svg",
        "/svg/logo-firefox.svg",
        "/svg/logo-flickr.svg",
        "/svg/logo-foursquare.svg",
        "/svg/logo-github.svg",
        "/svg/logo-gitlab.svg",
        "/svg/logo-google-playstore.svg",
        "/svg/logo-google.svg",
        "/svg/logo-hackernews.svg",
        "/svg/logo-html5.svg",
        "/svg/logo-instagram.svg",
        "/svg/logo-ionic.svg",
        "/svg/logo-ionitron.svg",
        "/svg/logo-javascript.svg",
        "/svg/logo-laravel.svg",
        "/svg/logo-linkedin.svg",
        "/svg/logo-markdown.svg",
        "/svg/logo-mastodon.svg",
        "/svg/logo-medium.svg",
        "/svg/logo-no-smoking.svg",
        "/svg/logo-nodejs.svg",
        "/svg/logo-npm.svg",
        "/svg/logo-octocat.svg",
        "/svg/logo-paypal.svg",
        "/svg/logo-pinterest.svg",
        "/svg/logo-playstation.svg",
        "/svg/logo-pwa.svg",
        "/svg/logo-python.svg",
        "/svg/logo-react.svg",
        "/svg/logo-reddit.svg",
        "/svg/logo-rss.svg",
        "/svg/logo-sass.svg",
        "/svg/logo-skype.svg",
        "/svg/logo-slack.svg",
        "/svg/logo-snapchat.svg",
        "/svg/logo-soundcloud.svg",
        "/svg/logo-stackoverflow.svg",
        "/svg/logo-steam.svg",
        "/svg/logo-stencil.svg",
        "/svg/logo-tableau.svg",
        "/svg/logo-tiktok.svg",
        "/svg/logo-tumblr.svg",
        "/svg/logo-tux.svg",
        "/svg/logo-twitch.svg",
        "/svg/logo-twitter.svg",
        "/svg/logo-usd.svg",
        "/svg/logo-venmo.svg",
        "/svg/logo-vercel.svg",
        "/svg/logo-vimeo.svg",
        "/svg/logo-vk.svg",
        "/svg/logo-vue.svg",
        "/svg/logo-web-component.svg",
        "/svg/logo-wechat.svg",
        "/svg/logo-whatsapp.svg",
        "/svg/logo-windows.svg",
        "/svg/logo-wordpress.svg",
        "/svg/logo-xbox.svg",
        "/svg/logo-xing.svg",
        "/svg/logo-yahoo.svg",
        "/svg/logo-yen.svg",
        "/svg/logo-youtube.svg",
        "/svg/magnet-outline.svg",
        "/svg/magnet-sharp.svg",
        "/svg/magnet.svg",
        "/svg/mail-open-outline.svg",
        "/svg/mail-open-sharp.svg",
        "/svg/mail-open.svg",
        "/svg/mail-outline.svg",
        "/svg/mail-sharp.svg",
        "/svg/mail-unread-outline.svg",
        "/svg/mail-unread-sharp.svg",
        "/svg/mail-unread.svg",
        "/svg/mail.svg",
        "/svg/male-female-outline.svg",
        "/svg/male-female-sharp.svg",
        "/svg/male-female.svg",
        "/svg/male-outline.svg",
        "/svg/male-sharp.svg",
        "/svg/male.svg",
        "/svg/man-outline.svg",
        "/svg/man-sharp.svg",
        "/svg/man.svg",
        "/svg/map-outline.svg",
        "/svg/map-sharp.svg",
        "/svg/map.svg",
        "/svg/medal-outline.svg",
        "/svg/medal-sharp.svg",
        "/svg/medal.svg",
        "/svg/medical-outline.svg",
        "/svg/medical-sharp.svg",
        "/svg/medical.svg",
        "/svg/medkit-outline.svg",
        "/svg/medkit-sharp.svg",
        "/svg/medkit.svg",
        "/svg/megaphone-outline.svg",
        "/svg/megaphone-sharp.svg",
        "/svg/megaphone.svg",
        "/svg/menu-outline.svg",
        "/svg/menu-sharp.svg",
        "/svg/menu.svg",
        "/svg/mic-circle-outline.svg",
        "/svg/mic-circle-sharp.svg",
        "/svg/mic-circle.svg",
        "/svg/mic-off-circle-outline.svg",
        "/svg/mic-off-circle-sharp.svg",
        "/svg/mic-off-circle.svg",
        "/svg/mic-off-outline.svg",
        "/svg/mic-off-sharp.svg",
        "/svg/mic-off.svg",
        "/svg/mic-outline.svg",
        "/svg/mic-sharp.svg",
        "/svg/mic.svg",
        "/svg/moon-outline.svg",
        "/svg/moon-sharp.svg",
        "/svg/moon.svg",
        "/svg/move-outline.svg",
        "/svg/move-sharp.svg",
        "/svg/move.svg",
        "/svg/musical-note-outline.svg",
        "/svg/musical-note-sharp.svg",
        "/svg/musical-note.svg",
        "/svg/musical-notes-outline.svg",
        "/svg/musical-notes-sharp.svg",
        "/svg/musical-notes.svg",
        "/svg/navigate-circle-outline.svg",
        "/svg/navigate-circle-sharp.svg",
        "/svg/navigate-circle.svg",
        "/svg/navigate-outline.svg",
        "/svg/navigate-sharp.svg",
        "/svg/navigate.svg",
        "/svg/newspaper-outline.svg",
        "/svg/newspaper-sharp.svg",
        "/svg/newspaper.svg",
        "/svg/notifications-circle-outline.svg",
        "/svg/notifications-circle-sharp.svg",
        "/svg/notifications-circle.svg",
        "/svg/notifications-off-circle-outline.svg",
        "/svg/notifications-off-circle-sharp.svg",
        "/svg/notifications-off-circle.svg",
        "/svg/notifications-off-outline.svg",
        "/svg/notifications-off-sharp.svg",
        "/svg/notifications-off.svg",
        "/svg/notifications-outline.svg",
        "/svg/notifications-sharp.svg",
        "/svg/notifications.svg",
        "/svg/nuclear-outline.svg",
        "/svg/nuclear-sharp.svg",
        "/svg/nuclear.svg",
        "/svg/nutrition-outline.svg",
        "/svg/nutrition-sharp.svg",
        "/svg/nutrition.svg",
        "/svg/open-outline.svg",
        "/svg/open-sharp.svg",
        "/svg/open.svg",
        "/svg/options-outline.svg",
        "/svg/options-sharp.svg",
        "/svg/options.svg",
        "/svg/paper-plane-outline.svg",
        "/svg/paper-plane-sharp.svg",
        "/svg/paper-plane.svg",
        "/svg/partly-sunny-outline.svg",
        "/svg/partly-sunny-sharp.svg",
        "/svg/partly-sunny.svg",
        "/svg/pause-circle-outline.svg",
        "/svg/pause-circle-sharp.svg",
        "/svg/pause-circle.svg",
        "/svg/pause-outline.svg",
        "/svg/pause-sharp.svg",
        "/svg/pause.svg",
        "/svg/paw-outline.svg",
        "/svg/paw-sharp.svg",
        "/svg/paw.svg",
        "/svg/pencil-outline.svg",
        "/svg/pencil-sharp.svg",
        "/svg/pencil.svg",
        "/svg/people-circle-outline.svg",
        "/svg/people-circle-sharp.svg",
        "/svg/people-circle.svg",
        "/svg/people-outline.svg",
        "/svg/people-sharp.svg",
        "/svg/people.svg",
        "/svg/person-add-outline.svg",
        "/svg/person-add-sharp.svg",
        "/svg/person-add.svg",
        "/svg/person-circle-outline.svg",
        "/svg/person-circle-sharp.svg",
        "/svg/person-circle.svg",
        "/svg/person-outline.svg",
        "/svg/person-remove-outline.svg",
        "/svg/person-remove-sharp.svg",
        "/svg/person-remove.svg",
        "/svg/person-sharp.svg",
        "/svg/person.svg",
        "/svg/phone-landscape-outline.svg",
        "/svg/phone-landscape-sharp.svg",
        "/svg/phone-landscape.svg",
        "/svg/phone-portrait-outline.svg",
        "/svg/phone-portrait-sharp.svg",
        "/svg/phone-portrait.svg",
        "/svg/pie-chart-outline.svg",
        "/svg/pie-chart-sharp.svg",
        "/svg/pie-chart.svg",
        "/svg/pin-outline.svg",
        "/svg/pin-sharp.svg",
        "/svg/pin.svg",
        "/svg/pint-outline.svg",
        "/svg/pint-sharp.svg",
        "/svg/pint.svg",
        "/svg/pizza-outline.svg",
        "/svg/pizza-sharp.svg",
        "/svg/pizza.svg",
        "/svg/planet-outline.svg",
        "/svg/planet-sharp.svg",
        "/svg/planet.svg",
        "/svg/play-back-circle-outline.svg",
        "/svg/play-back-circle-sharp.svg",
        "/svg/play-back-circle.svg",
        "/svg/play-back-outline.svg",
        "/svg/play-back-sharp.svg",
        "/svg/play-back.svg",
        "/svg/play-circle-outline.svg",
        "/svg/play-circle-sharp.svg",
        "/svg/play-circle.svg",
        "/svg/play-forward-circle-outline.svg",
        "/svg/play-forward-circle-sharp.svg",
        "/svg/play-forward-circle.svg",
        "/svg/play-forward-outline.svg",
        "/svg/play-forward-sharp.svg",
        "/svg/play-forward.svg",
        "/svg/play-outline.svg",
        "/svg/play-sharp.svg",
        "/svg/play-skip-back-circle-outline.svg",
        "/svg/play-skip-back-circle-sharp.svg",
        "/svg/play-skip-back-circle.svg",
        "/svg/play-skip-back-outline.svg",
        "/svg/play-skip-back-sharp.svg",
        "/svg/play-skip-back.svg",
        "/svg/play-skip-forward-circle-outline.svg",
        "/svg/play-skip-forward-circle-sharp.svg",
        "/svg/play-skip-forward-circle.svg",
        "/svg/play-skip-forward-outline.svg",
        "/svg/play-skip-forward-sharp.svg",
        "/svg/play-skip-forward.svg",
        "/svg/play.svg",
        "/svg/podium-outline.svg",
        "/svg/podium-sharp.svg",
        "/svg/podium.svg",
        "/svg/power-outline.svg",
        "/svg/power-sharp.svg",
        "/svg/power.svg",
        "/svg/pricetag-outline.svg",
        "/svg/pricetag-sharp.svg",
        "/svg/pricetag.svg",
        "/svg/pricetags-outline.svg",
        "/svg/pricetags-sharp.svg",
        "/svg/pricetags.svg",
        "/svg/print-outline.svg",
        "/svg/print-sharp.svg",
        "/svg/print.svg",
        "/svg/pulse-outline.svg",
        "/svg/pulse-sharp.svg",
        "/svg/pulse.svg",
        "/svg/push-outline.svg",
        "/svg/push-sharp.svg",
        "/svg/push.svg",
        "/svg/qr-code-outline.svg",
        "/svg/qr-code-sharp.svg",
        "/svg/qr-code.svg",
        "/svg/radio-button-off-outline.svg",
        "/svg/radio-button-off-sharp.svg",
        "/svg/radio-button-off.svg",
        "/svg/radio-button-on-outline.svg",
        "/svg/radio-button-on-sharp.svg",
        "/svg/radio-button-on.svg",
        "/svg/radio-outline.svg",
        "/svg/radio-sharp.svg",
        "/svg/radio.svg",
        "/svg/rainy-outline.svg",
        "/svg/rainy-sharp.svg",
        "/svg/rainy.svg",
        "/svg/reader-outline.svg",
        "/svg/reader-sharp.svg",
        "/svg/reader.svg",
        "/svg/receipt-outline.svg",
        "/svg/receipt-sharp.svg",
        "/svg/receipt.svg",
        "/svg/recording-outline.svg",
        "/svg/recording-sharp.svg",
        "/svg/recording.svg",
        "/svg/refresh-circle-outline.svg",
        "/svg/refresh-circle-sharp.svg",
        "/svg/refresh-circle.svg",
        "/svg/refresh-outline.svg",
        "/svg/refresh-sharp.svg",
        "/svg/refresh.svg",
        "/svg/reload-circle-outline.svg",
        "/svg/reload-circle-sharp.svg",
        "/svg/reload-circle.svg",
        "/svg/reload-outline.svg",
        "/svg/reload-sharp.svg",
        "/svg/reload.svg",
        "/svg/remove-circle-outline.svg",
        "/svg/remove-circle-sharp.svg",
        "/svg/remove-circle.svg",
        "/svg/remove-outline.svg",
        "/svg/remove-sharp.svg",
        "/svg/remove.svg",
        "/svg/reorder-four-outline.svg",
        "/svg/reorder-four-sharp.svg",
        "/svg/reorder-four.svg",
        "/svg/reorder-three-outline.svg",
        "/svg/reorder-three-sharp.svg",
        "/svg/reorder-three.svg",
        "/svg/reorder-two-outline.svg",
        "/svg/reorder-two-sharp.svg",
        "/svg/reorder-two.svg",
        "/svg/repeat-outline.svg",
        "/svg/repeat-sharp.svg",
        "/svg/repeat.svg",
        "/svg/resize-outline.svg",
        "/svg/resize-sharp.svg",
        "/svg/resize.svg",
        "/svg/restaurant-outline.svg",
        "/svg/restaurant-sharp.svg",
        "/svg/restaurant.svg",
        "/svg/return-down-back-outline.svg",
        "/svg/return-down-back-sharp.svg",
        "/svg/return-down-back.svg",
        "/svg/return-down-forward-outline.svg",
        "/svg/return-down-forward-sharp.svg",
        "/svg/return-down-forward.svg",
        "/svg/return-up-back-outline.svg",
        "/svg/return-up-back-sharp.svg",
        "/svg/return-up-back.svg",
        "/svg/return-up-forward-outline.svg",
        "/svg/return-up-forward-sharp.svg",
        "/svg/return-up-forward.svg",
        "/svg/ribbon-outline.svg",
        "/svg/ribbon-sharp.svg",
        "/svg/ribbon.svg",
        "/svg/rocket-outline.svg",
        "/svg/rocket-sharp.svg",
        "/svg/rocket.svg",
        "/svg/rose-outline.svg",
        "/svg/rose-sharp.svg",
        "/svg/rose.svg",
        "/svg/sad-outline.svg",
        "/svg/sad-sharp.svg",
        "/svg/sad.svg",
        "/svg/save-outline.svg",
        "/svg/save-sharp.svg",
        "/svg/save.svg",
        "/svg/scan-circle-outline.svg",
        "/svg/scan-circle-sharp.svg",
        "/svg/scan-circle.svg",
        "/svg/scan-outline.svg",
        "/svg/scan-sharp.svg",
        "/svg/scan.svg",
        "/svg/school-outline.svg",
        "/svg/school-sharp.svg",
        "/svg/school.svg",
        "/svg/search-circle-outline.svg",
        "/svg/search-circle-sharp.svg",
        "/svg/search-circle.svg",
        "/svg/search-outline.svg",
        "/svg/search-sharp.svg",
        "/svg/search.svg",
        "/svg/send-outline.svg",
        "/svg/send-sharp.svg",
        "/svg/send.svg",
        "/svg/server-outline.svg",
        "/svg/server-sharp.svg",
        "/svg/server.svg",
        "/svg/settings-outline.svg",
        "/svg/settings-sharp.svg",
        "/svg/settings.svg",
        "/svg/shapes-outline.svg",
        "/svg/shapes-sharp.svg",
        "/svg/shapes.svg",
        "/svg/share-outline.svg",
        "/svg/share-sharp.svg",
        "/svg/share-social-outline.svg",
        "/svg/share-social-sharp.svg",
        "/svg/share-social.svg",
        "/svg/share.svg",
        "/svg/shield-checkmark-outline.svg",
        "/svg/shield-checkmark-sharp.svg",
        "/svg/shield-checkmark.svg",
        "/svg/shield-outline.svg",
        "/svg/shield-sharp.svg",
        "/svg/shield.svg",
        "/svg/shirt-outline.svg",
        "/svg/shirt-sharp.svg",
        "/svg/shirt.svg",
        "/svg/shuffle-outline.svg",
        "/svg/shuffle-sharp.svg",
        "/svg/shuffle.svg",
        "/svg/skull-outline.svg",
        "/svg/skull-sharp.svg",
        "/svg/skull.svg",
        "/svg/snow-outline.svg",
        "/svg/snow-sharp.svg",
        "/svg/snow.svg",
        "/svg/speedometer-outline.svg",
        "/svg/speedometer-sharp.svg",
        "/svg/speedometer.svg",
        "/svg/square-outline.svg",
        "/svg/square-sharp.svg",
        "/svg/square.svg",
        "/svg/star-half-outline.svg",
        "/svg/star-half-sharp.svg",
        "/svg/star-half.svg",
        "/svg/star-outline.svg",
        "/svg/star-sharp.svg",
        "/svg/star.svg",
        "/svg/stats-chart-outline.svg",
        "/svg/stats-chart-sharp.svg",
        "/svg/stats-chart.svg",
        "/svg/stop-circle-outline.svg",
        "/svg/stop-circle-sharp.svg",
        "/svg/stop-circle.svg",
        "/svg/stop-outline.svg",
        "/svg/stop-sharp.svg",
        "/svg/stop.svg",
        "/svg/stopwatch-outline.svg",
        "/svg/stopwatch-sharp.svg",
        "/svg/stopwatch.svg",
        "/svg/storefront-outline.svg",
        "/svg/storefront-sharp.svg",
        "/svg/storefront.svg",
        "/svg/subway-outline.svg",
        "/svg/subway-sharp.svg",
        "/svg/subway.svg",
        "/svg/sunny-outline.svg",
        "/svg/sunny-sharp.svg",
        "/svg/sunny.svg",
        "/svg/swap-horizontal-outline.svg",
        "/svg/swap-horizontal-sharp.svg",
        "/svg/swap-horizontal.svg",
        "/svg/swap-vertical-outline.svg",
        "/svg/swap-vertical-sharp.svg",
        "/svg/swap-vertical.svg",
        "/svg/sync-circle-outline.svg",
        "/svg/sync-circle-sharp.svg",
        "/svg/sync-circle.svg",
        "/svg/sync-outline.svg",
        "/svg/sync-sharp.svg",
        "/svg/sync.svg",
        "/svg/tablet-landscape-outline.svg",
        "/svg/tablet-landscape-sharp.svg",
        "/svg/tablet-landscape.svg",
        "/svg/tablet-portrait-outline.svg",
        "/svg/tablet-portrait-sharp.svg",
        "/svg/tablet-portrait.svg",
        "/svg/telescope-outline.svg",
        "/svg/telescope-sharp.svg",
        "/svg/telescope.svg",
        "/svg/tennisball-outline.svg",
        "/svg/tennisball-sharp.svg",
        "/svg/tennisball.svg",
        "/svg/terminal-outline.svg",
        "/svg/terminal-sharp.svg",
        "/svg/terminal.svg",
        "/svg/text-outline.svg",
        "/svg/text-sharp.svg",
        "/svg/text.svg",
        "/svg/thermometer-outline.svg",
        "/svg/thermometer-sharp.svg",
        "/svg/thermometer.svg",
        "/svg/thumbs-down-outline.svg",
        "/svg/thumbs-down-sharp.svg",
        "/svg/thumbs-down.svg",
        "/svg/thumbs-up-outline.svg",
        "/svg/thumbs-up-sharp.svg",
        "/svg/thumbs-up.svg",
        "/svg/thunderstorm-outline.svg",
        "/svg/thunderstorm-sharp.svg",
        "/svg/thunderstorm.svg",
        "/svg/ticket-outline.svg",
        "/svg/ticket-sharp.svg",
        "/svg/ticket.svg",
        "/svg/time-outline.svg",
        "/svg/time-sharp.svg",
        "/svg/time.svg",
        "/svg/timer-outline.svg",
        "/svg/timer-sharp.svg",
        "/svg/timer.svg",
        "/svg/today-outline.svg",
        "/svg/today-sharp.svg",
        "/svg/today.svg",
        "/svg/toggle-outline.svg",
        "/svg/toggle-sharp.svg",
        "/svg/toggle.svg",
        "/svg/trail-sign-outline.svg",
        "/svg/trail-sign-sharp.svg",
        "/svg/trail-sign.svg",
        "/svg/train-outline.svg",
        "/svg/train-sharp.svg",
        "/svg/train.svg",
        "/svg/transgender-outline.svg",
        "/svg/transgender-sharp.svg",
        "/svg/transgender.svg",
        "/svg/trash-bin-outline.svg",
        "/svg/trash-bin-sharp.svg",
        "/svg/trash-bin.svg",
        "/svg/trash-outline.svg",
        "/svg/trash-sharp.svg",
        "/svg/trash.svg",
        "/svg/trending-down-outline.svg",
        "/svg/trending-down-sharp.svg",
        "/svg/trending-down.svg",
        "/svg/trending-up-outline.svg",
        "/svg/trending-up-sharp.svg",
        "/svg/trending-up.svg",
        "/svg/triangle-outline.svg",
        "/svg/triangle-sharp.svg",
        "/svg/triangle.svg",
        "/svg/trophy-outline.svg",
        "/svg/trophy-sharp.svg",
        "/svg/trophy.svg",
        "/svg/tv-outline.svg",
        "/svg/tv-sharp.svg",
        "/svg/tv.svg",
        "/svg/umbrella-outline.svg",
        "/svg/umbrella-sharp.svg",
        "/svg/umbrella.svg",
        "/svg/unlink-outline.svg",
        "/svg/unlink-sharp.svg",
        "/svg/unlink.svg",
        "/svg/videocam-off-outline.svg",
        "/svg/videocam-off-sharp.svg",
        "/svg/videocam-off.svg",
        "/svg/videocam-outline.svg",
        "/svg/videocam-sharp.svg",
        "/svg/videocam.svg",
        "/svg/volume-high-outline.svg",
        "/svg/volume-high-sharp.svg",
        "/svg/volume-high.svg",
        "/svg/volume-low-outline.svg",
        "/svg/volume-low-sharp.svg",
        "/svg/volume-low.svg",
        "/svg/volume-medium-outline.svg",
        "/svg/volume-medium-sharp.svg",
        "/svg/volume-medium.svg",
        "/svg/volume-mute-outline.svg",
        "/svg/volume-mute-sharp.svg",
        "/svg/volume-mute.svg",
        "/svg/volume-off-outline.svg",
        "/svg/volume-off-sharp.svg",
        "/svg/volume-off.svg",
        "/svg/walk-outline.svg",
        "/svg/walk-sharp.svg",
        "/svg/walk.svg",
        "/svg/wallet-outline.svg",
        "/svg/wallet-sharp.svg",
        "/svg/wallet.svg",
        "/svg/warning-outline.svg",
        "/svg/warning-sharp.svg",
        "/svg/warning.svg",
        "/svg/watch-outline.svg",
        "/svg/watch-sharp.svg",
        "/svg/watch.svg",
        "/svg/water-outline.svg",
        "/svg/water-sharp.svg",
        "/svg/water.svg",
        "/svg/wifi-outline.svg",
        "/svg/wifi-sharp.svg",
        "/svg/wifi.svg",
        "/svg/wine-outline.svg",
        "/svg/wine-sharp.svg",
        "/svg/wine.svg",
        "/svg/woman-outline.svg",
        "/svg/woman-sharp.svg",
        "/svg/woman.svg"
      ],
      "patterns": []
    }
digaus commented 3 years ago

@lincolnthree

just specify the specific icons in the ngsw-config

     {
            "name": "assets",
            "installMode": "prefetch",
            "resources": {
                "files": [
                    "/assets/**",
                    "/*.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)",
                    "/svg/menu.svg",
                    "/svg/close-outline.svg",
                    "/svg/information-circle-outline.svg",
                    "/svg/log-out-outline.svg",
                    "/svg/log-in-outline.svg",
                    "/svg/desktop-outline.svg",
                    "/svg/share-outline.svg"

                ]
            },
            "cacheQueryOptions": {
                "ignoreSearch": true
            }
        }
lincolnthree commented 3 years ago

@digaus Thanks. Yes that's right. Good info!

The other side of the issue, however, is that it's very difficult to know which icons are actually used/not used. It's likely a source review and manifest would resolve this, once, but it also makes it very risky and difficult to detect slippage on this -- without some kind of build-level enforcement. You could argue review should be done on each commit anyway, but it's just difficult to catch everything :)

Ideally there really needs to be a compile time error if the icon is not included in the manifest/files.

Any thoughts about how to address that part of it? Appreciated!

zineer commented 3 years ago

Just wanted to leave a note here that I was looking for a similar way to remove the extra svg files and came across https://gist.github.com/nucklehead/b568dc13d01b18b902c524754a7c9cd4. I added it as a script in package.json: "ionic:build:after": "node ./scripts/cleanIcon.js" so it runs automatically after a build. Appears to have done a good job finding the used icons and eliminating the rest.

lincolnthree commented 3 years ago

@zineer Glory! Thanks so much for finding this. I will give it a shot! Looks simple enough and easy to adapt. Something like this, configurable with a value like, "iconPatterns" would be amazing to see as part of the Ionic build process. (For now, this is almost as good!) You're the best.

ptmkenny commented 3 years ago

For reference, this does not seem to be an issue with Ionic React; I use about a dozen ion icons, and when I check the build directory, I only see the SVG I actually imported inlined into the JS, which is what I would expect. This is a stock Ionic React config.

tayambamwanza commented 2 years ago

https://github.com/avmaisak/ngx-bootstrap-icons

I've been using this project for bootstrap icons, might be worth a look.

although granted you have to manually declare which icons will be used, it's better than nothing.

TheBrockEllis commented 2 years ago

I just started a new ionic angular project a few weeks ago. Went to do a production build and manual FTP to the server before worrying about setting up automatic pipeline builds. I noticed that our www/assets/svg folder was FULL of svg files, most of what were not being used. Removing the asset rule in the angular.json file ended up removing all of the ionicons, even the ones that were being used (makes total sense).

It's been a few months, but is zineer's after build hook script posted above still the current best/recommended way to pare down the about of SVGs to ship to production?

tayambamwanza commented 2 years ago

@avmaisak Hey would you be willing to take this on? I love the way your library works maybe could do a pull request?

avmaisak commented 2 years ago

@tayambamwanza may be fork it? )) What did you say))

mirko77 commented 2 years ago

Any updates? @liamdebeasi In Ionic 6 Vue, the vendor bundle still has all the icons, while we are using like 15 of them. We are deploying as PWA, 500KB of icons gzipped is not great.

Screenshot 2022-11-02 at 14 00 59
liamdebeasi commented 2 years ago

@mirko77 Do you have a code reproduction? This issue should not impact Ionic Vue since icons are explicitly imported instead of globally registered.

LennonReid commented 1 year ago

Any updates, @liamdebeasi? I've just completed an update. I upgraded my @ionic/angular from v7.4.1 to v7.5.1, and I also modified all the imports from @ionic/angular to @ionic/angular/standalone. As a result, my app distribution size increased by approximately 1MB. Notably, all the Ionic icons' SVG files have been included in the dist directory as before.

liamdebeasi commented 1 year ago

@LennonReid Did you update your angular.json file to not copy the SVG files? This should be resolved using @ionic/angular/standalone. For those not using Ionic Framework pull from ionicons/components/icon.js instead of ionicons should enable treeshaking.

tayambamwanza commented 1 year ago

@LennonReid Did you update your angular.json file to not copy the SVG files? This should be resolved using @ionic/angular/standalone. For those not using Ionic Framework pull from ionicons/components/icon.js instead of ionicons should enable treeshaking.

I'm going to give this a shot, I planned to use Ionic as my default component library for projects but this issue stopped me, was literally the only reason, if it's fixed I'm so glad, I'll be using Ionic again πŸ˜ŠπŸš€

LennonReid commented 1 year ago

@LennonReid Did you update your angular.json file to not copy the SVG files? This should be resolved using @ionic/angular/standalone. For those not using Ionic Framework pull from ionicons/components/icon.js instead of ionicons should enable treeshaking.

I removed the following lines from my angular.json file:

{
            "glob": "**/*.svg",
            "input": "node_modules/ionicons/dist/ionicons/svg",
            "output": "./svg"
}

However, it appears that no SVG files are being output to my 'dist' directory. Can you spot anything I might be doing incorrectly?

liamdebeasi commented 1 year ago

However, it appears that no SVG files are being output to my 'dist' directory. Can you spot anything I might be doing incorrectly?

That's the correct behavior. That script copies all ~1300 icons to your project output. With the standalone approach only the icons you used are copied over. Additionally, the icon SVG data is embedded in your JavaScript rather than being a separate SVG file, so the icons that are copied over won't be in the same location.

LennonReid commented 1 year ago

Thank you so much, @liamdebeasi. Everything went just as planned, and I achieved the desired outcome by following the steps outlined in the standalone approach guide.

liamdebeasi commented 1 year ago

Glad to hear! I am going to close this since the work required to resolve this has been completed. Ionic Angular Developers should follow https://ionicframework.com/docs/angular/build-options#standalone if they want to move to an architecture that allows for proper tree shaking of icons.