Detailed explanation of the use of css-vars-ponyfill in IE environment (nextjs build)

Detailed explanation of the use of css-vars-ponyfill in IE environment (nextjs build)

css-vars-ponyfill

When using CSS variables to achieve web page skinning, compatibility issues may arise.

In order to solve the compatibility issues of IE, QQ, Baidu browser, etc., css-vars-ponyfill was introduced. However, in IE browser, css-vars-ponyfill performs poorly under nextjs. The main defect is that since the page is rendered on the server side, after the user sees the interface, dynamic theme colors and other styles cannot be rendered quickly, but there is a transition time (css-vars-ponyfill only supports client-side), and there will be an obvious color replacement process, which leads to poor user experience. By reading the source code, we can see that cssVars needs to wait until the browser content is loaded before it is triggered. Otherwise, it will keep listening to the dom's data content event, which will cause experience problems.

Solution

1. Parsing speed

By directly removing the restriction condition of document.readyState !== 'loading' , the browser can parse it and then change the introduction method of css-vars-ponyfill (the old introduction method is to introduce the module in mainjs in nextjs, and then call cssVars() directly. In this way, other unrelated chunks will be parsed before calling the ponyfill script. In order to parse the css variables faster, you need to manually select the insertion position). The changed css-vars-ponyfill finds the location of the css variable (nextjs packages the styles under different components in the header), and then inserts the changed ponyfill into the style for calling. This step is changed in the _document.tsx file rendered on the server.

2. Analysis stability

By manually changing the file parsing location and making relevant changes to the conditional trigger mechanism of the source code, the color rendering speed of the home page has been improved to a certain extent. However, there is still a problem. That is, when a new style chunk is inserted through the route jump interface, effective CSS variable parsing cannot be performed (I have tried to configure the cssVars option to turn on MutationObserver).

Therefore, the solution is to determine the UA so that all routes in browsers such as IE can be redirected through the a tag, triggering the re-parsing and execution of css-ponyfill.

export function browser() {
  const UA = window.navigator.userAgent
  if (UA.includes("qqbrowser")) return "qqbrowser"
  if (UA.includes("baidu")) return "baidu"
  if (UA.includes("Opera")) return "Opera"
  if (UA.includes("Edge")) return "Edge"
  if (UA.includes("MSIE") || (UA.includes("Trident") && UA.includes("rv:11.0")))
    return "IE"
  if (UA.includes("Firefox")) return "Firefox"
  if (UA.includes("Chrome")) return "Chrome"
  if (UA.includes("Safari")) return "Safari"
}
type CommonLinkProps = {
    children: ReactElement
    href?: string
    target?: string
    outerLink?: boolean
    styles?: unknown
}
export default function CustomLink(props: CommonLinkProps) {
  const { children, href, target, as, outerLink, styles = emptyStyles } = props
  const [isIE, setIE] = useState<boolean>(false)
  const cloneEl = (c: ReactElement, props?: any) =>
    React.cloneElement(c, { href: as ?? href, target, ...props })
  useEffect(() => {
    if (["IE", "qqbrowser", "baidu"].includes(browser())) {
      setIE(true)
    }
  }, [])
  function renderLink() {
    if (Children.only(children).type === "a") {
      const node = cloneEl(children as ReactElement)
      return node
    } else {
      let fn: () => void | null = null
      if (outerLink) {
        fn = () => {
          window.open(as ?? href)
        }
      } else {
        fn = () => {
          window.location.href = as ??href
        }
      }
      const node = cloneEl(children as ReactElement, {
        onClick: () => {
          fn()
        },
      })
      return node
    }
  }

  return (
    <>
      {!href ? (
        children
      ) : isIE ? (
        renderLink()
      ) : (
        <Link {...props}>{children}</Link>
      )}
      <style jsx>{styles}</style>
    </>
  )
}

Here, the type of children is ReactElement , rather than ReactNode that is usually supported in slots. This is mainly because we don’t want to consider the situation of directly inserting strings, which will increase the complexity of the problem. Therefore, we directly restrict it at the type level. Fragments are not considered, and no valid Fragments type is found, so it cannot be Omitted in ReactNode. If Fragments are inserted into the first layer, the Link in nextjs cannot jump normally. The possible reason is that it is impossible to bind valid events on Fragments. Currently, Fragments (16.13.1) only support key attributes. I hope it can be optimized later.

Summarize

This is the end of this article about the use of css-vars-ponyfill in the IE environment (nextjs build). For more relevant css-vars-ponyfill usage content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

<<:  Json string + Cookie + localstorage in JS

>>:  Detailed process of FastAPI deployment on Docker

Recommend

Usage of the target attribute of the html tag a

1: If you use the tag <a> to link to a page,...

How to import Excel files into MySQL database

This article shares with you how to import Excel ...

MySQL InnoDB monitoring (system layer, database layer)

MySQL InnoDB monitoring (system layer, database l...

MySQL 8.0.13 download and installation tutorial with pictures and text

MySQL is the most commonly used database. You mus...

Understanding of haslaylout and bfc parsing

1. haslayout and bfc are IE-specific and standard ...

Vue+swiper realizes timeline effect

This article shares the specific code of vue+swip...

Using jQuery to implement the carousel effect

What I bring to you today is to use jQuery to imp...

Examples of clearfix and clear

This article mainly explains how to use clearfix a...

Detailed explanation of how to copy and backup docker container data

Here we take the Jenkins container as an example ...

HTML 5.1 learning: 14 new features and application examples

Preface As we all know, HTML5 belongs to the Worl...

CSS HACK for IE6/IE7/IE8/IE9/FF (summary)

Since I installed the official version of IE8.0, ...

RGB color table collection

RGB color table color English name RGB 16 colors ...