React 我好像忘了发这个 - 基于 rails/webpacker 实现的 React 应用尝试

huacnlee for Ruby China · February 14, 2017 · Last by fresh_fish replied at June 10, 2020 · 11318 hits

话说目前工作所参与的项目前端就是大量用 React 编写的,自己还一直没有去认真学习过,主要原因是我认为 JavaScript 社区出的东西很容易过时,同时手上掌握了一套复杂前端的实现方案 Backbone.js,感觉各类场景都够用了。

某天看到 Rails 的某处文档上有 rails new myapp --webpack=react例子 了,我一看,不行啊,得学学 React 看看了。

同时也可以顺便提前试试 webpacker

于是基于 Ruby China 的 API 做了个简单的应用。

类似的东西,最近已经有好多人发布过了:

反正这些项目最后都会半途而废的 😄

关于 React

这个项目基本实现了话题列表、查看话题、赞、回帖(比较初级)、查看用户 Profile 等主要功能,还比较粗糙,做下来发现要完成整个 Ruby China 的功能还需要花非常多的时间,同时本以为纯前端渲染可能会提升一些打开的速度,但发现没多大变化(而且目前功能量实现还不多),暂时不会继续搞了。

单纯来说 React 还是挺简单,实现出来的效果(代码质量、效率)也很好,或许下次我新作项目会考虑用它开始。

什么时候 React 的版本会比目前 Ruby China 的速度

答:在网络不佳的情况下,React 的版本只需下载 API 的数据内容,而目前版本的 Ruby China 需要下载完整 HTML。

什么时候 React 的版本会比 Ruby China 目前的方式

答:在网络质量好,服务器带宽足的场景下,大多数时候 Ruby China 这种 HTML 结果直接返回 + Turbolinks 的优化,打开的速度是更快的,因为前端几乎是无运算的,本身 Rails 做好了,单个页面 Response Time 在 100ms 左右,剩下的时间都是网络传输了(大篇幅 HTML 代码)。同时 React 应用典型的问题是首次打开慢。

当然以上都得要求 Server Render 的部分要做的足够的好,Turbolinks 这种方式才能有足够快的响应速度。然而,这部分是 Rails 比较弱的,Views 渲染几乎占据了整个 Request 周期的 40% 以上甚至更多(以之前的一些应用的情况来看),而如果 Rails 写成 JSON 的 API,响应时间能缩短许多,并且都不用再像 Views 那样做大量的 Fragment Cache 增加 Views 里面的逻辑复杂度(其实复杂度最后都到前端去了... 结果是一样的)。

以上仅是正对两个 Ruby China 的实现版本多对比...

关于 Webpacker

Webpacker 由于还处于开发阶段,有些小细节还自己补了几刀才顺利搞起来,背后是基于 Webpack

说真的,长期用惯了 Assets Pipeline 那套机制,我非常不喜欢 Webpack,感觉简简单单的前端代码被它搞得好复杂,我也讨厌 import { XXX } from 'xxx';' 这种显式引用的写法,每个 JS 的文件顶部一对重复代码,严重违反了 DRY 的原则。

这个项目就没用用 react_on_rails 之类的 Gem 了,直接使用 npm 的包,前端是完整前端那套体系。刚开始做准备的时候花了好多时间...

由于水土不服,CoffeeScript 也用不上了,直接用 es2015 的语法写的 (是吧?)

Bootstrap 用了,但 JS 部分没发跑,这也是我不喜欢 React 的原因,以前的各类组建需要用 React 重写的才行。

项目源代码地址

如果你也想提前了解一下如何使用 Webpacker,以及如何在 Rails 里面编写 React 应用,这个项目或许能给你一些参考。

https://github.com/huacnlee/react-rails-example

演示地址

http://react-homeland.herokuapp.com

速度明显快,值得学习。

这学新东西跟玩似的

感觉快了,和现在 ruby china 部署到同样环境下对比一下,现在不能排除是 heroku 快 😄

那么多前端框架都已经从出生到死亡了,我还没开始研究,好像省了很多时间啊。

import { XXX } from 'xxx';' 这种显式引用的写法,每个 JS 的文件顶部一对重复代码,严重违反了 DRY 的原则

全局模块可以用ProviderPlugin定义,不需要重复。

对于局部需要的模块,我是十分喜欢显示引用。至少有了问题可以方便追溯源头。Rails 里面要是加了一些魔法方法,不熟悉项目的话要花好一番功夫琢磨到底是哪个 lib 或者 gem 加入了这些东西。

