审查自己项目的时候,发现自己一直用开的 UUID 库没有实际测试过性能,所以找了下网上的文章和库列表,就有了今天这一篇文章.

测试代码:

供使用参考,大量摘抄自 (Generating good unique ids in Go):

Package Id Format
github.com/segmentio/ksuid 0pPKHjWprnVxGH7dEsAoXX2YQvU 4 位时间 (单位秒) + 16 位随机数
github.com/rs/xid b50vl5e54p1000fo3gh0 4 位时间 (单位秒) + 3 位设备号 + 2 位进程号 + 3 位随机数
github.com/kjk/betterguid -Kmdih_fs4ZZccpx2Hl1 8 位时间 (单位毫秒) + 9 位随机数
github.com/sony/sonyflake 20f8707d6000108 ~6 位时间 (取 10 毫秒为一个单位) + 1 位顺序序列 + 2 位设备号
github.com/oklog/ulid 01BJMVNPBBZC3E36FJTGVF0C4S 6 位时间 (单位毫秒) + 8 位随机数
github.com/chilts/sid 1JADkqpWxPx-4qaWY47~FqI 8 位时间 (单位纳秒) + 8 位随机数
github.com/lithammer/shortuuid dwRQAc68PhHQh4BUnrNsoS UUID v4/5,支持自定义字符
github.com/satori/go.uuid 5b52d72c-82b3-4f8e-beb5-437a974842c UUID v1/2/3/4/5,符合 RFC 4122 和 DCE 1.1
github.com/google/uuid c01d7cf6-ec3f-47f0-9556-a5d6e9009a43 Google 公开的实现,符合 RFC 4122 和 DCE 1.1
github.com/matoous/go-nanoid Uakgb_J5m9g-0JDMbcJqLJ 更短的字符串,22 个字符,并且支持自定义字符和长度

引用:

Generating good unique ids in Go

近期遇到错误删除 Grub 启动分区,而引起无法启动的问题.

由于主分区用的是 Btrfs 格式,Grub 就需要将自己一个 core.img 嵌入到一个大小为 2M 左右的分区内.

修复步骤:

  1. gdisk 重新建立一个分区,大小为 2M 左右即可
  2. gdisk 修改分区 code 为 EF02
  3. grub-install /dev/SDA (SDA 为系统盘标识符),期间会自动识别 EF02 分区将 core.img 作为嵌入分区.
  4. 重启即可

引用:

Hugo 一个用于生成静态网站的框架,快速开始

Vercel 就是原来的 zeit.co 改名而来。

合并 Hugo 和 Vercel 的特性,可以快速部署一份自己的博客,而且费用全免。

第一步,建立自己的静态网站

直接参考 hugo 的快速开始即可:

# 安装 hugo
wget https://github.com/gohugoio/hugo/releases/download/v0.69.2/hugo_0.69.2_Linux-64bit.tar.gz
tar xf hugo_0.69.2_Linux-64bit.tar.gz hugo
chmod +x hugo

# 建立 MyBlog 网站项目
./hugo new site MyBlog
cd MyBlog

第二步,在 GitHub 上建立自己的私有项目

首先得有自己的 GitHub 账号,注册并登陆。

新建一个项目 MyBlog

  • Repository name: MyBlog
  • Private: You choose who can see and commit to this repository.

新建完毕后,获取项目地址: https://github.com/XXX/MyBlog 其中 XXX 就是 GitHub 账号名。

第三步,在 Vercel 建立并关联 MyBlog 项目

和 GitHub 一样,同样要先注册有 Vercel 账号。

引入 GitHub 的项目,先关联 GitHub 账号到 Vercel,并且选择 MyBlog 项目即可。

然后进去项目选择 Settings 配置 Build & Development Settings 的 FRAMEWORK RESET 为 Hugo,其他都不用修改。

第五步,提交自己的博客

这个时候就要将自己本地的 MyBlog 项目用 Git 进行管理。

# 回到第一步的终端内,紧跟着 cd MyBlog 命令后
git init
git remote add origin https://github.com/XXX/MyBlog # 此处为第二步得到的项目地址
git add archetypes config.toml content data layouts resources static themes
git commit -a -m 'init'
git push -u origin master

在 Vercel 项目 Deployments 页面可以看到等待 Vercel 进行努力编译 MyBlog 了~

经过漫长的几十秒编译后,你就得到第一个静态网站项目: MyBlog.XXX.now.sh 其中 XXX 就是你的用户名。

到此有更多可以处理的。

  1. 选择自己的域名绑定,相关内容在 Vercel 项目的 Settings / Domains 内
  2. 静态网站增加内容,默认建立的网站是一个完全空白的页面(当然啦,毕竟是自己的网站),新建一些内容吧:快速开始

快速解决 VSCode 和 Prettier 的交互。

vscode 版本:1.31.0

直接在项目里面建立一个文件 .prettierrc.js

// .prettierrc.js
module.exports = {
  semi: false,
  singleQuote: true,
  tabWidth: 4,
  trailingComma: 'es5',
};

// .eslintrc.js
module.exports = {
  env: {
    browser: true,
    es6: true,
  },
  extends: 'standard',
  parserOptions: {
    sourceType: 'module',
  },
  rules: {
    curly: [0],
    'prefer-const': [2],
    'space-before-function-paren': 'error',
    // Here to match our Prettier options
    semi: ['error', 'never'],
    quotes: ['error', 'single'],
    indent: ['error', 4],
    'comma-dangle': ['error', 'always-multiline'],
  },
};

其实就是一套配置,估计是 prettier 插件自己的默认配置不符合我的项目环境。

这段时间一直在各种 Angular 项目中挣扎,特别是上传让人措手不及。
索性直接编写一篇可以快速上手的实例,直接抄或者仿照都应该可以直接使用。

  • 新建一个服务

    $ng g s UploadService
    
  • 对服务添加依赖

    
    // http angular的标准HTTP服务
    constructor(private http: HttpClient) {}
    
    // 增加上传方法,参数暂时只有 file
    upload(file: File) {
    // 构建合适的数据表单
    const formData = new FormData();
    formData.append('file', file);
    
    // 构建请求体,因为要做上传进度,所以设置了 reportProgress 为真
    const req = new HttpRequest('POST', '/upload/file/path', formData, {
        reportProgress: true
    });
    
    // 上传重试两次,用了 rxjs 的操作
    return this.http.request(req).pipe(retry(2));
    }
    
    
  • 在 Component 增加上传的操作函数

    
    uploadButtonClicked(ev) {
    // 这里走的是模拟方法
    const elm = document.createElement('input');
    elm.type = 'file';
    elm.multiple = false; // 每次仅上传一个文件,所以直接设置为假
    
    // 监听改变
    elm.addEventListener('change', () => {
        if (elm.files.length > 0) {
            const file = elm.files[0];
    
            this.uploadService
                .upload(file)
                .subscribe((event) => {
                    switch (event.type) {
                        case HttpEventType.Sent:
                            console.info(`${file.name} 上传完毕`);
                            break;
    
                        case HttpEventType.UploadProgress:
                            const percentDone = Math.round(100 * event.loaded / event.total);
                            console.info(`${file.name} 上传进度: ${percentDone}%`)
                            break;
    
                        case HttpEventType.Response:
                            console.info(`远程有返回`)
                            break;
    
                        default:
                            this.logger.info(`"${file.name}" 其他状态: ${event.type}`);
                    }
                });
        }
    });
    elm.click();
    }
    
    

Gradle 国内设置
减少依赖 Google 和 JCenter,使用国内镜像,加速已经很慢的Gradle。

buildscript {
    repositories {
        // 屏蔽默认
        // google()
        // jcenter()
        // 补充国内镜像库
        // maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
        maven { url 'https://plugins.gradle.org/m2/' }
        maven { url 'http://maven.net.cn/content/groups/public/' }
        maven { url 'http://maven.aliyun.com/nexus/content/repositories/google' }
        maven { url 'http://maven.aliyun.com/nexus/content/repositories/jcenter'}
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:3.2.1'
    }
}

allprojects {
    repositories {
        // 屏蔽默认
        // google()
        // jcenter()
        // 补充国内镜像库
        // maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
        maven { url 'https://plugins.gradle.org/m2/' }
        maven { url 'http://maven.net.cn/content/groups/public/' }
        maven { url 'http://maven.aliyun.com/nexus/content/repositories/google' }
        maven { url 'http://maven.aliyun.com/nexus/content/repositories/jcenter'}
    }
}

HTTP DNS 不算新兴事物,不过肯定是好玩的东西。
国内直接提供的商就不认识了,不过还有国外出名的:Google, Cloudflare

这个就拿还能用的 Cloudflare 制作一个简单的例子。

先挖出自己的 JS 里面的 rRaw 函数里面实现,稍作修改就可以使用。

function rRaw(url, callback) {
  var r = new XMLHttpRequest();
  r.async = true;
  r.addEventListener('error', function(err) {
    console.error('[rRaw]', url, 'failed', err);
  });
  r.addEventListener('load', function() {
    console.info('[rRaw]', url, 'loaded');

    var dat = JSON.parse(this.responseText);
    if (callback !== undefined) {
      callback(dat);
    }
  });

  r.open('GET', url, true);

  r.send();
  console.info('[rRaw]', url);
}

Google

rRaw('https://dns.google.com/resolve?name=example', function(dat) {
  console.log(dat);
});

Cloudflare

rRaw('https://cloudflare-dns.com/dns-query?ct=application/dns-json&name=example.com&type=AAAA', function(dat) {
  console.log(dat);
});

让页面加载更快是每个网站都需要做的优化。

基础技术包括:

  • 最小化加载文件体积
  • 使用异步加载标签

这里仅作简易的指南,为了新人或者已经忘记初衷的人。


压缩 Compare, Minify

Javascript 压缩脚本推荐两个工具:

  1. Uglify 3? / Online
  2. Google 的 Closure / Online
  3. Yahoo YuiCompressor / Online

扩展阅读 The cost of transpiling es2015 in 2016

CSS 可以尝试下:

  1. CSSNano / Online
  2. CSSo / Online
  3. Yahoo YuiCompressor / Online

扩展阅读 Css Minification Benchmark 2017 report

HTML 优化:

  1. HTML Minifier / Online
  2. HTML Tidy 这个比较古旧,可是非常适合作为优化手段。

扩展阅读 Google’s Minify Resources (HTML, CSS, and JavaScript)

— 2018.04.03 夜深更新到此 —

提醒自己不要忘记前端更多是为了优化阅读体验。

— 2018.04.08 继续更新 —

异步化资源

通过对资源异步加载,将第一次屏显时间提高到最快。

  1. 特性: Preload link

    <link rel="preload" href="used-later.js" as="script" />
    <!-- ...other HTML... -->
    <script>
    // 最后通过Javascript再次将已经预加载到缓存的脚本执行
    var usedLaterScript = document.createElement("script");
    usedLaterScript.src = "used-later.js";
    document.body.appendChild(usedLaterScript);
    </script>
    

当然除了 script 也可以加载 style

<link rel="preload" href="custom.css" as="style" />

更进一步优化

<link rel="preload" href="custom.css" as="style" onload="this.rel='stylesheet'" />

这个 preload 优势就是浏览器本身加载,速度和加载时机都非常靠前,比起自己通过 Javascript 控制加载时机快多了。

注意,这个特性并不是每个浏览器都完整支持。

  1. 使用 Javascript 进行异步

这个是古老的方法,并且可行。可是问题出现在加载实际上。

因为本身 HTML 的顺序加载和解释方式上,一般只有在 HTML 尾部执行 Javascript 才能准确加载异步脚本。

如在 <html /> 后加载 <script />

<html>
  <head></head>
  <body></body>
</html>

<script>
  function rStyle(url) {
    var s = document.getElementsByTagName("head")[0];
    var link = document.createElement("link");
    link.rel = "stylesheet";
    link.type = "text/css";
    link.href = url;
    link.media = "all";
    link.addEventListener("error", function () {
      // handle error
    });
    link.addEventListener("load", function () {
      // handle load done
    });

    s.appendChild(link);
  }

  rStyle("https://iscys.com/js/utils.js");
</script>

在页面解释到此处就是插入一个对象到 DOM 树上,然后异步加载,比较适合业务脚本插入。

博客从 WordPress 到 Blogger ,到自己写后端前端, 再到 Hugo ,简直是神烦。

之前用自建 WordPress 的时候,发现最麻烦的是维持一台独立的服务,然后还要保持这台服务器能够访问速度。

特别是中国那糟糕的网络体验,当时还没有很多廉价 CDN 可以使用。

到了 Blogger ,感觉是自虐了几个月!可访问性更差!特别是国内,直接被 Block。

没法,最后自己想办法优化(这个更加脑抽)。

略过搭建 PG 、构建 GeDNS 、维护服务器,一大箩筐的事情做完。

结果并不理想,只有自己能够正常访问下,还真没有其他用处!

好吧,2018 都到了,还是乖乖用现成的系统吧, Hugo 上!

Hugo 主要是简单。Go 基础,一个二进制,直接编入项目,改主题,抄 CSS ,差不多一周,基本完成。