Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tree Shake for Iconfont Symbol #120

Open
xianshenglu opened this issue Dec 12, 2020 · 0 comments
Open

Tree Shake for Iconfont Symbol #120

xianshenglu opened this issue Dec 12, 2020 · 0 comments
Labels
todo Next thing to do

Comments

@xianshenglu
Copy link
Owner

Say our team is maintaining an icon base using iconfont and we are using the icon with Symbol like this

image

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.

@xianshenglu xianshenglu added the todo Next thing to do label Dec 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
todo Next thing to do
Projects
None yet
Development

No branches or pull requests

1 participant