kk Blog —— 通用基础


date [-d @int|str] [+%s|"+%F %T"]
netstat -ltunp
sar -n DEV 1

octopress优化

octopress优化

能够让octopress在50篇文章下跑进5s,不优化要跑60s左右
300篇15s左右

运行过程

看octopress目录下的Rakefile,里面有generate,preview,watch等。

输入rake generate是就是按照Rakefile中task :generate do执行的。

最主要的两条:

1
2
system "compass compile --css-dir #{source_dir}/stylesheets"
system "jekyll build"

第一条是编译css,第二条是生成文章。

第一条不知道如何优化,略过。

第二条接着执行到

/usr/local/lib/ruby/gems/2.1.0/gems/jekyll-2.5.1/lib/jekyll/commands/build.rb

文件的 init_with_program -> process -> build 然后到

/usr/local/lib/ruby/gems/2.1.0/gems/jekyll-2.5.1/lib/jekyll/command.rb 文件的 process_site 然后到

/usr/local/lib/ruby/gems/2.1.0/gems/jekyll-2.5.1/lib/jekyll/site.rb 文件的 process,

process代码如下:

1
2
3
4
5
6
7
8
47     def process
48       reset
49       read
50       generate
51       render
52       cleanup
53       write
54     end

这里的函数都在这个文件里,主要费时在 generate 和 render。

1. generate

generate 会执行 octopress/plugins 目录下的 tag_generator.rb 和 category_generator.rb,

这两个文件的 write_tag_indexes 和 write_category_indexes 分别回构建 tag 和 category 的分类首页。

所以 tag 和 category 越多构建越慢。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from /home/kk/kk/github/octopress/plugins/rubypants.rb:261:in `to_html'
from /home/kk/kk/github/octopress/plugins/octopress_filters.rb:31:in `post_filter'
from /home/kk/kk/github/octopress/plugins/octopress_filters.rb:41:in `post_render'
from /usr/local/lib/ruby/gems/2.1.0/gems/octopress-hooks-2.2.1/lib/octopress-hooks.rb:255:in `block in post_render'
from /usr/local/lib/ruby/gems/2.1.0/gems/octopress-hooks-2.2.1/lib/octopress-hooks.rb:254:in `each'
from /usr/local/lib/ruby/gems/2.1.0/gems/octopress-hooks-2.2.1/lib/octopress-hooks.rb:254:in `post_render'
from /usr/local/lib/ruby/gems/2.1.0/gems/octopress-hooks-2.2.1/lib/octopress-hooks.rb:224:in `do_layout'
from /usr/local/lib/ruby/gems/2.1.0/gems/jekyll-2.5.1/lib/jekyll/page.rb:122:in `render'
from /home/kk/kk/github/octopress/plugins/category_generator.rb:100:in `write_category_index'
from /home/kk/kk/github/octopress/plugins/category_generator.rb:112:in `block in write_category_indexes'
from /home/kk/kk/github/octopress/plugins/category_generator.rb:111:in `each'
from /home/kk/kk/github/octopress/plugins/category_generator.rb:111:in `write_category_indexes'
from /home/kk/kk/github/octopress/plugins/category_generator.rb:141:in `generate'
from /usr/local/lib/ruby/gems/2.1.0/gems/jekyll-2.5.1/lib/jekyll/site.rb:280:in `block in generate'
from /usr/local/lib/ruby/gems/2.1.0/gems/jekyll-2.5.1/lib/jekyll/site.rb:279:in `each'
from /usr/local/lib/ruby/gems/2.1.0/gems/jekyll-2.5.1/lib/jekyll/site.rb:279:in `generate'
from /usr/local/lib/ruby/gems/2.1.0/gems/jekyll-2.5.1/lib/jekyll/site.rb:50:in `process'

2. render

1
2
3
4
5
6
7
8
9
10
11
from /home/kk/kk/github/octopress/plugins/rubypants.rb:261:in `to_html'
from /home/kk/kk/github/octopress/plugins/octopress_filters.rb:31:in `post_filter'
from /home/kk/kk/github/octopress/plugins/octopress_filters.rb:41:in `post_render'
from /usr/local/lib/ruby/gems/2.1.0/gems/octopress-hooks-2.2.1/lib/octopress-hooks.rb:249:in `block in pre_render'
from /usr/local/lib/ruby/gems/2.1.0/gems/octopress-hooks-2.2.1/lib/octopress-hooks.rb:248:in `each'
from /usr/local/lib/ruby/gems/2.1.0/gems/octopress-hooks-2.2.1/lib/octopress-hooks.rb:248:in `pre_render'
from /usr/local/lib/ruby/gems/2.1.0/gems/octopress-hooks-2.2.1/lib/octopress-hooks.rb:222:in `do_layout'
from /usr/local/lib/ruby/gems/2.1.0/gems/jekyll-2.5.1/lib/jekyll/page.rb:122:in `render'
from /usr/local/lib/ruby/gems/2.1.0/gems/jekyll-2.5.1/lib/jekyll/site.rb:299:in `block in render'
from /usr/local/lib/ruby/gems/2.1.0/gems/jekyll-2.5.1/lib/jekyll/site.rb:298:in `each'
from /usr/local/lib/ruby/gems/2.1.0/gems/jekyll-2.5.1/lib/jekyll/site.rb:298:in `render'

