提交 8f478189 编写于 作者: A a1511870876
此差异已折叠。
Create a new repository on the command line
touch README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin https://github.com/a1511870876/secondWorks.git
git push -u origin master
Push an existing repository from the command line
git remote add origin https://github.com/a1511870876/secondWorks.git
git push -u origin master
\ No newline at end of file
Create a new repository on the command line
touch README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin https://github.com/a1511870876/secondWorks.git
git push -u origin master
Push an existing repository from the command line
git remote add origin https://github.com/a1511870876/secondWorks.git
git push -u origin master
\ No newline at end of file
......@@ -4,7 +4,6 @@
代码注释已经非常详细,就不多做说明,需要的朋友自己查看代码即可,主文件Mail.js,截图文件capturePart1.js,capturePart2.js,capturePart3.js,这里只展示了capturePart1.js其他两个类似。值得注意的是有登录权限的网站一定要设置Cookie,需要截取高质量图片的话截取时间一定设置长一些。
### Mail.js
```
* 定时发送邮件功能说明:
* node.js必备安装模块:node_modules-->phantomjs,nodemailer,node-schedule,moment
* 涉及JS文件:route-->mail.js,public-->js-->capturePart1.js,capturePart2.js,capturePart3.js
......@@ -22,7 +21,6 @@
* 改变截图功能请修改public-->js-->server.js
* 改变定时功能请修改变量rule
* ------Sweety
```
//组件引入开始
var schedule = require("node-schedule");
var path = require('path');
......@@ -30,7 +28,6 @@ var childProcess = require('child_process');
var phantomjs = require('phantomjs');
var nodemailer = require("nodemailer");
var moment = require("moment");
```
//组件引入结束
/*--------------------------------------------------------------------------------------------------------------------------------------------*/
//变量定义开始
......@@ -165,9 +162,7 @@ function sent(){
});
}
//nodemailer发送邮件结束
function changeData(){
}
/*---------------------------------------------------------------------------------------------------------------------------------------------*/
```
......
## Package管理
后台npm
(不多说)
前台bower
简介:
Bower的功能类似于Nodejs中的npm或者Python中的pip,用于web包管理,如果越来越多得开源项目都托管在github上,bower只需要将github上项目加上一个配置文件既可以使用bower方式使用安装包。作为包管理,bower能提供添加新web包,更新web包,删除web包,发布web包功能,管理包依赖。web包通常认为由html+css+javascript构成。使用:
根据上面的简介描述,bower依赖于nodejs,下载安装依赖库实际上是使用git进行下载,因此使用bower前确保安装了Node和Git环境,并且建议使用git bash命令行来执行bower install命令。
(常用npm、node、大神略过此段)另外可能我们需要在任何目录使用bower命令的话,需要配置npm环境变量,这一步很重要,不然会提示“bower”不是内部或外部命令,配置npm环境变量就很简单了,在path目录下添加npm全局的包的安装路径但不包含node_modules目录,另外新建NODE_PATH,值为全局的包的安装路径包含node_modules目录,例如:path:D:\node,NODE_PATH:D:\node\node_modules,这样我们npm install XXX –g的安装包才能在全局使用,不会出现提示“XXX不是内部或外部命令”。
好了,废话不多说,bower使用就很简单了:
安装bower
npm install bower -g
在项目目录中运行
bower install jquery
运行成功之后项目中会多出components文件夹,文件夹中jquery文件夹,jquery文件夹里面就有最新的jquery文件。
这还不能说明他NB的地方,试想下面的场景,jQuery升级了,是不是再down一次jQuery呢?bower可以这样做:
bower update jquery
就可以自动升级到最新版的jquery了。
再假设我们需要使用bootstrap,bootstrap可不是一个文件,有css,js还有图片。js还依赖于jQuery,如果使用bower:
bower install bootstrap
bower会自动从github上down最新的代码,而且,会自动将依赖包jquery也down一次。
如果你发布程序的时候不想把一些依赖的库发布上去(主要原因是太大了 – – ),可以在项目根目录下生成一个 bower.json 文件用来管理依赖。
在项目目录下执行
bower init
按照提示操作就好,这样子会生成一个bower文件
安装 jquery
bower install jquery --save
这样子 bower.json 文件就会写入一个 Jquery的依赖项
别人只要在项目目录下输入
bower install
就会自动安装了
## Package管理
  后台npm
  (不多说)
  前台bower
  简介:
  Bower的功能类似于Nodejs中的npm或者Python中的pip,用于web包管理,如果越来越多得开源项目都托管在github上,bower只需要将github上项目加上一个配置文件既可以使用bower方式使用安装包。作为包管理,bower能提供添加新web包,更新web包,删除web包,发布web包功能,管理包依赖。web包通常认为由html+css+javascript构成。使用:
  根据上面的简介描述,bower依赖于nodejs,下载安装依赖库实际上是使用git进行下载,因此使用bower前确保安装了Node和Git环境,并且建议使用git bash命令行来执行bower install命令。
  (常用npm、node、大神略过此段)另外可能我们需要在任何目录使用bower命令的话,需要配置npm环境变量,这一步很重要,不然会提示“bower”不是内部或外部命令,配置npm环境变量就很简单了,在path目录下添加npm全局的包的安装路径但不包含node_modules目录,另外新建NODE_PATH,值为全局的包的安装路径包含node_modules目录,例如:path:D:\node,NODE_PATH:D:\node\node_modules,这样我们npm install XXX –g的安装包才能在全局使用,不会出现提示“XXX不是内部或外部命令”。
  好了,废话不多说,bower使用就很简单了:
  安装bower
  npm install bower -g
  在项目目录中运行
  bower install jquery
  运行成功之后项目中会多出components文件夹,文件夹中jquery文件夹,jquery文件夹里面就有最新的  jquery文件。
  这还不能说明他NB的地方,试想下面的场景,jQuery升级了,是不是再down一次jQuery呢?bower可以这样做:
  bower update jquery
  就可以自动升级到最新版的jquery了。
  再假设我们需要使用bootstrap,bootstrap可不是一个文件,有css,js还有图片。js还依赖于jQuery,如果使用bower:
  bower install bootstrap
  bower会自动从github上down最新的代码,而且,会自动将依赖包jquery也down一次。
  如果你发布程序的时候不想把一些依赖的库发布上去(主要原因是太大了 – – ),可以在项目根目录下生成一个 bower.json 文件用来管理依赖。
  在项目目录下执行
  bower init
  按照提示操作就好,这样子会生成一个bower文件
  安装 jquery
  bower install jquery --save
  这样子 bower.json 文件就会写入一个 Jquery的依赖项
  别人只要在项目目录下输入
  bower install
  就会自动安装了
