Respo 文档站点的 isomorphic rendering 方案
文档站的特点
正好帮我刷一下访问量... http://respo.site/ 文档站是基于 React 写的,用的是自己的 router 和 store 方案 比如说我浏览页面,在前端渲染好了 isomorphic rendering(同构渲染)
这个方案有几个特征:
除了首屏加载的 js 代码没有做分块之外,总体感觉都比较好, 当然,这个页面比较简单,没有通过 Ajax 加载 JSON 再渲染的部分, 至于动态内容,我觉得在客户端通过脚本抓取是更简单的方案, 实现思路
大致是这样一个过程:
首先就是服务端很容易遇到的 Component 的加载和渲染问题, 这个步骤对路由模块有做了一些要求,需要能在服务端运行, router-as-view
https://github.com/react-chin... 在 {parseAddress} = require 'router-as-view/lib/path' routes = Immutable.fromJS home: [] 'discuss.html': [] guide: ['entry'] docs: ['post'] router = parseAddress path,routes initialStore = schema.store.set 'router',router ReactDOM.renderToString(Container(store: store})) 从而很容易进行抽象,然后再 Gulp 里调用渲染 HTML: gulp.task 'entries',(cb) -> // ... pages.forEach (pathname) -> // ... fs.writeFileSync "build/#{filename}.html",html(env,routerPath) // ... react-router
具体实现不清楚,我只能摘录文档当中的例子: https://github.com/ReactTrain... import { renderToString } from 'react-dom/server' import { match,RoutingContext } from 'react-router' import routes from './routes' serve((req,res) => { // Note that req.url here should be the full URL path from // the original request,including the query string. match({ routes,location: req.url },(error,redirectLocation,renderProps) => { if (error) { res.status(500).send(error.message) } else if (redirectLocation) { res.redirect(302,redirectLocation.pathname + redirectLocation.search) } else if (renderProps) { res.status(200).send(renderToString(<RoutingContext {...renderProps} />)) } else { res.status(404).send('Not found') } }) }) vue-routerVue 2 文档上没解释服务端路由的问题,从已经发布的 Demo 看是支持的, https://github.com/vuejs/vue-... https://github.com/vuejs/vue-... respo-routerrespo-router 基本上是 https://github.com/Respo/shel... 有点难看到懂,但是大体的思路还是用组件生成 HTML,其他部分都是脚本: (defn html-dsl [data html-content ssr-stages router] (make-html (html {} (head {} (let [store (assoc schema/store :router router)] (script (:attrs {:id "store" :type "text/edn" :innerHTML (pr-str store)})))) (body {} (div {:attrs {:id "app" :innerHTML html-content}}) (script {:attrs {:src "/main.js"}}))))) (defn generate-html [router ssr-stages] (let [ tree (comp-container {:router router} ssr-stages) html-content (make-string tree)] (html-dsl {:build? true} html-content ssr-stages router))) (def dict {"post" ["post"],"about.html" [],"home" []}) (defn -main [] (spit "target/index.html" (generate-html (parse-address "/" dict) #{:shell})) (spit "target/about.html" (generate-html (parse-address "/about.html" dict) #{:shell})) (sh "mkdir" "target/post/") (spit "target/post/a.html" (generate-html (parse-address "/post/a.html" dict) #{:shell})) (spit "target/post/b.html" (generate-html (parse-address "/post/b.html" dict) #{:shell}))) 结尾其他的方案,Angular 2 未知... 按说已经支持服务端渲染,应该能搞定, 当然,回到文章的核心观点,就是要提供一个 Gulp 渲染的方案,所有的页面入口按照路由在服务端预渲染完成,作为一个优化,从而让页面在观感上加载得更快. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |