Giter VIP home page Giter VIP logo

react-lite's Introduction

react-lite

Travis npm Join the chat at https://gitter.im/Lucifier129/react-lite

Introduction

react-lite is an implementation of React that optimizes for small script size.

Note: react-lite dose not support React v16.x now.

Size Comparison

Framework Version Minified Size
Ember 2.2.0 446kb
Polymer 1.0.6 183kb
Angular 1.4.8 148kb
React 0.14.3 136kb
Web Components Polyfill 0.7.19 118kb
Riot 2.3.11 20kb
React-lite 0.15.6 25kb
preact + preact-compat 8.2.1 5kb

React-lite supports the core APIs of React, such as Virtual DOM, intended as a drop-in replacement for React, when you don't need server-side rendering in browser(no ReactDOM.renderToString & ReactDOM.renderToStaticMarkup).

Usage

If you are using webpack, it's so easy to use react-lite, just config alias in webpack.config.js:

// webpack.config.js
{
    resolve: {
        alias: {
            'react': 'react-lite',
            'react-dom': 'react-lite'
        }
    }
}

Note: feel free to try react-lite, if something happen and we can't fix it in time, then use regular react instead.

Installation

You can install react-lite from npm:

npm install react-lite --save

Browser compatibility

supports IE9+ / ES5 enviroment

Documentation

learn react-lite from React official documentation

What can react-lite do?

just the same as what react does, see some demos below(I just add the alias to webpack.config.js, no need to do anything else):

React-lite vs React

via react-lite:

  • all of React.PropTypes method is no-op(empty function)
  • use React in server side rendering, and use React-lite in browser
    • react-lite will replace the dom tree with new dom tree
    • you had better avoid script|head|link tag in client side
  • can not use react-dev-tool inspect react-lite, should switch to regular react for debugging
  • react-lite only works with a JSX toolchain(issue)
  • unlike react, event object in react-lite is always persistent, and event.persist is set as no-op to avoid throwing error.
  • react-lite can't work with react-tap-event-plugin, please use fastclick instead. or add alias 'react-tap-event-plugin': 'react-lite/lib/react-tap-event-plugin', just like here
  • can't work with transform-react-inline-elements, you will get a bundle include both react and react-lite.
  • react-lite just follow the best practice of React.

Test

react-lite reuses react's unitest(170), you can see them in __test__, and run the tests with:

npm test

License: MIT (See LICENSE file for details)

react-lite's People

Contributors

amuzalevskiy avatar beholderrk avatar bjarneo avatar cllu avatar creeperyang avatar deanius avatar gerhut avatar gitter-badger avatar haroenv avatar jpdevries avatar lucifier129 avatar matthewoates avatar mindreframer avatar nathancahill avatar pconerly avatar wub avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-lite's Issues

vchild.initTree is undefined

image

It breaks when an Object appears

// src/virtual-dom.js
    initTree: function initTree(parentNode) {
        var type = this.type;
        var props = this.props;

        var node = this.node = createElement$1(type, props);
        this.eachChildren(function (vchild) {

            console.log(vchild)   // added
            vchild.initTree(node);
        });
        appendNode(parentNode, node);
        this.attachRef();
    },

Is there some way of forcing peer dependencies to react-lite?

So, I really like this project and use it in production on several projects. One problem I run into over and over again has to do with peer deps. I'll pull an npm package into my project, eg this React lightbox component, and it ends up forcing regular React to be bundled instead of react-lite due to peer deps.

Yes I could go in and change the peer deps on each package, but that defeats the purpose of a package manager. I'm using browserify by the way, but would gladly switch to webpack if it makes this easier. Is anyone aware of a good way to force peer deps?

Issues with replaceChild + solution

I open a new ticket for this one. As mentioned replaceChild can be read-only.
I was looking into your code, and figured out how to fix this. My solution is then also related to
performance issues.

The solution:

In each prototype - stateless, component etc, you add this in the top:

this.element = null

In the init section where you create , change to

* node = this.element = ....*

And then when you do a diff / update, you do this:

* newElement.element = this.element*

Got it?

So then when it comes to destroy, you do this

this.element.parentNode.replaceChild(this.element, newElement.element)

In this solution you will not to do a typeof to check if its a function anymore. Will give you some better performance :)

Great work with react-lite!

Doesn't support react-portal

It doesn't work with react-portal. Just pointing out, close it if there's no work around or it isn't suppose to work.

Error:

ERROR in ./~/react-portal/portal.js
[0] Module not found: Error: Cannot resolve module 'react-lite/lib/CSSPropertyOperations' in /Users/project/node_modules/react-portal

Document where this repo diverges from regular ReactJS

Hey, great project!

I'm just about to start reading through the source to figure out exactly what the tradeoffs are (beyond losing out on server-side rendering). This definitely looks like it could be a sane alternative to the core library, especially for smaller projects, but it would be nice to know up front just what the differences are so people don't run into a wall down the road.

That is unless the only difference is the loss of renderToString/renderToStaticMarkup, which I find doubtful, but it'd be nice to know for sure straight from the documentation.

Thanks!

