説明
There are a couple of issues with the current icon approach used by Ionic when used in a production application.
Performance
Icons are "all or nothing" in the application. A typical app might use 5-20 icons but the build process results in 700 icons with a total size of almost 3mb in the svg folder in the build output.
The service worker pre-cache manifest includes all of these icons (2800 lines of code) even if you only use a single icon. The service worker also loads all of these icons into the cache (3mb) This uses network traffic, blocks other loading, and uses limited available local storage space.
Lazy loading
Icons are lazy loaded as individual files when it would sometimes be faster to inline them into component files. I have noticed that the stencil site project uses inline svg to help with this. If an icon is only used by a single component then it results in an extra round trip to the server.
Cache headers
Cache headers are difficult to specify for icon content. Javascript and css uses hash versions in the file names so that it possible to use "cache forever" headers on the content and know that old versions will be replaced. This does not work with icons. If "cache forever" is used then the icons can never be updated. If "cache for x days" is used then there will be lots of round trips to check for new versions even though the icons are very unlikely to change.
Alternate approach
A potential alternate approach would be to use standard js imports for the content.
For example:
// ionic/icons
export const svgAirplane = '<svg xmlns="http://www.w3.org/2000/svg" ... ';
export const svgAlarm = '<svg xmlns="http://www.w3.org/2000/svg" ... ';
// etc.
// my-component.tsx
import { svgAlarm } from '@ionic/icons';
import { myIcon } from './my-icon';
render() {
return (
<div>
<ion-icon icon={svgAlarm} />;
<ion-icon icon={myIcon} />;
</div>
);
}
Some of the benefits of this approach include:
- Only icons that are used get built into the app.
- Icons get inlined into components or chunks using the standard build process.
- Inline icons are displayed synchronously for faster initial display.
- "Cache forever" can be used because all file references are versioned already.
- Custom icons can be used if
<ion-icon>accepts svg vs. name.
Some potential issues with this approach:
- How to handle mode specific icons