大数据知识分享之服务器渲染
博客前言:
疫情期间,停下脚步,终于有时间去总结自己、反省自己,从而有机会提升自己,人嘛,总不能原地踏步。三年前放弃办公位,随着公司的发展方向,选择扛着我的电脑奔赴各大城市,去实施、开发、应对市场对软件应用的各式需求。无论堆积了多少的心酸和眼泪,还是从一个坑跳到另一个坑留下的伤痕累累。从结果来看,收获都是颇为丰富的,从中提升了我的价值观和改变了我一些开发的思维方式。
三年以前,作为一个前端开发,无论App也好还是混合开发到后来的web开发。我深知自己的能力和知识储备有限,要有很大的突破是很难的,甚至当时觉得天天坐在办公桌上敲一些业务逻辑代码,好比一台机器在设定的程序下重复做一件事,作为一个这样的开发者,就真正的成为了一台机器,在被磨损,不能生产的那一天,终究会被淘汰。当真正入行,你才会发现,在中国这个大社会环境下,该行业的竞争压力有多大,人才济济,大佬比比皆是,如果你得不到突破,始终会被固定在一个自己认知的界限里,随着年龄的增长被淘汰掉。
虽然现在也要敲代码,但是这种感觉是幸福的,从真正喜欢探索大数据世界这天开始,我的职业让我从为了生活变为了生活兴趣,就好比我同事开玩笑道,“在项目交付中,我是最会写代码的;在会写代码中,我是最会项目交付的”,这或许是我的生存之道。然而,每当在项目实施管理中累了,可以敲敲代码,学习后端大数据服务框架;在敲代码中累了,可以反思根据项目业务需求,去根据需求发散思维进行创新。开发的本意就是需要我们创新,我们的创新,需要凌驾于代码之上,通过不断地学习大数据的架构,通过自己的理解,去提出不同的解决方案。最终的落地实施是脱离不了市场的需求。最好的解决方案不是等需求敲定,而是在不断挖掘需求的过程中去想到更多的方案,通过不同的方案去匹配客户引导客户(ps:深入行业的大数据除外)。这就是我所理解的大数据,也是目前中国社会大环境下的大数据。
服务器渲染
回归正题,今天要分享的是前端代码通过服务器渲染,服务器渲染这项技术,在三年前很多web应用就开始流行使用了,这是一个浏览器加载多数据web应用的解决方案之一。在大数据应用中,无论是我们的业务系统,还是大屏可视化,首先要考虑的是我的应用要通过什么方式来解决加载大量数据的请求以及业务逻辑的计算。
1、什么是服务器渲染
基于大数据项目,底层海量数据汇集,通过大数据手段治理数据存放在数据持久层。如果客户端浏览器直接通过动态请求方式(例如ajax请求),将js数据填充到dom元素上最终展示到网页上,会造成前端性能、交互效果等有较差的用户体验。通过服务器渲染方式,后端现调用数据库,获得数据后,将数据和页面元素进行拼装,组合成完整的htnl页面,再直接返回给浏览器,以便用户浏览。
2、服务器渲染与客户端渲染优劣对比
针对于不同体量项目而言,孰优孰劣,根据判断数据量展示到应用层来选择:
a.服务器端渲染需要消耗更多的服务端资源(CPU,内存等)
b.客户端渲染可以将静态资源部署到CDN上,实现高并发
c.服务端渲染对SEO更友好
结合分析,大数据应用在前端上采用服务器渲染是更好的,其实我们也不难发现,大数据应用都会向底层数据库进行大量的数据请求,如果再加一些分析计算,那前端PC就不堪重负了,我们把这个任务交给一台高配置服务器来完成,不仅节约了前端PC资源,还可以提升良好的用户体验。对于开发者而言,轻量级的数据运算都是可以放在前端代码去实现,分析计算通过服务器渲实现业务逻辑代码来完成。当然像重量级的数据运算及算法实现还是需要依托于我们的数据储存工具来完成,通过运算好的结果数据展示在前端页面上,例如hadoop分布式计算三大组件,计算层:Map/Reduce、调度层:YARN、数据层:HDFS通过多节点的部署分工合作可帮我们解决大部分的数据处理。解决方案是灵活多变的,不管你中间层加多少的工具去处理数据,我们前端获取的是越接近于最终展示的结果数据,需要我们处理的数据就越少,前端的性能相对就越好(除去高性能的前端资源渲染考虑,例如:webGL技术,图片资源大小等),至少服务器渲染可以帮我们解决前端复杂计算的困扰。
源码分享
在阅读源码前具备:你的电脑装有node.js环境,前端开发工具,具备js ES6语法,node语法,vue前端框架知识,面向对象编程思想,此环境采用Vue全家桶的技术栈:Vue+vue-router + vuex+SSR+koa
源码说明:此源码从npm install 直接部署, 已配置sass、stylus、scss可直接使用,后期加入java后台搭建组成一个完整的微服务应用平台
此处修改客户端IP和端口:
/**=========================================
* fileName: webpack.config.client.js
* discription: 客户端启动自定义配置文件
* author: TangYang
* date: 2020-03-12
* Copyright (C) 2020 Private
===========================================*/
/**
* 插件及配置文件的引入
*/
const path = require("path");
const HTMLPlugin = require("html-webpack-plugin");
const webpack = require("webpack");
const merge = require("webpack-merge");
const ExtractPlugin = require("extract-text-webpack-plugin");
const baseConfig = require("./webpack.config.base");
const VueClientPlugin = require("vue-server-renderer/client-plugin");
/**
* 全局常量
*/
const IS_DEVELOPMENT = process.env.NODE_ENV === "development";
const defaultPluins = [
new webpack.DefinePlugin({
"process.env": {
NODE_ENV: IS_DEVELOPMENT ? '"development"' : '"production"'
}
}),
new HTMLPlugin({
template: path.join(__dirname, "template.html")
}),
new VueClientPlugin()
];
const devServer = {
port: 8088, //客户端端口
host: "0.0.0.0", //客户端地址
overlay: {
errors: true
}
},
historyApiFallback: {
index: "/public/index.html"
},
此处修改服务器IP和端口:
/**=========================================
* fileName: server.js
* discription: koa服务端渲染自定义配置文件
* author: TangYang
* date: 2020-03-12
* Copyright (C) 2020 Private
===========================================*/
/**
* 引入koa框架
*/
const Koa = require("koa");
const send = require("koa-send");
const app = new Koa();
const path = require("path");
pageRouter = require("./routers/dev-ssr");
/**
* 定义全局常量
*/
const IS_DEV_ENV = process.env.NODE_ENV === "development"; //是否是开发环境
const HOST = process.env.HOST || "0.0.0.0"; //server IP
const PORT = process.env.PORT || 8089; // server PORT
/**
* koa中间件:记录服务端请求及异常抛出
*/
app.use(async (ctx, next) => {
try {
console.log(`请求路径:${ctx.path}`);
await next();
} catch (err) {
console.log(err);
ctx.status = 500;
if (IS_DEV_ENV) {
ctx.body = err.message;
} else {
ctx.body = "请稍后再试...";
}
}
});
app.use(async (ctx, next) => {
if (ctx.path === "/favicon.ico") {
await send(ctx, "/favicon.ico", { root: path.join(__dirname, "../") });
} else {
await next();
}
});
app.use(pageRouter.routes()).use(pageRouter.allowedMethods());
app.listen(PORT, HOST, () => {
console.log(`服务器地址:${HOST}:${PORT}`);
});