Nodejs express渲染ejs,如果是首页这种逻辑比较多的页面。用哪种方案好?
Nodejs express渲染ejs,如果是首页这种逻辑比较多的页面。用哪种方案好?
express渲染ejs,如果是首页这种逻辑比较多的页面。用哪种方案好? 一、app.get(’/’,fn1,fn2,fn3,fn(){render})这种next的方式 二、并发执行,然后兼听fn1,fn2,fn3全部完成再render 三、用ajax方式,模板加载后主动取数据渲染 是不是有更好的方案?
对于 Node.js 和 Express 渲染 EJS 模板时,处理逻辑复杂的首页(例如需要从多个 API 获取数据、处理复杂的业务逻辑等),选择合适的方案非常重要。以下是对您提出的几种方案的分析以及推荐方案:
方案一:中间件链(next
的方式)
这种方式是 Express 中间件的标准使用方式。它适用于需要按顺序处理多个步骤的情况。
app.get('/', function(req, res, next) {
fn1(req, res, next);
}, function(req, res, next) {
fn2(req, res, next);
}, function(req, res, next) {
fn3(req, res, next);
}, function(req, res) {
res.render('index', { /* 数据 */ });
});
优点:代码结构清晰,易于理解和维护。
缺点:如果 fn1
, fn2
, fn3
是异步操作,则可能造成阻塞或回调地狱。
方案二:并发执行,等待所有完成
这种方式适用于需要并行处理多个任务,并在所有任务完成后进行渲染的情况。
const async = require('async');
app.get('/', function(req, res) {
const tasks = [
function(callback) { fn1(req, res, callback); },
function(callback) { fn2(req, res, callback); },
function(callback) { fn3(req, res, callback); }
];
async.parallel(tasks, function(err, results) {
if (err) return res.status(500).send(err);
res.render('index', { /* 数据 */ });
});
});
优点:提高性能,适合并行任务。
缺点:需要引入额外的库如 async
。
方案三:使用 AJAX
这种方式将部分渲染逻辑移到客户端,减轻服务器负担,但可能导致首屏加载时间变长。
<!-- index.ejs -->
<div id="content"></div>
<script>
fetch('/api/data')
.then(response => response.json())
.then(data => {
document.getElementById('content').innerHTML = renderTemplate(data);
});
</script>
优点:减少服务器压力,提升用户体验。 缺点:增加客户端复杂度,可能影响 SEO。
推荐方案
并发执行 + async 库:这种方式可以同时利用服务器资源,提高响应速度,又保持代码简洁。推荐使用这种方法,尤其是当你的应用中有很多类似的场景需要处理。
const async = require('async');
app.get('/', function(req, res) {
const tasks = [
function(callback) { fn1(req, res, callback); },
function(callback) { fn2(req, res, callback); },
function(callback) { fn3(req, res, callback); }
];
async.parallel(tasks, function(err, results) {
if (err) return res.status(500).send(err);
res.render('index', { /* 数据 */ });
});
});
这样既保证了性能,又保持了代码的可读性和可维护性。
fn1,fn2,fn3不再执行完,不能render吧?
使用流程控制模块来控制流程 比如async等
bigpipe
what is this
对于首页这种逻辑较多的页面,可以采用异步并行处理的方式来优化性能和代码可维护性。推荐使用并发执行的方式,确保所有异步任务完成后统一渲染页面。这里可以通过async
库或者Promise.all
来实现并发执行,这样可以保证首页加载时所有必要的数据都已准备好。
示例代码(使用Promise.all
)
const express = require('express');
const app = express();
const ejs = require('ejs');
// 定义异步函数fn1, fn2, fn3
async function fetchData1() {
// 模拟异步操作,例如数据库查询
return new Promise(resolve => setTimeout(() => resolve({ data: 'data1' }), 500));
}
async function fetchData2() {
return new Promise(resolve => setTimeout(() => resolve({ data: 'data2' }), 400));
}
async function fetchData3() {
return new Promise(resolve => setTimeout(() => resolve({ data: 'data3' }), 600));
}
app.get('/', async (req, res) => {
try {
const [data1, data2, data3] = await Promise.all([fetchData1(), fetchData2(), fetchData3()]);
// 渲染EJS模板,并传递数据
res.render('index', { data1, data2, data3 });
} catch (error) {
console.error(error);
res.status(500).send('Internal Server Error');
}
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
解释
- 异步函数:
fetchData1
,fetchData2
, 和fetchData3
是三个模拟的异步数据获取函数。 - 并发执行:通过
Promise.all
,这三个函数会被并发执行,而不是按顺序执行。当所有函数都完成时,才会继续下一步。 - 数据传递:将所有获取的数据传递给 EJS 模板进行渲染。
- 错误处理:使用
try...catch
来捕获可能发生的错误,避免服务器崩溃。
这种方式可以显著提高首页加载速度,并保持代码清晰易维护。