Failing reordering

Comparing react-lite to React, I can't see any use of keys when I did a quick search through your source code. React uses keys to sort and re-order keyed-nodes.
I notice however that you have a silly implementation of something that suppose to be reordering, but far far from what React has and use.

If this is a small "copy" of React, why not follow what React does and implement a correct reordering?

DOM nodes don't have focus

React have a feture to keep track on DOM nodes, and keep them in focus during update. You don't have this.

document.activeElement;

Any plans to copy React on this one?

filesize clarification

Neat project!

Is the filesize in the readme after compression + gzip? could you clarify that and potentially compare directly with vanilla React?

Thanks!

lot of bugs

It seems that whatever I try to do with your code, I ran into errors, bugs or strange behaviour.
Obviously this code is at a very early stage and not ready for production.

  • TypeError: Failed to execute 'replaceChild' on 'Node': parameter 2 is not of type 'Node'.
  • TypeError: Cannot read property 'childNodes' of null
  • TypeError: Cannot read property 'tagName' of null

This is just a few errors I get all the time. And this is related till how you are dealing with the children, the fact you are not removing any children etc.

In your velem and the destroy function. Seems sometimes it can't find the children it should unmount. Sometimes 1 or more of the children are undefined or null.

And a lot more.

I suggest try to copy some of the stuff from Virtual DOM as I have seen you tried in the beginning, but changed from that path. They are also following React and doesnt have this errors.

React-lite is a good attempt, but not ready yet. For now I got enough because of this and performance so I move away to better solutions.

Maybe one day in the future I will check back on this repo

missing removeEventListener

I noticed that you are missing an important feature - to remove events from the DOM.A listener should be cleaned up when you destroy a node, and also on the nodes children.

You find it in React if you look at the EventListener object..

remove: function () {
          target.removeEventListener(eventType, callback, false);
        }

findDOMNode issue with various animation libraries

Hi!
version: 0.15.13

I'm having trouble using react-lite alongside animation libraries.

when the component tries to transition, I get:
Uncaught Invariant Violation: findDOMNode was called on an unmounted component.

I've had the same error with both rc-animate and velocity-react.

Both work fine w/ the same code on regular react. Any ideas?

Thanks!

context bug in forceUpdate

The context will be assigned to an empty object when calling forceUpdate.

I have found some wried codes which may be the bug's source, on the 750th line of react-lite.common.js:

var nextContext = $cache.context || {};

After simply changing it to the below, the bug seems to be fixed:

var nextContext = $cache.context || context;

Maybe I should give a PR? to master? or other branchs?

Use with react-worker-dom ?

instead using react.render can we use ReactDOM default renderer... for initial render instead use it inside react tree.. or use it as aliases ?
eg: eact-worker-dom and use react lite to work too...

import React from 'react';
import reactDOM from 'react-worker-dom'; // Instead of using react-dom
reactDOM.render(new Worker('worker.js'), document.getElementById('container'));

many clojurescript React wrapper also use ReactDOM..

Bump version to 15.0

React changes their versioning scheme and now they are at 15.0. It would be nice if we can keep in sync with their version numbers.

Boolean false props not handled the same as React

Using react-bootstrap, attributes are being added to the rendered components that are not present with React. For example, here is the rendered result of a react-bootstrap Button with default props:

<a bsstyle="default" bsclass="btn" active="false" block="false" disabled="false" navitem="false" navdropdown="false" href="/accounts/users/add" class="btn btn-default" role="button">Add New User</a>

All the false attributes actually shouldn't be there.

Horrible performance

Hi! I ran the vdom benchmark, and I have to state that the performance is horrible. Any plans to fix this shortly? Else, a very great concept. But there are so many vdom libraries out there that have better performance.

SVG elements not showing

When using react-icons, it appears svg elements lose attribute styles. This is is a screenshot in a working dev environment
screen shot 2016-02-07 at 4 13 25 pm

and a screenshot of a production build using react-lite where the svg does not show
screen shot 2016-02-07 at 4 13 27 pm

One thing I noticed is the attributes lose their camel case in the dom. I tested a production build using react and svg elements display normally. Any help to get svgs showing would be appreciated!

this.refs sometimes equals to null

  render() {
    return (
      <img className="avatar-one" ref="img"
        onLoad={()=>{
          console.log('onload this.refs', this.refs)
        }}
        onError={()=>{
          console.log('onerror this.refs', this.refs)
        }} />
    )
  }

Hey @Lucifier129
In react-lite, I found that this.refs sometimes equals to null, called in onLoad/onError of <img> tag.
The probability is very small, but I can always reproduce it by very frequent rendering.
It causes a bug in my app.
And when I try the regular React, it's fine.

Why does function returned from getEventHandler prevent from propagating event?

I have a question about react-lite's event system. Why does function returned from getEventHandler prevent from propagating native event?

    var getEventHandler = function getEventHandler(handleEvent) {
        handleEvent = eventHandlerWrapper(handleEvent);
        return function (e) {
            e.stopPropagation(); // This makes some side effect.
            e.nativeEvent = e;
            return handleEvent.call(this, e);
        };
    };