angular1.08 的时候我机智地跑了😆
react_on_rails 提供了服务器渲染,还是挺感兴趣的,然而并没有做 spa 的打算,还是用 mithril.js 凑合用着

为啥我感觉这 react 的 UI 清爽了好多。。

个人感觉就是 react 的绝对使用场景相对较少,一般非即时页面(聊天室),非富交互 web 产品,rails 已经够用…react 有点过于工程化了。

所以我一直都没机会学 react, angular 这些来做自己的 idea…

当然,以上前提都是 Server Render 的细节要做的够好才能足够快,否则可能 React 出来的结果容易更好一些

现在很多讨论都说 react 渲染和服务端渲染(Turbolinks 本质上还是服务端渲染)速度的比较问题。其实我认为这个讨论没有太大的实质意义:react 试图降低的是前端复杂性,而不是数据传输的大小(react 做 api,减少了 html 标签之类的数据传输微不足道,也不是 react 的重点,其他前后端分离的框架一样能做到;至于 heroku 什么的那是中国国情,也没什么代表性意义)。

比如一个界面组成超复杂,交互逻辑很多,工程师都绕晕了的情况,react 可以极大简化代码逻辑,更易维护。而 ruby-china 论坛这种网页前端复杂性停留在传统 web1.0+ 时代的网站来说,并不是他的应用场景。

@sefier

至于 heroku 什么的那是中国国情,也没什么代表性意义

我的意思你没看懂...

现在很多讨论都说 react 渲染和服务端渲染(Turbolinks 本质上还是服务端渲染)速度的比较问题

我只是提了这么一点而已,并不是说因为这个来对比,在这,最终产生的渲染效率也是一个考量的方向。再者本身这个尝试就是想看看换成那种方式能带来什么变化,开发效率、响应效率。

react 做 api,减少了 html 标签之类的数据传输微不足道

这个不知道你在说什么,React 可以做 API? 还是你把我原文看错了?


我当然知道 React 的意义在于简化前端代码逻辑,但这个事情哪个前端框架不都是这个目的么?只是我这里没有提而已。但实际上都是扯淡,用得好的人,用什么都能组织的好,用不好的用 React 依然乱的一塌糊涂。

#13 楼 @huacnlee

我针对的是这个

在网络质量好,服务器带宽足的场景下,大多数时候 Ruby China 这种 HTML 结果直接返回 + Turbolinks 的优化,打开的速度是更快的,因为前端几乎是无运算的,本身 Rails 做好了,单个页面 Response Time 在 100ms 左右,剩下的时间都是网络传输了(大篇幅 HTML 代码)。同时 React 应用典型的问题是首次打开慢。 所以鉴于上面的情况,这是有意义的,因为网络质量是不稳定的(例如,我的演示代码部署在 Heroku,首次打开以后几乎感觉不到 Heroku 的慢了),而且每个用户不同。

1.Heroku 的网络质量不稳定是国情,现在做网站一般多数不考虑这种情况

2.大篇幅 HTML 代码 vs. React 采用的 API 相比,网络传输节约的量微不足道

结论:“所以鉴于上面的情况,这是有意义的,因为网络质量是不稳定的”

你的意思是 React 的意义,就在于网络质量不稳定,节约流量。这个意义不大,现在网络已经不是以前的网络了,我觉得你考虑下 react 是不是简化了你的代码逻辑,易扩展,易维护,这个更值得分享,让我们更清楚哪些情况下更值得使用 React,哪些情况下不值得使用(从你的描述来看,很容易得出结论:如果应对网络状况不佳的用户,React 很有意义)。

#14 楼 @sefier 所以你都没看完后面的内容,你甚至这句的意思都理解错了

#15 楼 @huacnlee 是的,我“理解错了”,我说的要么你“不知道你在说什么”,要么就是“我当然知道”么?那我就不说了。😅

#16 楼 @sefier 你不要在我回复以后再重新修改之前的回帖呀?你之前那句是让人觉得你没看明白啊

#17 楼 @huacnlee 我引用的那一段后面是“关于 Webpacker”,你说我没看完后面的内容,我不知道我漏了哪一块?

#14 楼 @sefier

你的意思是 React 的意义,就在于网络质量不稳定,节约流量。

不要抬杠好不好!我哪有哪个意思,你是非得强加上去。

