npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ts-sfc-plugin

v0.0.4

Published

A plugin for optimizing stateless component in React(tsx).

Downloads

3

Readme

Codacy grade npm Coveralls github branch CircleCI branch GitHub license

ts-sfc-plugin

A plugin for optimizing stateless component of React (tsx)

Why

React functional component(SFC) is easy to use and help to reduce code size significantly, but sometimes people might have been some misunderstanding about its perfomance. Usually, we think functional components would avoid some overheads like mounting / unmounting / lifecycle checking and memory allocations, but in fact, there're no special optimizations currently (but after react 16 was released, sfc is indeed faster than before).

Fortunately SFC just function in react world, if we do care about performance in production there're still a way to improve and this plugin here come to simplify these situation.

const code1 = (
  <div>
    <Avatar />
  </div>
)

const code2 = (
  <div>
    { Avatar() }
  </div>
)

As we cannot recognize if the component is functional, we have to use an anotation to tag the expression:

<Avatar sfc />
// Plugin use `sfc` as identifier by default, but you can pass an option to override it.

How to use

webpack

  module: {
    rules: [
      {
        test: /\.(jsx|tsx|js|ts)$/,
        loader: 'ts-loader',
        options: {
          transpileOnly: true,
          getCustomTransformers: () => ({
            before: [sfcPlugin()],
          }),
          compilerOptions: {
            module: 'esnext',
          },
        },
        exclude: /node_modules/,
      }
    ],
  }

code

import React from 'react'

export const Avatar = ({ name }) => {
  return (
    <div>
      <img src=... />
      <span>{ name }</span>
    </div>
  )
}
import React from 'react'
import { Avatar } from './avatar.component'

export class App extends React.PureComponent {
  render() {
    return (
      <div>
        <Avatar name={ 'hello world' } sfc />
      </div>
    )
  }
}

option

sfcPlugin(option?: Option)

interface Option {
  pragma?: string
  mode?: 1 | 2
}

Deopt

| Reason | Deopt (mode 1) | Deopt (mode 2) |--|--|--| | spread operator | true | false | prop: key | true | false

Considering we transform the code from tsx to native function-call which means the additional vd-layer will be eliminatd, and the effects of key will be removed as well.

// before

const Message = () => <div>bravo</div>

export class App extends React.PureComponent {
  render() {
    return <Message key={ 1 } />
  }
}
// after

const Message = () => <div>bravo</div>

export class App extends React.PureComponent {
  render() {
    // won't get benefit from prop: `key`
    return Message()
  }
}

Notice

Unlike @babel/plugin-transform-react-inline-elements, we won't take ref into account because of this plugin will be applied to typescript only.

const Message = () => <div>bravo</div>

export class App extends React.PureComponent {
  render() {
    // ERROR: this is not type-safe
    // { ref: any } is not assignable to IntrinsicAttributes
    return <Message ref={ ... } />
  }
}

Defect

The following code is recommanded:

<Avatar sfc>
// enable rule: `jsx-boolean-value` in tslint.json

using declaration merging in global .d.ts

import React from 'react'

declare module 'react' {
  namespace JSX {
    interface IntrinsicAttributes extends React.Attributes {
      sfc?: boolean
    }
  }
}

Exception

code like the usage will not work, because the plugin does not include any runtime type checking.

const component = <Avatar sfc={ this.props.flag } />

Benchmark

React 16.4, <Dot />, 50 times, MacBook Pro (Retina, 13-inch, Early 2013)

| Classical | Functional | Direct-call | Auto-transform | |--|--|--|--| | 660ms | 408ms | 226ms | 229ms |

Refs

scu vs sfc

45% faster react functional components now