都是慢在 octopress/plugins/rubypants.rb 的 to_html 函数。

优化

1、to_html 函数的 tokenize 和 gsub 很慢。

to_html 函数只是把一些' “之类的转成html,试了一下不执行to_html,diff出来差别不大,页面上显示也都还OK。单纯的 < 在其他地方已经转好了。

所以 octopress/plugins/octopress_filters.rb 中不执行 to_html

2、每次计算侧边栏太慢

所有页面都是按照其 layout 的格式找对应 source/_layout/ 下的模板来生成的。

注意 post.html 和 page.html 的最后都有 { { include_array XXX } }, 这就是说每个页面都要运行 plugins/include_array.rb 中的 render(context) 来生成侧边栏。

但是侧边栏应该是(?)都一样的。所以改成隔一定时间计算一次

1
2
3
4
5
6
7
8
9
 26     @@caltime = 0
 27     @@retstore = ""
 28     def render(context)
 29         if Time.now.to_f - @@caltime < context.registers[:site].config['recaltime']
 30                 return @@retstore;
 31         end
 32         @@caltime = Time.now.to_f
...
 58       @@retstore = rtn

为什么要隔一段时间?因为在 preview 中有改动任何文件就会重新生成一次,这时侧边栏也要重新计算

3、减小文件大小

我的侧边栏有二级目录,整个侧边栏比较大,50篇时已经有20k。所以将侧边栏独立成一个文件,用js来load。

plugins/include_array.rb 中加:

1
2
3
4
5
59       fp = File.new('sidebar.html', 'w');
60       fp.puts(rtn);
61       fp.puts('<script src="/javascripts/category.js" type="text/javascript"></script>');
62       fp.puts('<script type="text/javascript"> hadOpenDiv();</script>');
63       fp.close();

source/_layout/post.html和source/_layout/page.html 的最后部分改成:

1
2
3
4
5
35 <aside class="sidebar" id='load_sidebar'>
36 </aside>
37 <script type="text/javascript">
38   $('#load_sidebar').load('/sidebar.html');
39 </script>

因为 source/index.html 里也有 { { include_array XXX } },所以不用担心不执行 plugins/include_array.rb。

问题1:就是"最近评论" 要从 _config.yml 中的 default_asides: 中移到 source/index.html 中。因为js load进的文件中的 document.write 不执行了。这也就是为什么 source/index.html 不采用js load。如果是 <aside> 中增加 div 用来 load 的话,侧边栏缩到底部就没有三列的效果。

问题2:sidebar.html 要写到主目录,source/sidebar.html 中用 ln 软链接到 sidebar.html。因为如果在watch状态直接写到 source/ 目录的话,他就会再次认为文件有改变,又重新生成。造成在不断生成的死循环。细节是在Rakefile文件的 generate 和 preview 中先加软链接再运行其他

