react-tweet icon indicating copy to clipboard operation
react-tweet copied to clipboard

CSS being loaded when `react-tweet` isn't on the page

Open JamesSingleton opened this issue 2 years ago • 2 comments

I was recently looking at some page speed insights for my website and noticed that I was getting Avoid chaining critical requests https://pagespeed.web.dev/analysis/https-www-redshirtsports-xyz-chicago-states-case-for-the-nec/rz9c7fcabb?form_factor=mobile which is basically adding almost 3 seconds to my load time

Screenshot 2023-11-29 at 1 49 39 PM

The first one is for tailwindcss but I noticed the second and 3rd are for react-tweet.

  • https://www.redshirtsports.xyz/_next/static/css/24c20da29490e307.css
    • This contains some font code but other than that it's all react-tweet stuff
  • https://www.redshirtsports.xyz/_next/static/css/3980d4e4036775b6.css

If you go to the URL being tested, you can see there is no tweet being rendered, so not sure why that CSS is being added.

I use react-tweet in my custom portable text component for Sanity. Could it be that just because it's a possibility that it gets added that Next is adding this CSS?

import Image from 'next/image'
import {
  PortableText,
  PortableTextComponents,
  PortableTextMarkComponentProps,
} from '@portabletext/react'
import { PortableTextBlock } from 'sanity'
import { Tweet } from 'react-tweet'

import type { TwitterComponents } from 'react-tweet'


const TweetComponents: TwitterComponents = {
  AvatarImg: (props) => <Image {...props} alt={props.alt} />,
  MediaImg: (props) => <Image {...props} alt={props.alt} fill unoptimized />,
}

export function CustomPortableText({
  paragraphClasses,
  value,
}: {
  paragraphClasses?: string
  value: PortableTextBlock[]
}) {
  const components: PortableTextComponents = {
    types: {
      twitter: ({ value }) => {
        return (
          <div className="not-prose flex items-center justify-center">
            <Tweet id={value.id} components={TweetComponents} />
          </div>
        )
      },
    },
  }

  return <PortableText components={components} value={value} />
}

JamesSingleton avatar Nov 29 '23 20:11 JamesSingleton

Could it be that just because it's a possibility that it gets added that Next is adding this CSS?

Yes. If you're importing the CustomPortableText somewhere and using it in your app then the CSS of react-tweet is being added to your app. To avoid this you can use next/dynamic.

which is basically adding almost 3 seconds to my load time

This is not true. The combined CSS size for react-tweet there is not higher than 8kb according to that. HTTP/2 requests are also ran in parallel and they'll finish quite quickly. I can investigate into why it is two requests and not one but in any case it's not adding 3 seconds of load time.

The resource being high priority is understandable because Next.js doesn't have a way of knowing at build time that you're not rendering a tweet so it considers the CSS of the component to be a high priority resource (because if you do load a tweet, its CSS must be there).

lfades avatar Dec 17 '23 03:12 lfades

@lfades would that look like this?

const Tweet = dynamic(() => import('react-tweet').then((module) => module.Tweet), {
  ssr: false,
})

JamesSingleton avatar Dec 18 '23 15:12 JamesSingleton

Revisiting this after a conversation with @leerob but basically I have a components/common/index.ts file. And then I would do something like

import { ArticleCard, Date, ImageComponent } from '@/components/common'

However, that index.ts also included an import for my <CustomPortableText /> which includes react-tweet. And that is why the react-tweet css was being included.

JamesSingleton avatar Aug 04 '24 23:08 JamesSingleton