I would suggest to do dynamic import on each page, for each component and utility instead of making components global. By doing so Next.js will create a small chunks or "pages" without any unused components.
If you load components globally, every page would increase in size but actually not use these components or utilities. It defeats a purpose of code-splitting.
It breaks modularity of your code, because components/pages (modules) will depend on some global utilities implicitly.
If you have too many imports in your component or page, probably, it's a sign to encapsulate that extra functionality by extracting it to it's own component.
Controversially, you could try to add global utilities in Custom "App"
For example, you could pass a React component to all Next.js pages via props of custom App.
_app.js
import Icon from '../components/Icon';
export default function MyApp({ Component, pageProps }) {
return <Component {...pageProps} icon={Icon} />
}
As all pages are instancing from the App, every page would have this component in the props.
index.js
const Home = props => (
<div>
<props.icon><props.icon/>
</div>
);
If you have many components you could group them into list and assign to a single prop, so you can use it like:
index.js
const Home = props => (
<div>
<props.components.icon/>
<props.components.anotherIcon/>
</div>
);
On a side note, it's suggested to use getStaticProps and getServerSideProps for pages instead of getInitialProps since Next.js 9.3.
Suggested reading:
Next.js Data fetching (getInitialProps)
React.js Code-Splitting