1
2
3
56 task :generate do
57   system('>`pwd`/sidebar.html')
58   system('ln -f -s `pwd`/sidebar.html `pwd`/source/sidebar.html')

优化效果

在文件中加入时间输出代码

1
p "    #{ __FILE__} line:#{__LINE__} time:#{Time.now.to_f}"

50篇文章,40个tag,61个category,运行如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
kk@kk-laptop:~/kk/github/octopress(source)$ rake generate
## Generating Site with Jekyll
"/home/kk/kk/github/octopress/Rakefile line:62 time:1416933869.1204205"
identical source/stylesheets/screen.css 
"/home/kk/kk/github/octopress/Rakefile line:64 time:1416933870.019113"
Configuration file: /home/kk/kk/github/octopress/_config.yml
	        Source: source
	   Destination: public
	  Generating... 
"    /home/kk/kk/github/octopress/plugins/category_generator.rb line:110 time:1416933870.7509217"
"    /home/kk/kk/github/octopress/plugins/category_generator.rb line:114 time:1416933871.8838022"
"    /home/kk/kk/github/octopress/plugins/tag_generator.rb line:93 time:1416933871.8838577"
"    /home/kk/kk/github/octopress/plugins/tag_generator.rb line:97 time:1416933872.389736"
"    /usr/local/lib/ruby/gems/2.1.0/gems/jekyll-2.5.1/lib/jekyll/site.rb line:297 time:1416933872.4271524"
"    /usr/local/lib/ruby/gems/2.1.0/gems/jekyll-2.5.1/lib/jekyll/site.rb line:301 time:1416933873.8506286"
	                done.
 Auto-regeneration: disabled. Use --watch to enable.
"/home/kk/kk/github/octopress/Rakefile line:66 time:1416933873.9671116"
"total = 4.846851825714111"

total = 4.846851825714111,不优化要60s左右。

300篇

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
kk@kk-laptop:~/kk/github/octopress(source)$ rake generate
## Generating Site with Jekyll
"/home/kk/kk/github/octopress/Rakefile line:62 time:1426179501.0918927"
identical source/stylesheets/screen.css 
"/home/kk/kk/github/octopress/Rakefile line:64 time:1426179502.0703895"
Configuration file: /home/kk/kk/github/octopress/_config.yml
	        Source: source
	   Destination: public
	  Generating... 
"    /home/kk/kk/github/octopress/plugins/category_generator.rb line:110 time:1426179503.376222"
"    /home/kk/kk/github/octopress/plugins/category_generator.rb line:114 time:1426179508.2033086"
"    /home/kk/kk/github/octopress/plugins/tag_generator.rb line:93 time:1426179508.2033658"
"    /home/kk/kk/github/octopress/plugins/tag_generator.rb line:97 time:1426179508.3304708"
"    /usr/local/lib/ruby/gems/2.1.0/gems/jekyll-2.5.1/lib/jekyll/site.rb line:297 time:1426179508.3851612"
"    /usr/local/lib/ruby/gems/2.1.0/gems/jekyll-2.5.1/lib/jekyll/site.rb line:301 time:1426179515.877446"
	                done.
 Auto-regeneration: disabled. Use --watch to enable.
"/home/kk/kk/github/octopress/Rakefile line:66 time:1426179516.2085445"
"total = 15.116710424423218"

octopress 加站长统计和站内搜索

站长统计

2022-07-07

histats带出多余访问,改为matomo


2022-07-02

cnzz 无法统计国外地址,换成histats


国内使用很广的CNZZ了,注册后,添加并验证你的网站就可以添加统计代码了,选好自己喜欢的样式,获得代码,可添加到source/_includes/custom/footer.html中。即可查看每天你的博客的流量

