前言
本次讲述的内容主要是 react 与 koa 搭建的一套 ssr 框架,是在别人造的轮子上再添加了一些自己的想法和完善一下自己的功能。
本次用到的技术为: react | rematch | react-router | koa
react服务端渲染优势
SPA(single page application)单页应用虽然在交互体验上比传统多页更友好,但它也有一个天生的缺陷,就是对搜索引擎不友好,不利于爬虫爬取数据(虽然听说chrome能够异步抓取spa页面数据了);
SSR与传统 SPA(Single-Page Application - 单页应用程序)相比,服务器端渲染(SSR)的优势主要在于:更好的 SEO 和首屏加载效果。
在 SPA 初始化的时候内容是一个空的 div,必须等待 js 下载完才开始渲染页面,但 SSR 就可以做到直接渲染html结构,极大地优化了首屏加载时间,但上帝是公平的,这种做法也增加了我们极大的开发成本,所以大家必须综合首屏时间对应用程序的重要程度来进行开发,或许还好更好地代替品(骨架屏)。
react服务端渲染流程
组件渲染
首先肯定是根组件的render,而这一部分和SPA有一些小不同。
使用 ReactDOM.render() 来混合服务端渲染的容器已经被弃用,并且会在React 17 中删除。使用hydrate() 来代替。
hydrate与 render 相同,但用于混合容器,该容器的HTML内容是由 ReactDOMServer 渲染的。 React 将尝试将事件监听器附加到现有的标记。
hydrate 描述的是 ReactDOM 复用 ReactDOMServer 服务端渲染的内容时尽可能保留结构,并补充事件绑定等 Client 特有内容的过程。
import React from 'react';import ReactDOM from 'react-dom';ReactDOM.hydrate(<App />, document.getElementById('app'));
在服务端中,我们可以通过 renderToString 来获取渲染的内容来替换 html 模版中的东西。
const jsx = <StaticRouter location={url} context={routerContext}> <AppRoutes context={defaultContext} initialData={data} /> </StaticRouter> const html = ReactDOMServer.renderToString(jsx);let ret = ` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, user-scalable=no"> </head> <body> <div id="app">${html}</div> </body> </html>`;return ret;
服务端返回替换后的 html 就完成了本次组件服务端渲染。
路由同步渲染
在项目中避免不了使用路由,而在SSR中,我们必须做到路由同步渲染。
首先我们可以把路由拆分成一个组件,服务端入口和客户端都可以分别引用。
function AppRoutes({ context, initialData }: any) { return ( <Switch> { routes.map((d: any) => ( <Route<InitRoute> key={d.path} exact={d.exact} path={d.path} init={d.init || ''} component={d.component} /> )) } <Route path='/' component={Home} /> </Switch> );}
新闻热点
疑难解答
图片精选