Hexo进阶之各种优化


1.npm速度优化


大家在使用hexo的时候,肯定经常要和npm打交道,需要用到它去下载一些东西,但npm的下载速度确实有点不尽如人意。
因为我们在使用hexo时,会需要用到npm去安装较多的插件,所以我们需要修改npm的仓库地址,以便能达到更快的安装速度。

  • 阿里的淘宝团队在国内做了个跟npm仓库一样的镜像叫cnpm
  • 淘宝镜像与npm官方包的同步频率目前为10分钟一次,来保证尽量与官方服务同步;
  • 所以说npmcnpm两者之间可以说是一样的,不会有什么差别。

通过改变地址来使用淘宝镜像(推荐)

  • npm的默认仓库地址是 https://registry.npmjs.org/
  • 可以使用以下命令查看当前npm的仓库地址
    npm config get registry
  • 可以使用以下命令来改变默认下载地址,从而达到不安装cnpm就能采用淘宝镜像的目的,然后使用上面的get命令查看是否设置成功。
    npm config set registry https://registry.npm.taobao.org

    安装cnpm

  • 安装cnpm,命令行代码:
    npm install -g cnpm --registry=https://registry.npm.taobao.org
  • 安装完成之后,可使用以下代码检查是否安装成功,安装成功之后,输入以下代码,则会出现版本号
    cnpm -v
  • 成功安装之后,就可以使用cnpm去代替npm来执行安装命令了

2.访问速度的优化


图片加载优化

在做图片加载优化之前,让我们了解一下预加载懒加载.


预加载

预加载是一种在进入项目前提前进行资源加载的一种加载形式,避免在项目中加载缓慢,影响用户体验。

  • 缺点:会增加网站服务器的压力

    懒加载

    懒加载一般是当图片滚动进可视化窗口内才加载图片,可视窗口之外的图片则不加载。
  • 优点:对服务器有一定缓解压力的作用

我所使用的matery主题整体采用预加载的模式,这样可以在我们访问其他页面的时候会稍微快一点,我们可以在这个基础上对图片进行懒加载,这样做效果就是html、css、js加载之后,图片再加载。既保证了网页的打开速度,也不会因图片的庞大体积而拖累了整个页面的加载。

具体操作

  • 首先安装图片懒加载插件:hexo-lazyload-image

  • 在Hexo的根目录执行以下代码操作:

    cnpm install hexo-lazyload-image --save
  • 然后在hexo配置文件_config.yml末尾添加以下代码:

    lazyload:
      enable: true 
      onlypost: false  # 是否只对文章的图片做懒加载
      loadingImg: # eg ./images/loading.gif
  • 到这里就配置完了,执行hexo cl&&hexo g && hexo s就有效果了,以后博客上的图片就都是懒加载了,以上步骤理论上任何主题都可以用

  • 一般情况下懒加载会和gallery插件会发生冲突,结果可能就是点开图片,左翻右翻都是loading image

  • matery主题的解决方案是:修改 /themes/matery/source/js 中的 matery.js 文件
    在第108行加上:

    $(document).find('img[data-original]').each(function(){
        $(this).parent().attr("href", $(this).attr("data-original"));
    });
  • 做完这步之后,还有点小Bug,首页的logo点击会直接打开logo图,而不是跳到首页。

  • 伪解决方案:打开 /themes/matery/layout/_partial/header.ejs 文件,

  • imgspan的两个头加个div

    <div class="brand-logo">
        <a href="<%- url_for() %>" class="waves-effect waves-light">
            <div>
                <% if (theme.logo !== undefined && theme.logo.length > 0) { %>
                <img src="<%= theme.logo %>" class="logo-img" alt="LOGO">
                <% } %>
                <span class="logo-span"><%- config.title %></span>
            </div>
        </a>
    </div>

    自定义loading图片

  • hexo-lazyload-image 插件提供了自定义loading图片的选项,方法就是在 loadingImg 后配置图片的路径就好了
    Like this as follow:

    lazyload:
      enable: true 
      onlypost: false  # 是否只对文章的图片做懒加载
      loadingImg: /medias/loading.gif # eg ./images/loading.gif

    懒加载优化

    经过以上操作就已经很完美了,以下内容可做也可不做,depend on yourself!

  • 其实第一次加载后本地都是有缓存的,如果每次都把loading显示出来就不那么好看

  • 所以我们需要对插件进行魔改,让图片稍微提前加载,避开加载动画

  • 打开 Hexo根目录 > node_modules > hexo-lazyload-image > lib > simple-lazyload.js 文件

  • 第9行修改为:

    && rect.top <= (window.innerHeight +240 || document.documentElement.clientHeight +240)
  • 作用:提前240个像素加载图片,当然这个值也可以根据自己情况修改


代码压缩优化

为什么要压缩代码:

因为hexo生成的html、css、js等都有很多的空格或者换行,而空格和换行也是占用字节的,所以需要将空格换行去掉也就是我要进行的“压缩”。

有人说空格换行能占多少字节?确实占不了多少,但是一个人访问是这么多字节,那么一百人,一万人呢?加起来这量就不少了吧,这都是流量啊!这也是很多css/js文件的后缀为*.min.js或*.min.css的原因。虽然我们可能没那么多访问量,但是能减小一点资源文件的大小也是对访问速度有那么一点提升的。

gulp实现代码压缩

  • 在hexo的根目录执行以下命令:
    # 全局安装gulp模块
    npm install gulp -g
    # 安装各种小功能模块  执行这步的时候,可能会提示权限的问题,最好以管理员模式执行
    npm install gulp gulp-htmlclean gulp-htmlmin gulp-minify-css gulp-uglify gulp-imagemin --save
    # 额外的功能模块
    npm install gulp-debug gulp-clean-css gulp-changed gulp-if gulp-plumber gulp-babel babel-preset-es2015 del @babel/core --save
  • 在Hexo根目录新建文件 gulpfile.js,并复制以下内容到文件中,有中文注释,可以根据自己需求修改。
    var gulp = require("gulp");
    var debug = require("gulp-debug");
    var cleancss = require("gulp-clean-css"); //css压缩组件
    var uglify = require("gulp-uglify"); //js压缩组件
    var htmlmin = require("gulp-htmlmin"); //html压缩组件
    var htmlclean = require("gulp-htmlclean"); //html清理组件
    var imagemin = require("gulp-imagemin"); //图片压缩组件
    var changed = require("gulp-changed"); //文件更改校验组件
    var gulpif = require("gulp-if"); //任务 帮助调用组件
    var plumber = require("gulp-plumber"); //容错组件(发生错误不跳出任务,并报出错误内容)
    var isScriptAll = true; //是否处理所有文件,(true|处理所有文件)(false|只处理有更改的文件)
    var isDebug = true; //是否调试显示 编译通过的文件
    var gulpBabel = require("gulp-babel");
    var es2015Preset = require("babel-preset-es2015");
    var del = require("del");
    var Hexo = require("hexo");
    var hexo = new Hexo(process.cwd(), {}); // 初始化一个hexo对象
    
    // 清除public文件夹
    gulp.task("clean", function () {
        return del(["public/**/*"]);
    });
    
    // 下面几个跟hexo有关的操作,主要通过hexo.call()去执行,注意return
    // 创建静态页面 (等同 hexo generate)
    gulp.task("generate", function () {
        return hexo.init().then(function () {
            return hexo
                .call("generate", {
                    watch: false
                })
                .then(function () {
                    return hexo.exit();
                })
                .catch(function (err) {
                    return hexo.exit(err);
                });
        });
    });
    
    // 启动Hexo服务器
    gulp.task("server", function () {
        return hexo
            .init()
            .then(function () {
                return hexo.call("server", {});
            })
            .catch(function (err) {
                console.log(err);
            });
    });
    
    // 部署到服务器
    gulp.task("deploy", function () {
        return hexo.init().then(function () {
            return hexo
                .call("deploy", {
                    watch: false
                })
                .then(function () {
                    return hexo.exit();
                })
                .catch(function (err) {
                    return hexo.exit(err);
                });
        });
    });
    
    // 压缩public目录下的js文件
    gulp.task("compressJs", function () {
        return gulp
            .src(["./public/**/*.js", "!./public/libs/**"]) //排除的js
            .pipe(gulpif(!isScriptAll, changed("./public")))
            .pipe(gulpif(isDebug, debug({ title: "Compress JS:" })))
            .pipe(plumber())
            .pipe(
                gulpBabel({
                    presets: [es2015Preset] // es5检查机制
                })
            )
            .pipe(uglify()) //调用压缩组件方法uglify(),对合并的文件进行压缩
            .pipe(gulp.dest("./public")); //输出到目标目录
    });
    
    // 压缩public目录下的css文件
    gulp.task("compressCss", function () {
        var option = {
            rebase: false,
            //advanced: true, //类型:Boolean 默认:true [是否开启高级优化(合并选择器等)]
            compatibility: "ie7" //保留ie7及以下兼容写法 类型:String 默认:''or'*' [启用兼容模式; 'ie7':IE7兼容模式,'ie8':IE8兼容模式,'*':IE9+兼容模式]
            //keepBreaks: true, //类型:Boolean 默认:false [是否保留换行]
            //keepSpecialComments: '*' //保留所有特殊前缀 当你用autoprefixer生成的浏览器前缀,如果不加这个参数,有可能将会删除你的部分前缀
        };
        return gulp
            .src(["./public/**/*.css", "!./public/**/*.min.css"]) //排除的css
            .pipe(gulpif(!isScriptAll, changed("./public")))
            .pipe(gulpif(isDebug, debug({ title: "Compress CSS:" })))
            .pipe(plumber())
            .pipe(cleancss(option))
            .pipe(gulp.dest("./public"));
    });
    
    // 压缩public目录下的html文件
    gulp.task("compressHtml", function () {
        var cleanOptions = {
            protect: /<\!--%fooTemplate\b.*?%-->/g, //忽略处理
            unprotect: /<script [^>]*\btype="text\/x-handlebars-template"[\s\S]+?<\/script>/gi //特殊处理
        };
        var minOption = {
            collapseWhitespace: true, //压缩HTML
            collapseBooleanAttributes: true, //省略布尔属性的值 <input checked="true"/> ==> <input />
            removeEmptyAttributes: true, //删除所有空格作属性值 <input id="" /> ==> <input />
            removeScriptTypeAttributes: true, //删除<script>的type="text/javascript"
            removeStyleLinkTypeAttributes: true, //删除<style>和<link>的type="text/css"
            removeComments: true, //清除HTML注释
            minifyJS: true, //压缩页面JS
            minifyCSS: true, //压缩页面CSS
            minifyURLs: true //替换页面URL
        };
        return gulp
            .src("./public/**/*.html")
            .pipe(gulpif(isDebug, debug({ title: "Compress HTML:" })))
            .pipe(plumber())
            .pipe(htmlclean(cleanOptions))
            .pipe(htmlmin(minOption))
            .pipe(gulp.dest("./public"));
    });
    
    // 压缩 public/medias 目录内图片
    gulp.task("compressImage", function () {
        var option = {
            optimizationLevel: 5, //类型:Number 默认:3 取值范围:0-7(优化等级)
            progressive: true, //类型:Boolean 默认:false 无损压缩jpg图片
            interlaced: false, //类型:Boolean 默认:false 隔行扫描gif进行渲染
            multipass: false //类型:Boolean 默认:false 多次优化svg直到完全优化
        };
        return gulp
            .src("./public/medias/**/*.*")
            .pipe(gulpif(!isScriptAll, changed("./public/medias")))
            .pipe(gulpif(isDebug, debug({ title: "Compress Images:" })))
            .pipe(plumber())
            .pipe(imagemin(option))
            .pipe(gulp.dest("./public"));
    });
    // 执行顺序: 清除public目录 -> 产生原始博客内容 -> 执行压缩混淆 -> 部署到服务器
    gulp.task(
        "build",
        gulp.series(
            "clean",
            "generate",
            "compressHtml",
            "compressCss",
            "compressJs",
            "compressImage",
            gulp.parallel("deploy")
        )
    );
    
    // 默认任务
    gulp.task(
        "default",
        gulp.series(
            "clean",
            "generate",
            gulp.parallel("compressHtml", "compressCss", "compressJs","compressImage")
        )
    );
    //Gulp4最大的一个改变就是gulp.task函数现在只支持两个参数,分别是任务名和运行任务的函数
  • 以后执行方式有两种:
    • 直接在Hexo根目录执行 gulp 或者 gulp default ,这个命令相当于 hexo cl && hexo g 并且再把代码和图片压缩。
    • 在Hexo根目录执行 gulp build ,这个命令与第1种相比是:在最后又加了个 hexo d ,等于说生成、压缩文件后又帮你自动部署了。
  • 值得注意的是:这个加入了图片压缩,如果不想用图片压缩可以把第154行的 "compressImage", 和第165行的 ,"compressImage" 去掉即可

    hexo-neat插件实现代码压缩

  • 可能以上方法比较复杂,来介绍个简单的,hexo-neat插件也是用来压缩代码的,底层也是通过gulp来实现的。
  • 但是这个插件是有Bug的:
    1.压缩 md 文件会使 markdown 语法的代码块消失
    2.会删除全角空格
  • Hexo根目录执行安装代码:
    cnpm install hexo-neat --save
  • 在Hexo配置文件 _config.yml 末尾加入以下配置:
    neat_enable: true
    neat_html:
      enable: true
      exclude:
    neat_css:
      enable: true
      exclude:
        - '*.min.css'
    neat_js:
      enable: true
      mangle: true
      output:
      compress:
      exclude:
        - '*.min.js'
  • 然后直接hexo cl && hexo g就可以了,会自动压缩文件。
  • 补充:为了解决以上Bug,对于matery主题需要将以上的默认配置修改为:
    #hexo-neat 优化提速插件(去掉HTML、css、js的blank字符)
    neat_enable: true
    neat_html:
      enable: true
      exclude:
        - '**/*.md'
    neat_css:
      enable: true
      exclude:
        - '**/*.min.css'
    neat_js:
      enable: true
      mangle: true
      output:
      compress:
      exclude:
        - '**/*.min.js'
        - '**/**/instantpage.js'
        - '**/matery.js'

文章作者: OilPicture
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 OilPicture !
评论
  目录