1
<script type="text/javascript">var cnzz_protocol = (("https:" == document.location.protocol) ? " https://" : " http://");document.write(unescape("%3Cspan id='cnzz_stat_icon_1253604690'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "s95.cnzz.com/z_stat.php%3Fid%3D1253604690' type='text/javascript'%3E%3C/script%3E"));</script>

站内搜索

2022-07-02

Search 360 达到次数后要收费,换成静态索引


2020-08-13

tapirgo 停止服务了, 换成 https://www.sitesearch360.com

修改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
diff --git a/sass/partials/_navigation.scss b/sass/partials/_navigation.scss
index d9614e3c5..4f57afaa1 100644
--- a/sass/partials/_navigation.scss
+++ b/sass/partials/_navigation.scss
@@ -59,6 +59,8 @@ cursor: pointer;
     ul.subscription {
       margin-left: .8em;
       float: right;
+      width: 100px;
+      margin-right: -47%;
       li:last-child a { padding-right: 0; }
     }
     ul li {
@@ -102,7 +104,8 @@ cursor: pointer;
   }
   @media only screen and (min-width: 992px) {
     form {
-      width: $sidebar-width-wide - $pad-wide - $sidebar-pad-wide*2 + 10px;
+      width: $sidebar-width-wide - $pad-wide - $sidebar-pad-wide*2 + 210px;
+      margin-right: 50px;
     }
     ul[data-subscription$=email] + form {
       width: $sidebar-width-wide - $pad-wide - $sidebar-pad-wide*2 - 58px;
@@ -116,7 +119,7 @@ cursor: pointer;
   }
 }
 @mixin mask-subscription-nav($feed: 'rss.png'){
-  position: relative; top: 3px;
+  position: relative; top: 6px;
   text-indent: -999999em;
   background-color: $nav-border-right;
   border: 0;
diff --git a/source/_includes/navigation.html b/source/_includes/navigation.html
index cdec89642..5c226aab4 100644
--- a/source/_includes/navigation.html
+++ b/source/_includes/navigation.html
@@ -1,5 +1,3 @@
-<ul class="subscription" data-subscription="rss">
-<li>
 <form action="/search" method="get">
     <input class="search" name="query" id="query" type="text" placeholder="search...">
     <input id="btnSubmit" value="search" type="submit">
@@ -10,6 +8,22 @@ if (query != null) {
  document.getElementById("query").value = query;
 }
 </script>
+
+<!-- Start of Site Search 360 Scripts -->
+<script type="text/javascript">
+var ss360Config = {
+    siteId: "abcdxyzk.github.io",
+    searchBox: {
+        selector: "input#query",
+        searchButton: "input#query+input[type='submit']"
+    }
+}
+</script>
+<script src="https://cdn.sitesearch360.com/v13/sitesearch360-v13.min.js" async></script>
+<!-- End of Site Search 360 Scripts -->
+
+<ul class="subscription" data-subscription="rss">
+<li>
 </li>
   <li><a href="/atom.xml" rel="subscribe-rss">RSS</a></li>

为了实现站内搜索(页面不跳转),

需要到tapirgo.com注册你的站点,填入atom.xml的url和邮箱地址,tapirgo会生成一对token,我们只使用public token就够了。
打开_config.yml文件,加入tapir_token: your_token
修改simple_search为你的站点域名simple_search: your_domain
在source/javascripts/新建jquery-tapir.js,内容为
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
(function($){
  var el;
  var settings = {};

  var methods = {
    init: function(options) {
      el = this;

      settings = {
	           token: false,
	           query_param: 'query'
	         };

      if (options) {
	$.extend(settings, options);
      }

      if (!settings.token || settings.query_param == '') {
	return this;
      }

      $.getJSON(
	'http://tapirgo.com/api/1/search.json?token=' + settings.token + '&query=' + paramValue(settings.query_param) + '&callback=?', function(data){
	  if(settings['complete']) { settings.complete() }
	  $.each(data, function(key, val) {
	  document.getElementById('search_results').style.display="block";
	  document.getElementById('search_results').style.height="100%";
	  document.getElementById('search_results').style.overflow="hidden";
	      var str1 = val.content;
	      var str2 = str1.substr(1, 250);
	      str2 = str2.substr(0, Math.min(str2.length, str2.lastIndexOf(" ")));
	    el.append('<div id="content" class="inner"><article class="post"><h2 class="title"><a href="' + val.link + '">' + val.title + '</a></h2><div class="entry-content"><div class="date">Published on: ' + (val.published_on).substr(0,10) + '</div></div><br><p>' + str2 + '...</p><br><a href="' + val.link +'">Read on →</a></article></div>');
	    if(key >= (data.length-1)){
	        el.append('<div id="content" class="inner"><center><h2 style="border-bottom: 1px solid #ddd;">Result ends</h2></center><br><br></div>');
	    }
	  });
	}
      );

      return this;
    }
  };

  // Extract the param value from the URL.
  function paramValue(query_param) {
    var results = new RegExp('[\\?&]' + query_param + '=([^&#]*)').exec(window.location.href);
    return results ? results[1] : false;
  }

  $.fn.tapir = function(method) {
    if (methods[method]) {
      return methods[ method ].apply(this, Array.prototype.slice.call(arguments, 1));
    } else if (typeof method === 'object' || ! method) {
      return methods.init.apply(this, arguments);
    } else {
      $.error('Method ' +  method + ' does not exist on jQuery.tapir');
    }
  };

})( jQuery );
然后在source/search/index.html中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
---
layout: default
---
<h1 class="entry-title"><center>Search Results</center></h1>
<div id="search_loading" style="margin: 40px 0">
    <center><img src="/images/loading.gif"></center>
</div>

<script type="text/javascript" src="/javascripts/jquery-tapir.js"></script>
<div id="search_results" style="display:none">
<br>
</div>
<script>
	 $('#search_results').tapir({
	     'token': 'your_token',
	     'complete' : function() { document.getElementById('search_loading').style.display="none"; }
	 });
</script>
更新source/_includes/navigation.html

将原来的google搜索

1
2
<input type="hidden" name="q" value="site:smarterhjw.com" />
<input class="search" type="text" name="q" results="0" placeholder="Search"/>

更改为

1
<input class="search" name="query" type="text" placeholder="Search..." x-webkit-speech />

最后rake generate,就可以了。 此时进行搜索,就不会再跳转到站外去了。

可以修改一下搜索框展示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
--- a/sass/partials/_navigation.scss
+++ b/sass/partials/_navigation.scss
@@ -74,6 +74,7 @@ body > nav {
       float: right;
       text-align: left;
       padding-left: .8em;
+      padding-top: .35em;
       width: $sidebar-width-medium - $pad-medium*2 - $sidebar-pad-medium + 20px;
       .search {
	 width: 93%;
@@ -86,7 +87,7 @@ body > nav {
       .search { width: 91%; }
     }
     fieldset.mobile-nav { display: none; }
-    fieldset[role=search]{ width: 99%; }
+    fieldset[role=search]{ width: 80%; }
   }
   @media only screen and (min-width: 992px) {
     form {

markdown部分语法

贴自http://wowubuntu.com/markdown/index.html

段落和换行

一个 Markdown 段落是由一个或多个连续的文本行组成,它的前后要有一个以上的空行。普通段落不该用空格或制表符来缩进。
如果你确实想要依赖 Markdown 来插入 <br /> 标签的话,在插入处先按入两个以上的空格然后回车。

标题

Markdown 支持两种标题的语法,类 Setext 和类 atx 形式。
类 Setext 形式是用底线的形式,利用 = (最高阶标题)和 - (第二阶标题),例如:

1
2
3
4
This is an H1
=============
This is an H2
-------------

任何数量的 = 和 - 都可以有效果。
类 Atx 形式则是在行首插入 1 到 6 个 # ,对应到标题 1 到 6 阶,例如:

1
2
3
# 这是 H1
## 这是 H2
###### 这是 H6

你可以选择性地「闭合」类 atx 样式的标题,这纯粹只是美观用的,若是觉得这样看起来比较舒适,你就可以在行尾加上 #,而行尾的 # 数量也不用和开头一样(行首的井字符数量决定标题的阶数):

1
2
3
# 这是 H1 #
## 这是 H2 ##
### 这是 H3 ######