大家好,我是Echa哥,这一次,让我们来以React为例,把服务端渲染(Server Side Render,简称“SSR”)学个明明白白 。
这里附上这个项目的github地址: https://github.com/sanyuan0704/react-ssr
欢迎大家点star,提issue,一起进步!
part1:实现一个基础的React组件SSR这一部分来简要实现一个React组件的SSR 。
一. SSR vs CSR什么是服务端渲染?
废话不多说,直接起一个express服务器 。
var express = require('express')var App = express()app.get('/', (req, res) => { res.send( `<html><head><title>hello</title></head><body><h1>hello</h1><p>world</p></body></html> ` )})app.listen(3001, () => { console.log('listen:3001')})复制代码
启动之后打开localhost:3001可以看到页面显示了hello world 。而且打开网页源代码:
文章插图
也能够完成显示 。
这就是服务端渲染 。其实非常好理解,就是服务器返回一堆html字符串,然后让浏览器显示 。
与服务端渲染相对的是客户端渲染(Client Side Render) 。那什么是客户端渲染? 现在创建一个新的React项目,用脚手架生成项目,然后run起来 。这里你可以看到React脚手架自动生成的首页 。
文章插图
然而打开网页源代码 。
文章插图
body中除了兼容处理的noscript标签之外,只有一个id为root的标签 。那首页的内容是从哪来的呢?很明显,是下面的script中拉取的JS代码控制的 。
因此,CSR和SSR最大的区别在于前者的页面渲染是JS负责进行的,而后者是服务器端直接返回HTML让浏览器直接渲染 。
为什么要使用服务端渲染呢?
文章插图
传统CSR的弊端:
- 由于页面显示过程要进行JS文件拉取和React代码执行,首屏加载时间会比较慢 。
- 对于seo(Search Engine Optimazition,即搜索引擎优化),完全无能为力,因为搜索引擎爬虫只认识html结构的内容,而不能识别JS代码内容 。
二、实现React组件的服务端渲染刚刚起的express服务返回的只是一个普通的html字符串,但我们讨论的是如何进行React的服务端渲染,那么怎么做呢? 首先写一个简单的React组件:
// containers/Home.jsimport React from 'react';const Home = () => {return (<div><div>This is sanyuan</div></div>)}export default Home复制代码
现在的任务就是将它转换为html代码返回给浏览器 。众所周知,JSX中的标签其实是基于虚拟DOM的,最终要通过一定的方法将其转换为真实DOM 。虚拟DOM也就是JS对象,可以看出整个服务端的渲染流程就是通过虚拟DOM的编译来完成的,因此虚拟DOM巨大的表达力也可见一斑了 。而react-dom这个库中刚好实现了编译虚拟DOM的方法 。做法如下:
// server/index.jsimport express from 'express';import { renderToString } from 'react-dom/server';import Home from './containers/Home';const app = express();const content = renderToString(<Home />);app.get('/', function (req, res) {res.send(`<html><head><title>ssr</title></head><body><div id="root">${content}</div></body></html>`);})app.listen(3001, () => {console.log('listen:3001')})复制代码
启动express服务,再浏览器上打开对应端口,页面显示出"this is sanyuan" 。到此,就初步实现了一个React组件是服务端渲染 。当然,这只是一个非常简陋的SSR,事实上对于复杂的项目而言是无能为力的,在之后会一步步完善,打造出一个功能完整的React的SSR框架 。part2: 初识同构一.引入同构其实前面的SSR是不完整的,平时在开发的过程中难免会有一些事件绑定,比如加一个button:
// containers/Home.jsimport React from 'react';const Home = () => {return (<div><div>This is sanyuan</div><button onClick={() => {alert('666')}}>click</button></div>)}export default Home复制代码
再试一下,你会惊奇的发现,事件绑定无效!那这是为什么呢?原因很简单,react-dom/server下的renderToString并没有做事件相关的处理,因此返回给浏览器的内容不会有事件绑定 。
推荐阅读
- 吃什么补血 中医教你补气血
- 教你煮饺子的方法,煮出的饺子更好吃 怎么煮饺子
- 教你怎样调配花草茶,润肤花草茶
- 从草本植物角度科学的认识百合花茶,四大步骤教你如何简易而快速的冲泡百合花茶
- 手把手教你进行pip换源,让你的Python库下载嗖嗖的
- 今日头条如何发文才有收益?新人朋友请看过来,教你一步步操作
- 教你安全配花茶,花茶的感官鉴赏
- 百合花茶搭配,四大步骤教你如何简易而快速的冲泡百合花茶
- 13个护发误区大扫盲,教你掌握正确洗护方法
- 黑苦荞茶什么牌子纯正,四大步骤教你如何简易而快速的冲泡百合花茶