Nodejs基于Express4的动态页面静态化
来源:互联网 发布:nginx mac 安装 编辑:程序博客网 时间:2024/05/12 13:15
Nodejs基于Express4的动态页面静态化
上个星期在慕课网上提了个问: Express4开发的动态页面访问好慢的说? 不幸的是并没有得到可行的回答,周末自己折腾了一番,一并将 小站(花满楼) 的几个页面全部静态化了;事后想了想,虽不是什么特别标准好的搞法,但纠结这么久了,这个问题终于有办法了,还是有些欣慰的;
一开始页面都是动态的,由jade模板render出来的,可不明白为什么不论页面内容多少,打开都至少要一秒多。。。 ;后来专门弄个站点作为静态资源站,缓存加gzip(Nodejs打造静态资源服务器与文件上传 );OK,静态资源现在没啥大问题了;可是页面打开速度并不理想,那后台再压一遍吧,来个app.use(compress());事实证明并没啥明显效果;郁闷的我刚学点Nodejs,咋就碰到这无语的问题呢,百度好久,呵呵。。。最后只想到一个办法了,参照静态资源站的搞法,将jade编译成html,把动态页面转成静态资源来对待,会不会像加载静态资源一样快呢!答案是肯定的!!!
就我的博客站点来说,现在面临两个问题:一是直接将原来的jade编译,保留动态数据;二是现将动态数据剔除,再编译为html,由ajax页面加载后请求数据;我选择了前者,因为这样能在静态页面上保留最新的数据,而后者由js后面渲染上去的对SEO很不好;呵呵,而实际上这两种方法我都没用,因为就这点水平来说,在express的框架里,并没听说这种搞法,我自然就无从下手了,只是理想上的可行方案;
那咋办呢?好吧,原谅我选择了放弃express内置的模板,稍作整理后,Gulp(gulp-jade模块)直接将那些jade全编译为html( 前端自动化之神器 — Gulp ),我是这样想的,将这些编译后的html做为一种类似模板的模块,在routes里还是原来那样拿数据,将拿到的数据作为变量传递到html类模板那个模块对应的接口,然后将返回的html生成一个真正的静态页面,这样,原来的jade,在router不变的情况下,直接生成到对应目录了;上面说过要像加载静态资源一样加载页面,才可能够快;
Gulpfile.js
1 var jade=require('gulp-jade');2 3 gulp.task('jade',function() {4 gulp.src('./views/bokeDetail.jade')5 .pipe(jade({pretty:true}))6 .pipe(gulp.dest('./public/famanoder/')); 7 });
bokeDetail.templ.js
1 var html=function(id,title,subtitle,time,from,contents){2 //传递动态数据3 return '<html><head></head><body>'+动态数据+'</body></html>';4 }5 //片段,实际情况而定
bokeDetail.js(router)
1 //...... 2 //引入对应静态模块 3 var boketempl=require('./templs/bokeDetail.templ.js); 4 5 //依旧读取数据 6 //传递数据:如,id,title,content,comments 7 //生成静态页面到指定目录 8 function createStaticPage(id,title,content,comments,fn){ 9 var path='./public/famanoder/';10 var html=boketempl(id,title,content,comments);11 var ws=fs.createWriteStream(path+id+'.html');12 ws.write(html,function(err) {13 console.log('writePage:'+path+id+'.html');14 fn&&fn();15 });16 ws.on('drain',function() {17 ws.end();18 });19 }
ok,程序执行后静态页面就会带着动态数据生成到public下的famanoder目录了;下面还是在bokeDetail.js(router)里将response直指上面生成的静态页面;
1 var pathname=url.parse(req.url).pathname; 2 var realpath='./public/famanoder/'+pathname.substr(pathname.lastIndexOf('/')+1)+'.html'; 3 var type='text/html'; 4 var extname='html'; 5 fs.exists(realpath,function(exist){ 6 if(!exist){console.log(101); 7 res.writeHead(404,{ 8 'content-type':'text/plain' 9 });10 res.write('The Resourse '+pathname+' was Not Found!');11 res.end();12 }else{13 fs.readFile(realpath,'binary',function(err,file){14 console.log(11);15 if(err){16 res.writeHead(500,{17 'content-type':'text/plain'18 });19 res.end();20 }21 if(extname.match(config.fileMatch)){22 var expires=new Date();23 expires.setTime(expires.getTime()+config.maxAge*1000);24 res.setHeader('Expires',expires.toUTCString());25 res.setHeader('cache-control','max-age='+config.maxAge);26 }27 fs.stat(realpath,function(err,stat){28 var lastModified=stat.mtime.toUTCString();29 res.setHeader('Last-Modified',lastModified);30 31 if(req.headers['if-modified-since']&&lastModified==req.headers['if-modified-since']){32 console.log(0);33 res.writeHead(304,{34 'content-type':type35 });36 res.end();37 }else{38 var raw=fs.createReadStream(realpath);39 var acceptEncoding=req.headers['accept-encoding']||'';40 var matched=extname.match(/css|js|html/ig);41 if(matched&&acceptEncoding.match(/\bgzip\b/)){42 console.log(1);43 res.writeHead(200,{44 'content-type':type,45 'Content-Encoding':'gzip'46 });47 raw.pipe(zlib.createGzip()).pipe(res);48 }else if(matched&&acceptEncoding.match(/\bdeflate\b/)){49 console.log(2);50 res.writeHead(200,{51 'content-type':type,52 'Content-Encoding':'deflate'53 });54 raw.pipe(zlib.createDeflate()).pipe(res);55 }else{56 console.log(3);57 res.writeHead(200,{58 'content-type':type59 });60 raw.pipe(res);61 }62 }63 });64 });65 }66 });
再次访问详情页,看看秒开了吧,纯静态的,路由没变,url没改,维护也很简单,只要改下bokeDetail.templ.js就可以了;没办法啊,可能在大侠眼里这样很愚蠢,就当逗您一笑吧;类似这种搞法,现在小站全部页面都静态化了,而且完全照顾到了SEO;
好吧,其实还遗留了一个重要问题:就博客详情来说,原来如果有大批博客,现在怎么批量转呢,其实我是在博客编辑好后提交时顺便生成静态页面的,为了详情页再快点。。。 ;问题来了,在这之前如果我有几百上千篇博客(当然我这个小前端还远没达到这么丰硕的成果),我不得每篇博客重新编辑提交一次;吓死宝宝了啊,别急,新建一个update.js直接批量生成吧,快的很!
1 Artical 2 .find({}).exec(function(err,docs) { 3 update(err,docs); 4 }); 5 6 function update(err,docs) { 7 err&&console.log(err); 8 for(var i=0;i<docs.length;i++){ 9 (function(i){10 createStaticFile(docs[i]._id,docs[i].title,docs[i].subtitle,docs[i].time,docs[i].from,docs[i].contents,function() {11 console.log((i+1)+'/'+docs.length+':updated');12 if (i==docs.length-1) {13 res.render('page/fifity',{14 title:'updateBokes',15 docs:docs.length16 });17 };18 })19 })(i);20 }21 }
其他牛逼启动更新的方式就不多讲了,
那么该轮到优化服务器和数据库了吧;好吧。。。我后端渣渣,服务器更不谈了,暂且就这样吧,毕竟几十块钱的服务器;小前端刚学Nodejs,诸多不足,望大侠路过指导
- Nodejs基于Express4的动态页面静态化
- 基于动态页面的静态页面实现
- 基于动态页面的静态页面实现
- 基于动态页面的静态页面实现
- nodejs基于express4+mysql+express-controller的mvc框架
- nodejs动态视图助手在Express4.x下的问题
- google优化(SEO)基于动态页面的静态页面实现
- Asp.Net基于动态页面的静态页面实现
- Asp.Net基于动态页面的静态页面实现
- 动态页面静态化的静态化
- nodejs+express4.X的文件下载
- 基于Nodejs+express4+Mongodb+Angularjs建立web项目
- 基于Nodejs+express4+Mongodb+Angularjs建立web项目
- 动态页面静态化
- 动态页面静态化
- 动态页面静态化
- 动态页面静态化
- 动态页面静态化
- win7 debugview 打印内核信息
- 【Node.js】'readline' 逐行读取、写入文件内容
- 面试题10
- Window程序的结构--学习笔记
- 二进制
- Nodejs基于Express4的动态页面静态化
- 基础概念:SIP,PJSIP,RTP,SDL
- 在正式提交测试前的代码检查
- 8.2016 物电学院 电气工程及其自动化 辛雅松 15050341033
- Maven打包中出现[INFO] pamirs-1.0.0/lib/pamirs-area-1.0.1.jar already added, skipping
- Lua_第25章 调用 C 函数
- 将十进制数转换成二进制数
- nyoj zb的生日--325
- POJ 1979 Red and Black