I had attached native click event listener on document.body, but because of it, my event listener was never called. React doesn't do like that.

sort and reorder children like React 0.14 / 15

I noticed that many important features for dealing with children is not adopted into React lite. E.g. insertAt(), a function React uses for children.

Plan to implement it?

React now also uses optimizations for Edge, when they deal with children. Added in React 15. This is not included either.

And you are not removing text nodes on diff. If nodeA have text and nodeB doesn't. nodeB will get undefined as text. In react this node are removed and reordered.

So any plans for a proper children diff algorithm ?

This is not a virtual DOM - touching DOM too much!

I just figured out that this is not a virtual DOM. You are touching DOM too much, both on creation and update! That's why you get your horrible performance!

One example is found in the velem prototype where you do an update. For children you are calling childNodes on a real DOM node!! An this happen on each update.

You take this childnodes and iterate over it - more expensive - BEFORE you update the node with it.

How many times you think you are touching the real DOM? Too many.

You should use the vdom object for this.

A lot of different places in your code you are doing this - touching DOM where you shouldn't.

I just compared with React. They are not doing it the same way as you are doing it!

To get the childNodes length in a virtual DOM, just count how many children there is on the vdom object without touching the DOM.

stopPropagation and event delegation

const Example = props =>
  <div onClick={event => console.log('outer')}>
    <span onClick={event => {event.stopPropagation(); console.log('inner');}} />
  </div>;

This logs first inner and then outer, same result with event.stopImmediatePropagation().

I assume this is because of the event delegation, as there is only on event handler at document per app and event, so the native stopImmediatePropagation won't work, because there are no other event listeners to cancel.

How can I prevent events from propagating with react-lite?

webpack alias example should be clearer

Had to look up webpack documentation for this, But I think resolve key should be stated in example.

// webpack.config.js
{
    resolve: {
        alias: {
            'react': 'react-lite',
            'react-dom': 'react-lite'
        }
    }
}

How did you implement it?

Did you copy most of the implementation details from React or created your own virtual-dom implementation?

Great work by the way!

binding event inside onClick prop (inconsistent with react)

<div className="op-btn" onClick={()=>{
                alert(1)
                window.addEventListener('click', () => {
                  alert(2)
                })

                // this.refs.filePanel.toggle()
              }}>发送文件</div>

Hello, here is one more difference I found between react and react-lite.
In react, both 1 and 2 are alerted, while in react-lite, only 1 is alerted.
In my case, I have to wrap the second binding with a setTimeout to make it work in react.
Yes, in this case, the result of react-lite is expected.
But there is such an inconsistency to be noticed ;)

component update clears innerHTML?

<Editor ref="edit" id="editor" className="edit"
              style={{
                fontFamily: fields.fontFamily.value,
                fontSize: fields.fontSize.value,
                fontWeight: fields.fontBold.value ? 'bold' : 'normal',
                color: fields.fontColor.value,
              }}
              onKeyDown={(e)=>this.onKeyDown(e)}
              onInput={(e)=>this.onInput(e)}
              dangerouslySetInnerHTML={{__html: currConver.editor}} />

It seems the innerHTML clears when one of the css style updates.
When I switch back to react, it works.
Is it a bug of react-lite?

Tried to use it with react-bootstrap

I am not sure if it's my setup. However I got an issue at this line in react-bootstrap:
var version = _react2['default'].version.split('.').map(parseFloat);
Seems the react object isn't populated with the version.

(Error was,
Uncaught TypeError: Cannot read property 'split' of undefined
)

component data on DOM node slows down

Hi. I notice you are storing id and relevant component data on the DOM node itself. Any reason for this? It's a major slow down. Better is to create a virtual instance and transfer the instance on update.
Comparing to React, that is how they do it, plus they use the owner that you are missing.

How to enable production mode?

Does react-lite have a dev and production mode like React?

With Webpack I use this:

new webpack.DefinePlugin({
  "process.env": { 
     NODE_ENV: JSON.stringify("production") 
   }
})

Does this also work with react-lite?

Cannot set property 'parentContext' of undefined

ReactDOM.render(<MyComponent />, container)

get error:

Uncaught TypeError: Cannot set property 'parentContext' of undefined
function initVcomponent(vcomponent, parentContext, namespaceURI) {
        var Component = vcomponent.type;
        var props = vcomponent.props;
        var uid = vcomponent.uid;

        var componentContext = getContextByTypes(parentContext, Component.contextTypes);
        var component = new Component(props, componentContext);
        var updater = component.$updater;
        var cache = component.$cache;
            // cache is undefined!
        cache.parentContext = parentContext;

can not work with react-router

工兄弟, 我已经尽量简化了重现问题步骤, 如附件:

  1. npm install
  2. npm start

注释掉:
resolve: {
alias: {
'react': 'react-lite',
'react-dom': 'react-lite'
}
}
成功
没有注释掉就失败

请点解, 等待您的回复
gyj.zip

deprecated features

React have either deprecated or removed a lot of fetures in the upcomming React 15, that you still are using in your code. Plans to remove them?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.