#19 楼 @huacnlee 因为之前有很多帖子提到这个问题,甚至有详细的对比 Turbolinks 和 React 的渲染速度对比,然后回复就是一片声的赞扬 Turbolinks 的渲染速度。拿服务器渲染和客户端框架渲染速度作对比,就好比用一个 HelloWorld 裸框架和一个提供了很多基础设施的高级框架进行速度对比一样。

这个对比很容易产生一个社区误导:React 速度不行。(我已经在那个帖子看到不少了)

你这个帖子只是略微提一下,那我也是略微提一下(我认为你不要再提这个了,尤其是 Heroku 这种例子,只会让社区更加不理解 React)。

以上,只是我的个人意见,并非抬杠。

再看你的原话:

所以鉴于上面的情况,这是有意义的,因为网络质量是不稳定的(例如,我的演示代码部署在 Heroku,首次打开以后几乎感觉不到 Heroku 的慢了),而且每个用户不同。

强调了 React 在网络质量不稳定下的意义,至于其他的意义,只字未提。你说我理解错了,那就是说需要我脑补其他问题。

#20 楼 @sefier

你哪里看出来我在强调?

就算我说慢/快,我也说的是 React 实现的 Ruby China 版本和目前版本的对比。

外加 #11 楼 你看我在说什么?

同时,我这篇文章有在说 React 不好大家不要用这类的意思么?没有吧

当然,可能原文某些话没有将太细,让你误解,我补补。

个人感觉前端渲染还是挺有意义的,传统 web 应用的浏览器端计算资源都被闲置了,对于 rails 来说,view 的 render 本来性能就被诟病,如果 view 移到浏览器端 render 的话,还可以提高服务器吞吐量,合理分配计算资源。缺点的话 SEO 不友好?以上个人愚见。下个项目打算用 vue 做前端,rails 做后端来搞。

#1 楼 @huacnlee 时间精力允许,其实学了没坏处。感觉这样说会误导新手。

庆幸当初没有去学 AngularJS、Ember.js,以及过程中死掉、或快死掉的各类前端框架

#24 楼 @hiveer 我不认为,有时间不如花在其他地方。况且这里受众群大多是 Ruby 工程师。

这些东西我认为了解一下就好了,没必要每个都去深入学一下。真要用的时候也就顶多一周就学会了。

#23 楼 @wildchilderic 不一定。

首先,客户端性能不是可忽视的,特别是移动端。https://medium.com/dev-channel/javascript-start-up-performance-69200f43b201#.5o2nxx2gw

其次 从 HTML 页面转 JSON API 不一定能降低服务器负担。像 Ruby China 的 API 优化得没有 Web 好,你可以调试顶楼的 demo,首页 Web 一个 30 毫秒请求,换成 API 需要两个 80 毫秒请求,服务器负担变大了。即使优化很好我觉得差别也不会大,因为数据库耗时是一定的,渲染部分都缓存住。

#26 楼 @Rei 学习了~ 我手上的项目有不少 js 的交互,现在的版本用了挺多 js.erb,混着 ruby 和 js 很难看,也不好维护。 接下来打算结合 turbolinks,vue;rails 既 render view(仅仅含有 vue component 的视图,不做数据输出)也输出 api(为 vue component 输出数据)。不是纯的 SPA,目标是分开混合的 js 和 ruby,同时降低 rails view rendering 的负担,用户量较小,暂时不打算做缓存。看看重写完和之前版本比较怎么样~

saiga in 跟风安利,用 Mithril.js 实现的 Homeland Demo mention this topic. 20 Feb 19:04
Reply to Rei
  1. ”一直到了最近有人利用 Ruby China API 重写前端,我才有机会做一个公平测试。“用一个新手写的练手项目,做 公平测试?请有点 基本 的科学素养。

  2. react 适合的场景不是”有很多拖拽、弹层、动画效果“。请不要误导新手。

非常感谢带路!

webpacker个人感觉真的不好用... 😑

可能也是我不太会用除了 assets 外的东西吧

Reply to msl12

webpack 对于用过 grunt,gulp 的人来说简直是天使..

Reply to nightire

以前的 js 的框架讨论总有你的精彩讨论,想起好久没看到你出没了。

@5swordsnightire 这是在讨论性能吧,这方面的讨论我向来都不太感兴趣,最近也忙,没空。

我觉得 Assets Pipeline 是个好东西,webpack 也是个好东西。 但是感觉 webpacker 太复杂了

webpacker 打包出来的 react 好大啊!

You need to Sign in before reply, if you don't have an account, please Sign up first.