-
Notifications
You must be signed in to change notification settings - Fork 184
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
DISCUSSION: Feature ideas for react-server
& react-server-cli
#50
Comments
There are a couple things in this list that get me excited. As you may expect they're around HTTP/2, Bundling, and CSS. However, my hunch is that we should carefully consider the order in which we take a look at a couple of these. Heres my two cents: Port to webpack 2 with tree shaking
Add support for HTTP/2 with server push
Allow RootElements to each have their own CSS
|
Thanks for the feedback and enthusiasm, @kcjonson! A few unprioritized reactions:
I think you probably already know this, but tree shaking goes one step further than linting. For example, right now if you code import { Link } from "react-server" you import everything from react-server (~85KB gzipped) into your codebase, even if you are linting. With tree-shaking, you import just
I personally don't think it makes a lot of sense, no. While webpack 2 is still in beta, I think it's an interesting research project, but I probably wouldn't worry too much about its effect on other stuff. Depending on unreleased open source versions is a dangerous game.
I don't know, and I think it's an empirical question. I did some experimentation with HTTP/2 in Apache in January to see how unbundling would affect a test page, and the results were pretty terrible when large numbers of JS files were unbundled. I don't know what caused my results, though; it could have been HTTP/2 implementation immaturity, bad default settings, increase in size due to gzip inefficiencies when unbundled, the absence of server push in Apache, or something else entirely. Khan Academy wrote a blog post about HTTP/2 unbundling slowing them down, but it's a deeply unsatisfying post from a technical explanation standpoint. Basically, I think we'd have to experiment with differing levels of bundling and see how browsers respond.
Agreed 100% on both counts.
Short answer is that I have no idea. To be clear, I'm not even sure this task is possible with webpack's current feature set. All I'm sure of is that it would require some webpack wizardry combined with some changes to the Page API. To be frank, I think that RootElements having their own CSS is an interesting feature, but it doesn't seem nearly as important to me as some other more fundamental perf optimizations (e.g. far-future expiration) or smoothing the dev rampup experience (e.g. routes file complexity, requirement to have routes file for simple sites, doc around data loading). |
Another Q, @kcjonson: do you have any feelings about things like CSS Modules or PostCSS support? |
Replace superagent with fetch I also don't quite understand this:
We currently just have pages Port to webpack 2 with tree shaking Add support for HTTP/2 with server push Long-term caching of static assets Port the react-server tests to use react-server-cli Simplify the use of routr Explore using react-router for routing instead of routr Add more documentation and example projects about how to do data loading |
Sorry, yes, this is what I mean.
You're right, I was going off some incorrect memories. I think the point about not having to document TritonAgent vs. fetch stands, though.
Mostly. I think (?) to get the most benefit it might require switching to ES6 imports inside the
I remember you saying that. I don't think we depend on anything in express that isn't in connect, but I wouldn't be surprised if I was wrong about that.
Truth. I went looking for info on express 5 yesterday, and after 3 hours of reading github issues I think it seems like it's not being released.
I think this gets a little more complicated if you separate the client build and server build (i.e. you want to pre-compile client code for a static server), but it's still not super hard.
It's almost like the same person wrote them both... ;)
Yep, although I think they may have changed a few things to make it better? But I'm not sure? |
Re: CSS Modules or PostCSS We should be clear exactly what problem were trying to solve here. The most dangerous thing about css is that all selectors on a page are essentially global to all components. Selectors from any stylesheet can target any dom node on the page. This is bad for scale software projects that have more than one or two people working in the css. We currently solve this purely by convention. Our convention to make things simple for devs is that we match three things. Forgive the pseudo code below. Filename: /common/Button.js import './Button.less';
export default class Button extends Component {
static displayName: 'Button';
render() {
return(<button className='Button'>...</button>);
}
} Filename: /common/Button.less .Button {
color: blue;
} The first thing I see with this is that the string "Button" appears seven times. Lets count them:
Our convention is to keep them all in sync. We teach all new hires that they should be in sync by verbally telling them or catching the pattern in their first pull requests. We really haven't even documented it anywhere (which is totally my fault btw) This is certainly a broken system in my opinion. It's learning process is broken, there are no tests to enforce it, and major regressions are regularly caused when its not adhered to. Now that we're all pissed off at how silly we're being with CSS and how much work we're causing the devs just trying to do daily feature work , what can we do about it?
So, you mentioned PostCSS of which the most relevant part to trying to solve the aforementioned problem of styles seeking into the global scope is the react-css-modules plugin. Its base webpack only implementation is such: import styles from './table.css';
export default class Table extends Component {
render () {
return <div className={styles.table}>
<div className={styles.row}>
// More stuff here
</div>
</div>;
}
} Which results in: <div class="table__table___32osj">
<div class="table__row___2w27N">
<!-- More stuff here -->
</div>
</div> A couple things that I see about this approach. It certainly does solve the problem of styles leaking into the global scope, which really should be our number one issue. Still, there is a lot of convention, and a it doesn't really solve anything about the dev annoyances either. I don't personally find it easier to understand or reason about, but I could see myself getting used to it. There are a couple things you can do outside of webpack in the JS code to clean it up a bit, but I still find it a bit cumbersome and messy. To be perfectly clear, I do believe that adopting So, here's where I'll add some controversy and some open questions. To me, most of solutions out there don't do enough to solve the dev annoyances part. Here is an extreme proposal, that addresses all of the issues that I have mentioned above. Source Files Filename: /common/Button.js export default class extends Component {
render() {
return(<button>...</button>);
}
} Filename: /common/Button.less color: blue; or alternate syntax :local {
color: blue;
} Get transformed at build time into: import './Button.less';
export default class Button extends Component {
render() {
return(<button className="Button x0ns8">...</button>);
}
} .Button.x0ns8 {
color: blue;
} Which ultimately outputs: <button class='Button x0ns8'>...</button> .Button.x0ns8 {
color: blue;
}
Anyway, those are my initial thoughts, but I'll let people chew on that for meow. |
@roblg: one other question about this. I can't exactly figure out what the package dependencies would look like. I think that since |
Personally, and I'm just gonna throw this out there, I would love to see a future version of this that uses Koa instead of Express. |
@DanielFGray This issue is getting pretty large; would you mind filing the Koa issue on its own? |
This issue is too big for my puny brain; I'm going to split it into individual issues. |
(Dunno if this is the right place to put this; please advise if it's not.)
I was thinking about how I could best contribute to making
react-server
a public success, and I wanted to open a little bit of a discussion about what features might be added to (or subtracted from!)react-server-cli
andreact-server
. I brainstormed for a little while on my own, and the list is pretty scattered and wildly biased towards my own priorities. It's really only meant to be a starting point, and to prevent me from coding on something for a week or two that has no chance whatsoever of being merged because it's not in line with y'all's vision. Caveat: I'm not even sure that these are good ideas if there were infinite time to implement, and they betray my two main priorities: making dev rampup as quick & painless as possible, and having react-server(-cli) be a good example of web performance best practices.Without any further ado, here's my list, with guesses at T-shirt size:
loader
argument to the page API and then explaining superagent, we'd just say "use fetch like you already do".react-server
is that the server-side knows, in a structured way, about all of the associated resources for a page (JS, CSS, JSON XHR) and could push them pro-actively. Not only would this theoretically be faster than the current code, it would also obviate the need for the TritonAgent cache, which would simplify the logic a lot in the HTTP/2 case.Commons chunk (S): Tweak the webpack build in react-server-cli to pull out a common chunk of JavaScript, which would include the core of(Edited: Forgot I already did this, and it was merged in e30947a. Too much context switching!)react-server
. This would allow that chunk to be cached and shared in between pages.react-server
tests to usereact-server-cli
(M) - A bunch of tests forreact-server
fire up an actual express server, parse and massage the routes file, and run webpack before running a simulated browser against the resulting site. It would be nice if instead they usedreact-server-cli
to do that, both because we could delete a lot of code, and because it would help serve as a test forreact-server-cli
.react-server-cli
at a page file and have it set up a simple "/" route for that page. I could also potentially imagine pointing it at a directory and having every file namedXXXPage.js
being mapped to/xxx
.shrink-ray
that is adding zopfli and brotli support to express compression. I don't think this is a particularly good thing to spend time on right now, fwiw.react-dom-stream
; probably also not a particularly good use of time right now until rds is a bit more stable.startServer
callable.OK, that's what I've got for now. As I said, all totally up for discussion and not all great ideas. Please feel to add, subtract, disagree, etc. I'm especially interested in which ideas are total non-starters, and which you'd gladly accept as contributions if they were done well. Thanks!
The text was updated successfully, but these errors were encountered: