React同构直出原理浅析

通常,当客户端请求一个包含React组件页面的时候,服务端首先响应输出这个页面,客户端和服务端有了第一次交互。然后,如果加载组件的过程需要向服务端发出Ajax请求等,客户端和服务端又进行了一次交互,这样,耗时相对较长。服务端是否可以在页面初次加载时把所有方面渲染好再一次性响应给客户端呢?
「React同构直出」就是用来解决这个问题的,做到「秒开」页面。过程大致是这样滴:
1、在需要同构直出的页面(比如是index.html)放上占位符
<div id="root">@@@</div>
###
以上,当客户端发出首次请求,服务端渲染出组件的html内容放@@@这个位置,然后服务端再渲染出类似<script>renderApp()</script>这样的js代码段把组件最终渲染到DOM上。也就是说,renderApp方法实际上就是在渲染组件。
2、而为了直接调用renderApp方法,必须让renderApp方法成为window下的方法
window.renderApp = function(){ReactDOM.render(...)}
3、服务端取出index.html,渲染出占位符的内容,替代占位符,并一次性响应给客户端
通过一个例子来体会。
文件结构
browser.js(在这里把渲染组件的过程赋值给window.renderApp)
bundle.js(把browser.js内容bundle到这里)
Component.js(组件在这里定义)
express.js(服务端)
index.html(同构直出的页面)
package.json
index.html,直出页面放上占位符
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Untitled Document</title>
</head>
<body>
<div id="root">@@@</div>
<script src="bundle.js"></script>
###
</body>
</html>
Component.js,在这里定义组件
var React = require('react');
var ReactDOM = require('react-dom');
var Component = React.createClass({
clickHandler: function(){
alert(this.props.msg)
},
render: function(){
return React.createElement('button', {onClick: this.clickHandler}, this.props.msg)
}
})
module.exports = Component;
browser.js,把组件渲染过程赋值给window对象
var React = require('react');
var ReactDOM = require('react-dom');
var Component = React.createFactory(require('./Component'));
window.renderApp = function(msg){
ReactDOM.render(Component({msg: msg}), document.getElementById('root'));
}
可以通过<script>render()</script>来触发组件的渲染。稍后,在服务端会把这段代码渲染出来。
express.js,服务端
以上,需要直出的页面有了占位符,定义了组件,并把渲染组件的过程赋值给了window对象,服务端现在要做的工作就是:生成组件的html和渲染组件的js,放到直出页面index.html的占位符位置。
var express = require('express');
var React = require('react');
var ReactDOMServer = require('react-dom/server');
var fs = require('fs');
var Component = React.createFactory(require('./Component'));
//原先把文件读出来
var BUNDLE = fs.readFileSync('./bundle.js',{encoding:'utf8'});
var TEMPLATE = fs.readFileSync('./index.html',{encoding:'utf8'});
var app = express();
function home(req, res){
var msg = req.params.msg || 'Hello';
var comp = Component({msg: msg});
//@@@占位符的地方放组件
var page = TEMPLATE.replace('@@@', ReactDOMServer.renderToString(comp));
//###占位符的地方放js
page = page.replace('###', '<script>renderApp("'+msg+'")</script>')
res.send(page);
}
//路由
app.get('', home);
app.get('/bundle.js', function(req, res){
res.send(BUNDLE);
})
app.get('/:msg', home);
app.listen(4000);
package.json中的配置
"scripts": {
"start": "watchify ./browser.js -o ./bundle.js"
},
运行:npm start
运行:node express.js
浏览:localhost:4000
项目地址:https://github.com/darrenji/ReactIsomorphicSimpleExample
React同构直出原理浅析的更多相关文章
- 腾讯新闻构建高性能的 react 同构直出方案
在腾讯新闻抢金达人活动 node 同构直出渲染方案的总结文章中我们整体了解了下同构直出渲染方案在我们项目中的使用.正如我在上篇文章结尾所说的: 应用型技术的难点不是在克服技术问题,而是在于能够不断的结 ...
- React同构直出优化总结
收录待用,修改转载已取得腾讯云授权 作者:郭林烁 joeyguo 原文地址 React 的实践从去年在 PC QQ家校群开始,由于 PC 上的网络及环境都相当好,所以在使用时可谓一帆风顺,偶尔遇到点小 ...
- 面向亿万级用户的QQ一般做什么?——兴趣部落的Web同构直出分享
作者:李强,腾讯web开发工程师 商业转载请联系腾讯WeTest获得授权,非商业转载请注明出处. 原文链接:http://wetest.qq.com/lab/view/348.html 一.什么是同构 ...
- 面向亿万级用户的QQ一般做什么?——兴趣部落的 Web 同构直出分享
欢迎大家前往腾讯云社区,获取更多腾讯海量技术实践干货哦~ 作者:李强,腾讯web开发工程师商业转载请联系腾讯WeTest获得授权,非商业转载请注明出处.原文链接:http://wetest.qq.co ...
- Vue(SPA) WebPack模块化打包、SEO优化(Vue SSR服务端同构直出)、全浏览器兼容完整解决方案
白驹过隙,时光荏苒 大概去年这个时候写了angular 结合webpack的一套前端方案,今年此时祭出vue2结合webpack的一套前端方案. 明年的这个时候我又是在做什么... 读在最前面: 1. ...
- 腾讯新闻抢金达人活动node同构直出渲染方案的总结
我们的业务在展开的过程中,前端渲染的模式主要经历了三个阶段:服务端渲染.前端渲染和目前的同构直出渲染方案. 服务端渲染的主要特点是前后端没有分离,前端写完页面样式和结构后,再将页面交给后端套数据,最后 ...
- React直出实现与原理
前一篇文章我们介绍了虚拟DOM的实现与原理,这篇文章我们来讲讲React的直出. 比起MVVM,React比较容易实现直出,那么React的直出是如何实现,有什么值得我们学习的呢? 为什么MVVM不能 ...
- 打造高可靠与高性能的React同构解决方案
前言 随着React的兴起, 结合Node直出的性能优势和React的组件化,React同构已然成为趋势之一.享受技术福利的同时,直面技术挑战,在复杂场景下,挑战10倍以上极致的性能优化. 什么是同构 ...
- React同构起步
React同构从0到1 前言 如果你想快速做react同构的新项目建议你去了解next.js等成熟框架,本教程仅限于想了解如何从0开始实现一个同构环境过程的同学,对于想改造现有spa项目的同学也很有帮 ...
随机推荐
- [转载]提高rails new时bundle install运行速度
最近在新建rails项目时,rails new老是卡在bundle install那里,少则五分钟,多则几十分.这是因为rails new时自动会运行bundle install,而bundle in ...
- iOS富文本的使用
NSString *name = nil; if (_payNumber == 1) { name = [NSString stringWithFormat:@"向%@收款",na ...
- 理解em,rem以及rem的失效问题
在平常做网站写代码的时候一般都是使用px,在之前的学习时就略微的学习了一些关于em.rem的知识,但是由于一直没有用到过,所以几乎全部忘记了.今天在研究一些知识的时候用到了em,所以特意将学到的知识总 ...
- WebService 基本操作
1.新建asp.net web 应用程序 2.添加web 服务webservice.asmx public string HelloWorld(int a) { if (a==1) { return ...
- pullToRefresh下拉刷新上拉加载
PullToRefresh 是一个第三方的工程. 之前的自定义下拉刷新控件貌似不太好用,于是网上找了这个. 参考:http://www.cnblogs.com/summers/p/4343964.ht ...
- Masonry 轻量级布局框架的使用
iOS 提供了自动布局的方法,但是原生的方法使用太过麻烦 ,Masonry 框架提供了类似的方法,同样可以实现自动布局 ,代码更加直观,而且容易理解. Masonry 是一个轻量级的布局框架.拥有自己 ...
- java实验一 20135104刘帅
实验报告 一.实验目的与要求: 实验目的: 1. 使用JDK编译.运行简单的Java程序 2.使用Eclipse 编辑.编译.运行.调试Java程序 实验要求: 1.没有Linux基础的同学建议先学习 ...
- html 问题
1.footer处理 目标: 页面较短,footer位于页面底部,出现滚动条时,依然在原来的位置,不随滚动条移动 页面较长,位于元素底部 .container{ position: relative ...
- International Conference in 2015
Call for Paper International Conference on Computer Vision(ICCV2015, Santiago, Chile). (deadline: Ap ...
- 从C#到Objective-C
Objective-C 程序设计语言采用特定的语法,来定义类和方法.调用对象的方法.动态地扩展类,以及创建编程接口,来解决具体问题.Objective-C 作为 C 程序设计语言的超集,支持与 C 相 ...