The same best practices that hold good for a normal website hold good for an AEM application as well.
AEM WCM Core components has a working example of using multiple favicons for different viewports.
Refer to the below files from the repo.
Head.html under page component
<template data-sly-template.head="${ @ page }" data-sly-use.headlibRenderer="headlibs.html">
------------------
<!--/* For IE 9 and below. ICO should be 32x32 pixels in size */-->
<sly data-sly-test.faviconIco="${page.favicons['faviconIco']}">
<!--[if IE]><link rel="shortcut icon" href="${faviconIco}"/><![endif]-->
</sly>
<!--/* Firefox, Chrome, Safari, IE 11+ and Opera. 196x196 pixels in size. */-->
<link data-sly-test.faviconPng="${page.favicons['faviconPng']}"
rel="icon" type="image/png" href="${faviconPng}"/>
<link data-sly-test="${!faviconPng && faviconIco}"
rel="icon" href="${faviconIco}"/>
<link data-sly-test.touchIcon60="${page.favicons['touchIcon60']}"
rel="apple-touch-icon" sizes="60x60" href="${touchIcon60}"/>
<link data-sly-test.touchIcon76="${page.favicons['touchIcon76']}"
rel="apple-touch-icon" sizes="76x76" href="${touchIcon76}"/>
<link data-sly-test.touchIcon120="${page.favicons['touchIcon120']}"
rel="apple-touch-icon" sizes="120x120" href="${touchIcon120}"/>
<link data-sly-test.touchIcon152="${page.favicons['touchIcon152']}"
rel="apple-touch-icon" sizes="152x152" href="${touchIcon152}"/>
</template>
PageImpl.java
protected void loadFavicons(String designPath) {
favicons.put(PN_FAVICON_ICO, getFaviconPath(designPath, FN_FAVICON_ICO));
favicons.put(PN_FAVICON_PNG, getFaviconPath(designPath, FN_FAVICON_PNG));
favicons.put(PN_TOUCH_ICON_120, getFaviconPath(designPath, FN_TOUCH_ICON_120));
favicons.put(PN_TOUCH_ICON_152, getFaviconPath(designPath, FN_TOUCH_ICON_152));
favicons.put(PN_TOUCH_ICON_60, getFaviconPath(designPath, FN_TOUCH_ICON_60));
favicons.put(PN_TOUCH_ICON_76, getFaviconPath(designPath, FN_TOUCH_ICON_76));
}
For better understanding of favicon best practices -