## 正则表达式学习
.就是一个占位符,匹配除'\n'之外的任意字符。
*匹配前面字符0次或任意次
?匹配前一个字符0次或1次
-----------------------------------------------------------------
上面的内容全部只需要了解即可,需要掌握的只有下面这一种组合方式(.*?)
.* 贪心算法,尽可能多的匹配,像一个胖子尽可能多的吃
.*?非贪心算法,尽可能少的匹配,像一个婴儿少量多餐
## 正则表达式学习
\.就是一个占位符,匹配除'\n'之外的任意字符。
\*匹配前面字符0次或任意次
?匹配前一个字符0次或1次
___
上面的内容全部只需要了解即可,需要掌握的只有下面这一种组合方式(.*?)
.* 贪心算法,尽可能多的匹配,像一个胖子尽可能多的吃
.*?非贪心算法,尽可能少的匹配,像一个婴儿少量多餐
```
例如:code = 'hhosahfoxxIxxohofhjosfhxxlovexxoruowhntlnmlxxyouxxljh'
re.findall('xx.*xx',code)匹配第一个xx到最后一个xx,即xxIxxohofhjosfhxxlovexxoruowhntlnmlxxyouxx
re.findall('xx.*?xx',code)匹配结果['xxIxx','xxlovexx','xxyouxx']
......@@ -17,8 +18,10 @@
I
love
you
-----------------------------------------------------------------
re.S
```
___
re.S
```
例如:code = 'hhosahfoxxI
xxohofhjosfhxxlovexxoruowhntlnmlxxyouxxljh'
d = re.findall('xx(.*?)xx',code)
......@@ -35,8 +38,10 @@ re.S
re.I 使匹配对大小写不敏感
re.L 做本地化识别(locale-aware)匹配
re.M 多行匹配,影响 ^ 和 $
-----------------------------------------------------------------
对比findall与search的区别
```
___
对比findall与search的区别
```
s2 = 'asdfxxIxx123xxlovexxdfdasdfxxIxx123xxlovexxdfd'
f = re.search('xx(.*?)xx123xx(.*?)xx',s2)
print f.group(2)
......@@ -53,13 +58,17 @@ print f2
输出结果:
[('I', 'love'), ('I', 'love')]
注:findall返回一个list,有多次匹配在list中嵌套tuple(元组)
-----------------------------------------------------------------
```
___
sub的使用
```
s = '123abccssfadjfdj123'
output = re.sub('123(.*?)123','123%d123%789',s)
print output
-----------------------------------------------------------------
```
___
常用技巧
```
1、在确定只有一个内容时,使用search方法可以提高效率
2、不要要使用compile
str = 'asdfxxIxx123xxlovexxdfdasdfxxIxx123xxlovexxdfd'
......@@ -71,8 +80,10 @@ a = 'asdsds123456fasd888fas'
b = re.findall('(\d+)',a)
print b
执行结果:['123456','888']
-----------------------------------------------------------------
```
___
总结
```
re.match 尝试从字符串的起始位置匹配一个模式。
re.search 扫描整个字符串并返回第一个成功的匹配。
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。
......@@ -80,15 +91,12 @@ re.sub用于替换字符串中的匹配项。
re.split按照能够匹配的子串将string分割后返回列表。
re.findall搜索string,以列表形式返回全部能匹配的子串。
re.finditer搜索string,返回一个顺序访问每一个匹配结果(Match对象)的迭代器。
re.I 使匹配对大小写不敏感
re.L 做本地化识别(locale-aware)匹配
re.M 多行匹配,影响 ^ 和 $
re.S 使 . 匹配包括换行在内的所有字符
re.U 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.
re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。
. 匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[.\n]' 的模式。
\d 匹配一个数字字符。等价于 [0-9]。
\D 匹配一个非数字字符。等价于 [^0-9]。
......@@ -96,7 +104,6 @@ re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\w 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。
\W 匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。
[Pp]ython 匹配 "Python" 或 "python"
rub[ye] 匹配 "ruby" 或 "rube"
[aeiou] 匹配中括号内的任意一个字母
......@@ -106,7 +113,6 @@ rub[ye] 匹配 "ruby" 或 "rube"
[a-zA-Z0-9] 匹配任何字母及数字
[^aeiou] 除了aeiou字母以外的所有字符
[^0-9] 匹配除了数字外的字符
. 点 匹配单个任意字符
[...] 字符组 匹配单个字符组出现的字符
[^...] 排除型字符组 匹配单个未在字符组出现的字符
......@@ -120,10 +126,9 @@ rub[ye] 匹配 "ruby" 或 "rube"
| | 多选结构
(...) 括号 用处有三,请看上面
\1.\2 反向引用 对括号捕捉到的分组进行引用。
括号
如果需要使用分组,或者对一个分组进行量词限定,就可以使用它了。使用括号以后,可以:
在后面进行反向引用
作为一个子表达式使用
限制多选结构
-----------------------------------------------------------------
\ No newline at end of file
```
\ No newline at end of file
### 功能
每天定时截图,并把截到的图片自动通过邮件发送。
### 说明
代码注释已经非常详细,就不多做说明,需要的朋友自己查看代码即可,主文件Mail.js,截图文件capturePart1.js,capturePart2.js,capturePart3.js,这里只展示了capturePart1.js其他两个类似。值得注意的是有登录权限的网站一定要设置Cookie,需要截取高质量图片的话截取时间一定设置长一些。
### Mail.js
```
/************************************************************************************************************
* 定时发送邮件功能说明:
* node.js必备安装模块:node_modules-->phantomjs,nodemailer,node-schedule,moment
* 涉及JS文件:route-->mail.js,public-->js-->capturePart1.js,capturePart2.js,capturePart3.js
* 截图保存地址:public-->images-->mainPage.jpeg(1600*4200)
* 截图url:http://www.***********.com
* 程序主要思路:
* (1)phantomjs截图-->参照http://phantomjs.org/
* (2)nodemailer发送邮件-->参照https://www.npmjs.com/package/nodemailer
* (3)node-schedule定时-->参照https://www.npmjs.com/package/node-schedule
* 注意:
* 改变发件服务器请修改SMTP
* 改变收件人请修改变量receiver
* 改变邮件内容请修改变量html
* 改变邮件附加图片和附件请修改attachments
* 改变截图功能请修改public-->js-->server.js
* 改变定时功能请修改变量rule
* ------Sweety
***************************************************************************************************************/
//组件引入开始
var schedule = require("node-schedule");
var path = require('path');
var childProcess = require('child_process');
var phantomjs = require('phantomjs');
var nodemailer = require("nodemailer");
var moment = require("moment");
//组件引入结束
/*--------------------------------------------------------------------------------------------------------------------------------------------*/
//变量定义开始
var today; //今天开始时间
var binPath = phantomjs.path; //获取phantomjs.exe路径
var jsPath = process.cwd()+"/public/js/"; //获取server.js所在目录
var childArgs;
//capturePart3();
//capturePart1();
//变量定义结束
/*--------------------------------------------------------------------------------------------------------------------------------------------*/
//主程序开始
var rule = new schedule.RecurrenceRule(); //schedule定时器
rule.hour = 11;
rule.minute = 0;
rule.second = 0; //定时器规则设定(每天11点触发事件)
var j = schedule.scheduleJob(rule, function(){
var now = moment();
today = now.clone().add(-1, 'days').format('YYYY-MM-DD');
capturePart1(); //触发截图事件(邮件发送功能包含在截图事件里边)
});
//主程序结束
/*---------------------------------------------------------------------------------------------------------------------------------------------*/
//phantomjs截图开始(第一张)
function capturePart1(){
childArgs = [
path.join(jsPath, 'serverPart1.js'), //server.js
' https://www.hao123.com ' //要截图的url
];
childProcess.execFile(binPath, childArgs, function(err, stdout, stderr) {
if(err)
{
console.log(err); //打印错误信息
}else{
console.log("Captured Part1 Successful !!"); //打印正确信息
capturePart2();
}
});
}
//phantomjs截图结束(第一张)
//phantomjs截图开始(第二张)
function capturePart2(){
childArgs = [
path.join(jsPath, 'serverPart2.js'), //server.js路径
'https://www.hao123.com ' //要截图的url
];
childProcess.execFile(binPath, childArgs, function(err, stdout, stderr) {
if(err)
{
console.log(err); //打印错误信息
}else{
console.log("Captured Part2 Successful !!"); //打印正确信息
capturePart3();
}
});
}
//phantomjs截图结束(第二张)
//phantomjs截图开始(第三张)
function capturePart3(){
childArgs = [
path.join(jsPath, 'serverPart3.js'), //server.js路径
' https://www.hao123.com ' //要截图的url
];
childProcess.execFile(binPath, childArgs, function(err, stdout, stderr) {
if(err)
{
console.log(err); //打印错误信息
}else{
console.log("Captured Part3 Successful !!"); //打印正确信息
sent(); // 触发发送邮件事件
}
});
}
//phantomjs截图结束(第三张)
/*-------------------------------------------------------------------------------------------------------------------------------------------------*/
//nodemailer发送邮件开始
function sent(){
var imgPart1 = fs.readFileSync(process.cwd()+"/public/images/mainPagePart1.jpeg"); //图片来源
var imgPart2 = fs.readFileSync(process.cwd()+"/public/images/mainPagePart2.jpeg"); //图片来源
var imgPart3 = fs.readFileSync(process.cwd()+"/public/images/mainPagePart3.jpeg"); //图片来源
var smtpTransport = nodemailer.createTransport("SMTP",{ //邮件SMTP设定(发送邮箱服务器必须开启SMTP)
host: "smtp.xxxxx.com", // 主机
secureConnection: false, // 不使用 SSL
port: 587, // SMTP 端口
auth: {
user: "xxxxx@xxxx.com", //用户名
pass: "xxxxxx" //密码
}
});
var html = '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">' +
'XX好:</br>'+
'&nbsp;&nbsp;下面为【XXXX】日报汇报('+today+')的内容,请参考</br>' +
'&nbsp;&nbsp;(日报详细信息请点击<a href="#" onclick="changeData();">此处登陆</a>查看)'+
'</br>' +
'<img src="cid:img1" id="img1">'+
'<img src="cid:img2" id="img2">'+
'<img src="cid:img3" id="img3">';//邮件内容(html代码),img唯一指定地址对应cid(见mailOptions设定)
var receiver = "xxx@xxx.com";//收件人列表
var cc = "xxxx@xxxx.com,xxx@xxx.com,xxx@xxxx.com"; //抄送人列表
var bcc = "xxx@xxxx.com,xxx@xxxx.com"; //密抄送人列表
var mailOptions = { //邮件内容选项设定
from: "<xxx@xxxx.com>", //发件地址
//to: "xxx@xxxx.com",
to: receiver, //收件人
cc:cc, //抄送人
bcc:bcc, //密抄送人
subject:"【XXXX】日报汇报("+today+")", //邮件主题
text: "【XXXX】日报汇报("+today+")", // plaintext body
html:html, //html内容
attachments: [
{
filename: 'mainPagePart1.jpeg', //图片名称
contents: imgPart1, //图片来源
cid: 'img1' //插入图片标识
},{
filename: 'mainPagePart2.jpeg', //图片名称
contents: imgPart2, //图片来源
cid: 'img2' //插入图片标识
},{
filename: 'mainPagePart3.jpeg', //图片名称
contents: imgPart3, //图片来源
cid: 'img3' //插入图片标识
}
]
};
smtpTransport.sendMail(mailOptions, function(error, response){//发送邮件
if(error){
console.log(error); //打印错误信息
}else{
console.log("Sent Successful !!"); //打印正确信息
}
});
}
//nodemailer发送邮件结束
function changeData(){
### 让你的 Node.js 应用跑得更快的 10 个技巧
引用地址:[http://www.oschina.net/translate/10-tips-make-node-js-web-app-faster](http://www.oschina.net/translate/10-tips-make-node-js-web-app-faster)
英文原文:[http://www.sitepoint.com/10-tips-make-node-js-web-app-faster](http://www.sitepoint.com/10-tips-make-node-js-web-app-faster)
个人技术分享GitHub地址:[https://github.com/a1511870876/studyFiles](https://github.com/a1511870876/studyFiles)
  Node.js 受益于它的事件驱动和异步的特征,已经很快了。但是,在现代网络中只是快是不行的。如果你打算用 Node.js 开发你的下一个Web 应用的话,那么你就应该无所不用其极,让你的应用更快,异常的快。本文将介绍 10 条,经过检验得知可大大提高 Node 应用的技巧。废话不多说,让我们逐条来看看。
### 1. 并行
  创建 Web 应用的时候,你可能要多次调用内部 API 来获取各种数据。比如说,假设在 Dashboard 页面上,你要执行下面这几个调用:
  用户信息 -getUserProfile().
  当前活动 -getRecentActivity().
  订阅内容 -getSubscriptions().
  通知内容 -getNotifications().
  为了拿到这些信息,你应该会为每个方法创建独立的中间件,然后将它们链接到 Dashboard 路由上。不过问题是,这些方法的执行是线性的,上一个没结束之前下一个不会开始。可行解决案是并行调用它们。
  如你所知由于异步性,Node.js 非常擅长并行调用多个方法。我们不能暴殄天物。我上面提到的那些方法没有依赖性,所以我们可以并行执行它们。这样我们可以削减中间件数量,大幅提高速度。
  我们可以用 async.js 来处理并行,它是一个专门用来调教 JavaScript 异步的 Node 模块。下面代码演示怎样用 async.js 并行调用多个方法的:
```
function runInParallel() {
async.parallel([
getUserProfile,
getRecentActivity,
getSubscriptions,
getNotifications
], function(err, results) {
//This callback runs when all the functions complete
});
}
/*---------------------------------------------------------------------------------------------------------------------------------------------*/
```
### capturePart1.js
  如果你想更深入了解 async.js ,请移步它的 GitHub 页面。
### 2. 异步
  根据设计 Node.js 是单线程的。基于这点,同步代码会堵塞整个应用。比如说,多数的文件系统 API 都有它们的同步版本。下面代码演示了文件读取的同步和异步两种操作:
```
//phantomjs截图
var page = require('webpage').create(),
system = require('system'),
address;
page.viewportSize = { width:1920, height: 1080};
page.clipRect = { top: 200, left: 210, width: 1680, height: 1530 };
page.customHeaders={"Cookie":"koa:sess=e*******=;koa:sess.sig=pjadZtLAVtiO6-Haw1vnZZWrRm8"};
if (system.args.length === 1) {
phantom.exit(1);
} else {
address = system.args[1];
page.open(address, function (status) {
// Asynchronous
fs.readFile('file.txt', function(err, buffer) {
var content = buffer.toString();
});
// Synchronous
var content = fs.readFileSync('file.txt').toString();
```
  不过要是你执行那种长时间的阻塞操作,主线程就会被阻塞到这些操作完成为止。这大大降低你应用的性能。所以,最好确保你的代码里用的都是异步版本 API,最起码你应该在性能节点异步。而且,你在选用第三方模块的时候也要很小心。因为当你想方设法把同步操作从你代码中剔除之后,一个外部库的同步调用会让你前功尽弃,降低你的应用性能。
### 3. 缓存
  如果你用到一些不经常变化的数据,你应该把它们缓存起来,改善性能。比如说,下面的代码是获取最新帖子并显示的例子:
```
var router = express.Router();
router.route('/latestPosts').get(function(req, res) {
Post.getLatest(function(err, posts) {
if (err) {
throw err;
}
res.render('posts', { posts: posts });
});
});
```
  如果你不经常发贴的话,你可以把帖子列表缓存起来,然后一段时间之后再把它们清理掉。比如,我们可以用 Redis 模块来达到这个目的。当然,你必须在你的服务器上装 Redis。然后你可以用叫做 node_redis 的客户端来保存键/值对。下面的例子演示我们怎么缓存帖子:
```
var redis = require('redis'),
client = redis.createClient(null, null, { detect_buffers: true }),
router = express.Router();
router.route('/latestPosts').get(function(req,res){
client.get('posts', function (err, posts) {
if (posts) {
return res.render('posts', { posts: JSON.parse(posts) });
}
Post.getLatest(function(err, posts) {
if (err) {
throw err;
}
client.set('posts', JSON.stringify(posts));
res.render('posts', { posts: posts });
});
}
setTimeout(function() {
console.log("");
console.log("### STEP 5: Close page and shutdown (with a delay)");
page.render('./public/images/mainPagePart1.jpeg', {format: 'jpeg', quality: '100'});
page.close();
setTimeout(function(){
phantom.exit();
}, 3000);
}, 19000);
```
\ No newline at end of file
});
});
```
  看到了吧,我们首先检查 Redis 缓存,看看是否有帖子。如果有,我们从缓存中拿这些帖子列表。否则我们就检索数据库内容,然后把结果缓存。此外,一定时间之后,我们可以清理 Redis 缓存,这样就可以更新内容了。
### 4. gzip 压缩
  开启 gzip 压缩对你的 Web 应用会产生巨大影响。当一个 gzip 压缩浏览器请求某些资源的时候,服务器会在响应返回给浏览器之前进行压缩。如果你不用 gzip 压缩你的静态资源,浏览器拿到它们可能会花费更长时间。
  在 Express 应用中,我们可以用内建 express.static() 中间件来处理静态内容。此外,还可以用 compression 中间件压缩和处理静态内容。下面是使用例:
```
var compression = require('compression');
app.use(compression()); //use compression
app.use(express.static(path.join(__dirname, 'public')));
```
### 5. 如果可以,在用客户端渲染
  现在有超多功能强劲的客户端 MVC/MVVM 框架,比如说 AngularJS, Ember, Meteor, 等等,构建一个单页面应用变得非常简单。基本上,你只要公开一个 API,返回 JSON 响应给客户端就可以了,而不需要在服务端渲染页面。在客户端,你可以用框架来组织 JSON 然后把它们显示在 UI 上。服务端只发送 JSON 响应可以节省带宽,改善性能,因为你不需要在每个响应里面都返回布局标记了,对吧,你只需要返回纯 JSON,然后在客户端渲染它们。
  看下我的这个教程,它是关于怎样用 Express 4 公开一个 RESTful APIs的。我还写了另一篇教程,演示了怎样把这些 APIs 和 AngularJS 结合起来。
### 6. 不要在 Sessions 存储太多数据
  典型的 Express 页面应用, Session 数据默认是保存在内存中的。当你把太多数据保存在 Session 的时候,会导致服务器开销显著增大。所以,要么你切换到别的储存方式来保存 Session 数据,要么尽量减少存储在 Session 中的数据量。
  比如说,当用户登录到你的应用的时候,你可以只在 Session 中保存他们的 ID 而不是整个用户数据对象。还有,对于那些你能够从 id 拿到对象的查询,你应该会喜欢用 MongoDB 或者 Redis 来存储 session 数据。
### 7. 优化查询
  假设你有个博客,你要在主页上显示最新帖子。你可能会通过 Mongoose 这样取数据:
```
Post.find().limit(10).exec(function(err, posts) {
//send posts to client
});
```
  不过问题是 Mongoose 的 find() 方法会把对象的所有字段都查询出来,而许多字段在主页上并不要求。比如说,commentsis 保存的是特定帖子的回复。我们不需要显示文章回复,所以我们可以在查询的时候把它给剔除掉。这无疑会提高速度。可以像这样优化上面那条查询:
```
Post.find().limit(10).exclude('comments').exec(function(err, posts) {
//send posts to client
});
```
### 8. 用标准的 V8 方法
  集合上的一些操作,比如 map,reduce,和 forEach 不一定支持所有浏览器。我们可以通过前台的库解决部分浏览器兼容性问题。但对于 Node.js,你要确切知道 Google 的 V8 JavaScript 引擎支持哪些操作。这样,你就可以在服务端直接用这些内建方法来操作集合了。
### 9. 在 Node 前面用 Nginx
  Nginx 是个微小型轻量 Web 服务器,用它可以降低你的 Node.js 服务器的负载。你可以把静态资源配置到 nginx 上,而不是在 Node 上。你可以在 nginx 上用 gzip 压缩响应,让所有的响应都变得更小。所以,如果你有个正在营运的产品,我觉得你应该会想用 nginx 来改善运行速度的。
### 10. 打包 JavaScript
  最后,你还可以大大提高页面应用速度,通过把多个 JS 文件打包。当浏览器在页面渲染中碰到 <script\> 元素的时候会被堵塞,直到拿到这个脚本才继续运行(除非设置了异步属性)。比如,如果你的页面有五个 JavaScript 文件,浏览器会发出五个独立的 HTTP 请求来获取他们。如果把这五个文件压缩打包成一个,整体性能将可以大幅提升。CSS 文件也是一样。你可以用诸如 Grunt/Gulp 这样的编译工具来打包你的资源文件。
### 结论
  上面 10 条技巧肯定可以提高你的 Web 应用的速度的。不过,我知道还有改善和优化的空间。如果你有任何改善性能的技巧的话,在回复里告诉我。
\ No newline at end of file
## Html
1、<q></q>短文本引用,自动加双引号,语义是引用。
2、<blockquote></blockquote>长文本引用,自动两端缩进。
3、<br><br />为换行,&nbsp;为空格,<hr />为水平横线。
4、<address></address>地址。
5、<code></code>当代码为一行代码时,你就可以使用<code>标签了。
6、<pre></pre>语言代码段,多行。
7、<table summary="表格简介文本"><caption>标题文本</caption>
8、<a href="目标网址" target="_blank">click here!</a>新建浏览器窗口中打开链接。
9、<a href=”mailto: yy@qq.com?cc=xx@qq.com&bcc=zz@qq.com&subject=主题&body=内容”>发送</a>
(第一个参数用?隔开后边参数用&隔开,cc:抄送。Bcc:密抄送。Subject:标题。Body:内容)
10、<img src= alt= title= > src为图片地址;alt为下载不成功时描述性文本;title为图像可见时图像的描述。
11、<form method="传送方式" action="服务器文件">
12、<textarea rows="行数" cols="列数">文本</textarea>文本域。
13、<input type="radio/checkbox" value="值" name="名称" checked="checked"/>单选框、复选框。同一组的单选按钮,name 取值一定要一致,这样同一组的单选按钮才可以起到单选的作用。
14、<select><option value=”向服务器提交的值” selected=”selected”>显示的值</option></select>下拉框。multiple="multiple"使用下拉列表框进行多选。
15、<input type="submit" value="确定" />按钮,<input type="reset" value="重置" />重置按钮。
16、<label for="控件id名称">当用户单击选中该label标签时,浏览器就会自动将焦点转到和标签相关的表单控件上。
注意:标签的 for 属性中的值应当与相关控件的 id 属性值一定要相同。
## CSS
1、>作用于元素的第一代后代,空格作用于元素的所有后代。>适合包含样式时仅设置第一代后代样式。
2、伪类选择符a:hover{color:red;}鼠标滑过的状态。
3、有些特殊的情况需要为某些样式设置具有最高权值,怎么办?这时候我们可以使用!important来解决。
## Html ##
```
1、<q></q>短文本引用,自动加双引号,语义是引用。
2、<blockquote></blockquote>长文本引用,自动两端缩进。
3、<br><br />为换行,&nbsp;为空格,<hr />为水平横线。
4、<address></address>地址。
5、<code></code>当代码为一行代码时,你就可以使用<code>标签了。
6、<pre></pre>语言代码段,多行。
7、<table summary="表格简介文本">,<caption>标题文本</caption>
8、<a href="目标网址" target="_blank">click here!</a>新建浏览器窗口中打开链接。
9、<a href=”mailto: yy@qq.com?cc=xx@qq.com&bcc=zz@qq.com&subject=主题&body=内容”>发送</a>
(第一个参数用?隔开后边参数用&隔开,cc:抄送。Bcc:密抄送。Subject:标题。Body:内容)
10、<img src=” ” alt=” ” title=” ”> src为图片地址;alt为下载不成功时描述性文本;title为图像可见时图像的描述。
11、<form method="传送方式" action="服务器文件">
12、<textarea rows="行数" cols="列数">文本</textarea>文本域。
13、<input type="radio/checkbox" value="值" name="名称" checked="checked"/>单选框、复选框。同一组的单选按钮,name 取值一定要一致,这样同一组的单选按钮才可以起到单选的作用。
14、<select><option value=”向服务器提交的值” selected=”selected”>显示的值</option></select>下拉框。multiple="multiple"使用下拉列表框进行多选。
15、<input type="submit" value="确定" />按钮,<input type="reset" value="重置" />重置按钮。
16、<label for="控件id名称">当用户单击选中该label标签时,浏览器就会自动将焦点转到和标签相关的表单控件上。
注意:标签的 for 属性中的值应当与相关控件的 id 属性值一定要相同。
```
## CSS ##
```
1、>作用于元素的第一代后代,空格作用于元素的所有后代。>适合包含样式时仅设置第一代后代样式。
2、伪类选择符a:hover{color:red;}鼠标滑过的状态。
3、有些特殊的情况需要为某些样式设置具有最高权值,怎么办?这时候我们可以使用!important来解决。
p{color:red!important;}
p{color:green;}
4、文字排版
字体p{font-family:"Microsoft Yahei";}现在一般网页喜欢设置“微软雅黑”
文字粗体p{font-weight:bold;}
文字斜体p{font-style:italic;}
文字下划线p{text-decoration:underline;}
文字删除线p{text-decoration:line-through;}
文字缩进p{text-indent:2em;} 2em的意思就是文字的2倍大小。
文字行间距p{line-height:1.5em;}
中文间距h1{letter-spacing:50px;} 字母间距h1{word-spacing:50px;}
5、段落排版
对齐h1{text-align:center;} {text-align:left;} {text-align:right;}
6、元素分类
常用的块状元素有:
<div><p><h1>...<h6><ol><ul><dl><table><address><blockquote><form>
常用的内联元素有:
<a><span><br><i><em><strong><label><q><var><cite><code>
常用的内联块状元素有:
<img><input>
7、元素分类--块级元素
每个块级元素都从新的一行开始,并且其后的元素也另起一行。
元素的高度、宽度、行高以及顶和底边距都可设置。
元素宽度在不设置的情况下,是它本身父容器的100%(和父元素的宽度一致),除非设定一个宽度。
将内联元素a转换为块状元素a{display:block;}
8、元素分类--内联元素
和其他元素都在一行上;
元素的高度、宽度及顶部和底部边距不可设置;
元素的宽度就是它包含的文字或图片的宽度,不可改变。
将块状元素设置为内联元素
4、文字排版
字体p{font-family:"Microsoft Yahei";}现在一般网页喜欢设置“微软雅黑”
文字粗体p{font-weight:bold;}
文字斜体p{font-style:italic;}
文字下划线p{text-decoration:underline;}
文字删除线p{text-decoration:line-through;}
文字缩进p{text-indent:2em;} 2em的意思就是文字的2倍大小。
文字行间距p{line-height:1.5em;}
中文间距h1{letter-spacing:50px;} 字母间距h1{word-spacing:50px;}
5、段落排版
对齐h1{text-align:center;} {text-align:left;} {text-align:right;}
6、元素分类
常用的块状元素有:
<div>、<p>、<h1>...<h6>、<ol>、<ul>、<dl>、<table>、<address>、<blockquote> 、<form>
常用的内联元素有:
<a>、<span>、<br>、<i>、<em>、<strong>、<label>、<q>、<var>、<cite>、<code>
常用的内联块状元素有:
<img><input>
7、元素分类--块级元素
每个块级元素都从新的一行开始,并且其后的元素也另起一行。
元素的高度、宽度、行高以及顶和底边距都可设置。
元素宽度在不设置的情况下,是它本身父容器的100%(和父元素的宽度一致),除非设定一个宽度。
将内联元素a转换为块状元素a{display:block;}
8、元素分类--内联元素
和其他元素都在一行上;
元素的高度、宽度及顶部和底部边距不可设置;
元素的宽度就是它包含的文字或图片的宽度,不可改变。
将块状元素设置为内联元素
div{display:inline;}
9、元素分类--内联块状元素
就是同时具备内联元素、块状元素的特点,代码display:inline-block就是将元素设置为内联块状元素。
10、盒子模型—块级标签
盒子和内容间隙叫padding,内边距,有四个方向top,right,bottom,left
盒子和盒子之间得间隙叫margin,外边距,有四个方向top,right,bottom,left
边框border有四个方向top,right,bottom,left
border-style(边框样式)常见样式有:dashed(虚线)| dotted(点线)| solid(实线)。
border-color(边框颜色)中的颜色可设置为十六进制颜色,如:border-color:#888;//前面的井号不要忘掉。
border-width(边框宽度)中的宽度也可以设置为:thin | medium | thick(但不是很常用),最常还是用象素(px)。
简写div{border:2px solid red;}
11、CSS布局模型
布局模型与盒模型一样都是 CSS 最基本、 最核心的概念。
在网页中,元素有三种布局模型:
1)流动模型(Flow)
2)浮动模型 (Float)
3)层模型(Layer)
CSS定义了一组定位(positioning)属性来支持层布局模型。
层模型有三种形式:
1)绝对定位(position: absolute)
2)相对定位(position: relative)
3)固定定位(position: fixed)
绝对定位,相对于父对象真实移动,如果没有父对象,父对象是body
9、元素分类--内联块状元素
就是同时具备内联元素、块状元素的特点,代码display:inline-block就是将元素设置为内联块状元素。
10、盒子模型—块级标签
盒子和内容间隙叫padding,内边距,有四个方向top,right,bottom,left
盒子和盒子之间得间隙叫margin,外边距,有四个方向top,right,bottom,left
边框border有四个方向top,right,bottom,left
border-style(边框样式)常见样式有:dashed(虚线)| dotted(点线)| solid(实线)。
border-color(边框颜色)中的颜色可设置为十六进制颜色,如:border-color:#888;//前面的井号不要忘掉。
border-width(边框宽度)中的宽度也可以设置为:thin | medium | thick(但不是很常用),最常还是用象素(px)。
简写div{border:2px solid red;}
11、CSS布局模型
布局模型与盒模型一样都是 CSS 最基本、 最核心的概念。
在网页中,元素有三种布局模型:
1)流动模型(Flow)
2)浮动模型 (Float)
3)层模型(Layer)
CSS定义了一组定位(positioning)属性来支持层布局模型。
层模型有三种形式:
1)绝对定位(position: absolute)
2)相对定位(position: relative)
3)固定定位(position: fixed)
绝对定位,相对于父对象真实移动,如果没有父对象,父对象是body
.a{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}
相对定位,相对于该元素原始位置便宜,且偏移前的位置还保留不动,覆盖不了前面的div没有偏移前的位置。
固定定位,fixed:表示固定定位,与absolute定位类型类似,但它的相对移动的坐标是视图(屏幕内的网页窗口)本身。不会受文档流动影响。比如固定当前窗口的小广告
12、盒模型简写
margin:10px 15px 12px 14px;/*上设置为10px、右设置为15px、下设置为12px、左设置为14px*/
1、如果top、right、bottom、left的值相同,如下面代码:
相对定位,相对于该元素原始位置便宜,且偏移前的位置还保留不动,覆盖不了前面的div没有偏移前的位置。
固定定位,fixed:表示固定定位,与absolute定位类型类似,但它的相对移动的坐标是视图(屏幕内的网页窗口)本身。不会受文档流动影响。比如固定当前窗口的小广告
12、盒模型简写
margin:10px 15px 12px 14px;/*上设置为10px、右设置为15px、下设置为12px、左设置为14px*/
1、如果top、right、bottom、left的值相同,如下面代码:
margin:10px 10px 10px 10px;
可缩写为:
可缩写为:
margin:10px;
2、如果top和bottom值相同、left和 right的值相同,如下面代码:
2、如果top和bottom值相同、left和 right的值相同,如下面代码:
margin:10px 20px 10px 20px;
可缩写为:
可缩写为:
margin:10px 20px;
3、如果left和right的值相同,如下面代码:
3、如果left和right的值相同,如下面代码:
margin:10px 20px 30px 20px;
可缩写为:
可缩写为:
margin:10px 20px 30px;
注意:padding、border的缩写方法和margin是一致的。
13、字体缩写
注意:padding、border的缩写方法和margin是一致的。
13、字体缩写
body{
font-style:italic;
font-variant:small-caps;
font-weight:bold;
font-size:12px;
line-height:1.5em;
font-family:"宋体",sans-serif;
font-family:"宋体",sans-serif;
}
这么多行的代码其实可以缩写为一句:
这么多行的代码其实可以缩写为一句:
body{
font:italic small-caps bold 12px/1.5em "宋体",sans-serif;
font:italic small-caps bold 12px/1.5em "宋体",sans-serif;
}
1、使用这一简写方式你至少要指定 font-size 和 font-family 属性,其他的属性(如 font-weight、font-style、font-varient、line-height)如未指定将自动使用默认值。
2、在缩写时 font-size 与 line-height 中间要加入“/”斜扛。
一般情况下因为对于中文网站,英文还是比较少的,所以下面缩写代码比较常用:
1、使用这一简写方式你至少要指定 font-size 和 font-family 属性,其他的属性(如 font-weight、font-style、font-varient、line-height)如未指定将自动使用默认值。
2、在缩写时 font-size 与 line-height 中间要加入“/”斜扛。
一般情况下因为对于中文网站,英文还是比较少的,所以下面缩写代码比较常用:
body{
font:12px/1.5em "宋体",sans-serif;
font:12px/1.5em "宋体",sans-serif;
}
只是有字号、行间距、中文字体、英文字体设置。
14、长度值
px(像素)、em、% 百分比,要注意其实这三种单位都是相对单位。
像素指的是显示器上的小点
em就是本元素给定字体的 font-size 值,如果元素的 font-size 为 14px ,那么 1em = 14px;如果 font-size 为 18px,那么 1em = 18px。
p{font-size:12px;line-height:130%}设置行高(行间距)为字体的130%(12 * 1.3 = 15.6px)。
15、居中
水平居中,内联元素水平居中text-align:center。
当被设置元素为块状元素时用 text-align:center 就不起作用了。这时也分两种情况:定宽块状元素和不定宽块状元素。
满足定宽和块状两个条件的元素是可以通过设置“左右margin”值为“auto”来实现居中的。
不定宽度的块状元素有三种方法居中(这三种方法目前使用的都比多):
加入 table 标签
设置 display;inline 方法
设置 position:relative 和 left:50%;
垂直居中-父元素高度确定的单行文本
设置父元素的 height 和 line-height 高度一致来实现
垂直居中-父元素高度确定的多行文本
1、 vertical-align是垂直居中属性,但只有父元素为tr和td的时候才有用。因此可以用table包含多行文本,实现垂直居中。注意:td 标签默认情况下就默认设置了 vertical-align 为 middle。
2、 通过设施display:table-cell; 激活 vertical-align 属性,但注意 IE6、7 并不支持这个样式。
display:table-cell;/*IE8以上及Chrome、Firefox*/
vertical-align:middle;/*IE8以上及Chrome、Firefox*/
只是有字号、行间距、中文字体、英文字体设置。
14、长度值
px(像素)、em、% 百分比,要注意其实这三种单位都是相对单位。
像素指的是显示器上的小点
em就是本元素给定字体的 font-size 值,如果元素的 font-size 为 14px ,那么 1em = 14px;如果 font-size 为 18px,那么 1em = 18px。
p{font-size:12px;line-height:130%}设置行高(行间距)为字体的130%(12 * 1.3 = 15.6px)。
15、居中
水平居中,内联元素水平居中text-align:center。
当被设置元素为块状元素时用 text-align:center 就不起作用了。这时也分两种情况:定宽块状元素和不定宽块状元素。
满足定宽和块状两个条件的元素是可以通过设置“左右margin”值为“auto”来实现居中的。
不定宽度的块状元素有三种方法居中(这三种方法目前使用的都比多):
加入 table 标签
设置 display;inline 方法
设置 position:relative 和 left:50%;
垂直居中-父元素高度确定的单行文本
设置父元素的 height 和 line-height 高度一致来实现
垂直居中-父元素高度确定的多行文本
1、 vertical-align是垂直居中属性,但只有父元素为tr和td的时候才有用。因此可以用table包含多行文本,实现垂直居中。注意:td 标签默认情况下就默认设置了 vertical-align 为 middle。
2、 通过设施display:table-cell; 激活 vertical-align 属性,但注意 IE6、7 并不支持这个样式。
display:table-cell;/*IE8以上及Chrome、Firefox*/
vertical-align:middle;/*IE8以上及Chrome、Firefox*/
```
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册