Description
Say our team is maintaining an icon base using iconfont and we are using the icon with Symbol like this
So, we would get a script URL whose content is like this
!(function (s) {
var c,
n =
'<svg><symbol id="icon-arrow" viewBox="0 0 1024 1024"></symbol></svg>'
l = (c = document.getElementsByTagName("script"))[
c.length - 1
].getAttribute("data-injectcss");
if (l && !s.__iconfont__svg__cssinject__) {
s.__iconfont__svg__cssinject__ = !0;
try {
document.write(
"<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>"
);
} catch (c) {
console && console.log(c);
}
}
!(function (c) {
if (document.addEventListener)
if (~["complete", "loaded", "interactive"].indexOf(document.readyState))
setTimeout(c, 0);
else {
var l = function () {
document.removeEventListener("DOMContentLoaded", l, !1), c();
};
document.addEventListener("DOMContentLoaded", l, !1);
}
else
document.attachEvent &&
((t = c),
(o = s.document),
(e = !1),
(i = function () {
e || ((e = !0), t());
}),
(n = function () {
try {
o.documentElement.doScroll("left");
} catch (c) {
return void setTimeout(n, 50);
}
i();
})(),
(o.onreadystatechange = function () {
"complete" == o.readyState && ((o.onreadystatechange = null), i());
}));
var t, o, e, i, n;
})(function () {
var c, l, t, o, e, i;
((c = document.createElement("div")).innerHTML = n),
(n = null),
(l = c.getElementsByTagName("svg")[0]) &&
(l.setAttribute("aria-hidden", "true"),
(l.style.position = "absolute"),
(l.style.width = 0),
(l.style.height = 0),
(l.style.overflow = "hidden"),
(t = l),
(o = document.body).firstChild
? ((e = t), (i = o.firstChild).parentNode.insertBefore(e, i))
: o.appendChild(t));
});
})(window);
And when we are using it the code would be like
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-arrow"></use>
</svg>
Or we can encapsulate this component further. Finally, we are using it like
<svg-icon icon-name="icon-arrow"></svg-icon>
As you can see, the size of the script is determined by how many icons we have. If we have a big icon base, the icon code would be very large. For example, currently, we only have one icon called icon-arrow
the icon code is
var c,
n =
'<svg><symbol id="icon-arrow" viewBox="0 0 1024 1024"></symbol></svg>'
If we have 100 icons whose names are like icon-arrow1
, icon-arrow2
......until icon-arrow100
, the icon code would be like
var c,
n =
'<svg><symbol id="icon-arrow" viewBox="0 0 1024 1024"></symbol><symbol id="icon-arrow1" viewBox="0 0 1024 1024"></symbol><symbol id="icon-arrow2" viewBox="0 0 1024 1024">...remaining 97 icons code...</symbol><symbol id="icon-arrow100" viewBox="0 0 1024 1024"></symbol></svg>'
The gzipped file size would be more than 50kB. In the cases that we just need one or a few icons, the size of the script would be a waste and might hurt performance. So here are my thoughts.
Thoughts
Say we have a loader, it can read and analyze our source code. It might be possible to know how many icons were really used in our project and finally remove the unused icon code to reduce the size of the script. However, there might exist some situations we need to handle carefully.
Dynamic Icon Name
In this scenery, the source code would be like
<svg-icon icon-name="variable"></svg-icon>
It means that we won't be able to know what the real icon-name is before the code runs. However, we could enhance our implementation of svg-icon
. For example, support a prop like icon-names
to allow developers to pass the possible icon names. The demo code would be
<svg-icon icon-name="variable" icon-names="['icon-alert','icon-loading']"></svg-icon>
Unknow Scenerys
If the loader meets any scenery it doesn't know, it can give up the tree shake function and output the original file content or throw an error to tell the developers.
Activity