Hexo折腾记——性能优化篇

简介: 折腾Hexo的本来目的就是为了学习把性能优化到极致,由于水平有限,这里牵涉到的所谓的性能优化仅仅只是一些表面工夫,并不牵涉非常细节的前端性能。 另外,由于我朝特殊的网络环境,我使用的谷歌分析,以及Disqus 均会导致出现因时因地因运营商而异的发抽状况,故而所有速度测试均在排除这些干扰下进行的

折腾Hexo的本来目的就是为了学习把性能优化到极致,由于水平有限,这里牵涉到的所谓的性能优化仅仅只是一些表面工夫,并不牵涉非常细节的前端性能。

另外,由于我朝特殊的网络环境,我使用的谷歌分析,以及Disqus 均会导致出现因时因地因运营商而异的发抽状况,故而所有速度测试均在排除这些干扰下进行的。

静态文件压缩

静态文件包括: html,css,js,images . 我才用了gulp来跑自动压缩任务 。具体方法如下:

  1. npm 安装如下工具, 方法皆为 : npm install xxx --save
    "gulp": "^3.9.1",
    "gulp-htmlclean": "^2.7.6",
    "gulp-htmlmin": "^1.3.0",
    "gulp-imagemin": "^2.4.0",
    "gulp-minify-css": "^1.2.4",
    "gulp-uglify": "^1.5.3",
  1. 建立 gulpfile.js 文件
    var gulp = require('gulp');
    var minifycss = require('gulp-minify-css');
    var uglify = require('gulp-uglify');
    var htmlmin = require('gulp-htmlmin');
    var htmlclean = require('gulp-htmlclean');

    // 获取 gulp-imagemin 模块
    var imagemin = require('gulp-imagemin')

    // 压缩 public 目录 css
    gulp.task('minify-css', function() {
        return gulp.src('./public/**/*.css')
            .pipe(minifycss())
            .pipe(gulp.dest('./public'));
    });
    // 压缩 public 目录 html
    gulp.task('minify-html', function() {
      return gulp.src('./public/**/*.html')
        .pipe(htmlclean())
        .pipe(htmlmin({
             removeComments: true,
             minifyJS: true,
             minifyCSS: true,
             minifyURLs: true,
        }))
        .pipe(gulp.dest('./public'))
    });
    // 压缩 public/js 目录 js
    gulp.task('minify-js', function() {
        return gulp.src('./public/**/*.js')
            .pipe(uglify())
            .pipe(gulp.dest('./public'));
    });


    // 压缩图片任务
    // 在命令行输入 gulp images 启动此任务
    gulp.task('images', function () {
        // 1. 找到图片
        gulp.src('./photos/*.*')
        // 2. 压缩图片
            .pipe(imagemin({
                progressive: true
            }))
        // 3. 另存图片
            .pipe(gulp.dest('dist/images'))
    });



    // 执行 gulp 命令时执行的任务
    gulp.task('default', [
        'minify-html','minify-css','minify-js','images'
    ]);

注意, 修改上面的各个目录为你的真实目录, ** 代表0或多个子目录

  1. 执行 gulp ,即可自动压缩所有静态文件

CDN 接入

上面的静态文件压缩幅度有限,要先提升下载速率还需要CDN的支持 。 理论上最佳方案是把所有静态文件都放在CDN上,但是由于hexo各处都在调用内部的js/css,如果需要改动,工程量会比较大,后期维护也不是很方便。不知道以后Hexo会不会原生提供一个配置静态资源地址的选项。

所以我这里只将图片放在了七牛CDN上,hexo 有一个七牛的插件 : hexo-qiniu-sync 。 但是不知道为什么, 我在我电脑上跑不来这个,我看网上也有人说这个插件有许多bug,于是我就自己写了个脚本(本来想写插件,但是并没有研究过hexo的插件该如何写,所以暂时放弃了,后期有时间尝试下吧)。

我的需求很简单,我有一个相册的页面,里面可能会放许多图片,我只想要一个脚本,能过一键上传所有图片然后把url全部写进我的相册界面里。具体实现思路参见 [Hexo 折腾记(基本配置篇)]() 。

一键上传所有文件至七牛的Node 脚本在Github上: https://github.com/joway/qiniu_upload_node

InstantClick 黑科技

说到性能优化,有一个黑科技虽然不是特别优雅,但是提升的速度却是立杆见影且惊人的,那就是 InstantClick 。

InstantClick 的思路非常巧妙,它利用鼠标点击链接前的短暂时间(统计说是平均400ms)进行预加载,从而在感观上实现了迅速打开页面的效果。当你在打开页面的时候,其实页面已经加载到本地了,也就会很快能个完成渲染。

InstantClick 并不能滥用,许多js无法与它兼容,比如 谷歌分析,百度统计,另外还有fancybox 。故而它有两种启用方式:

  1. 白名单方式:

初始化:

    <script src="instantclick.min.js"data-no-instant></script>
    <script data-no-instant>InstantClick.init(true);</script>

针对具体每个链接启动:

    <a href="/blog/" data-instant>Blog</a>
  1. 黑名单方式:

初始化,以及解决部分js无法加载的问题:

    <script src="/js/instantclick.min.js" data-no-instant></script>
    <script data-no-instant>
    InstantClick.on('change', function(isInitialLoad) {
      if (isInitialLoad === false) {
        if (typeof MathJax !== 'undefined') // support MathJax
          MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
        if (typeof prettyPrint !== 'undefined') // support google code prettify
          prettyPrint();
        if (typeof _hmt !== 'undefined')  // support 百度统计
          _hmt.push(['_trackPageview', location.pathname + location.search]);
        if (typeof ga !== 'undefined')  // support google analytics
            ga('send', 'pageview', location.pathname + location.search);
      }
    });
    InstantClick.init();
    </script>

这时候对于所有链接都开启 预加载模式,但是可以针对部分链接假如黑名单:

    <a href="/blog/" data-no-instant>Blog</a>

这里我遇到的一个坑是,我的相册使用了fancybox,而对于InstantClick死活无法解决fancybox的问题(网上也没解决方案),虽然我可以通过指定data-no-instant来达到不预加载的目的,但是hexo对于每个同级链接都是一样对待的,我如何让它单单对于相册不进行预加载呢?

我能够想到的方法就是对导航栏的每一个url指定一个以其中文名(暂时不映射成英文)命名的id值,然后待页面渲染完了以后,对id值为'相册'的元素添加 data-no-instant 属性:

    $("#相册").attr("data-no-instant",'');

有些时候这种加黑名单的方法也没用,那么就用最后一招,强制刷新(自己调试出来的,略土。。) :

    document.getElementById('相册').onclick = function(e){
         location.href = document.getElementById('相册').href;
    }

Nginx 优化配置

Gzip压缩:

http {
    gzip               on;
    gzip_vary          on;

    gzip_comp_level    6;
    gzip_buffers       16 8k;

    gzip_min_length    1000;
    gzip_proxied       any;
    gzip_disable       "msie6";

    gzip_http_version  1.0;

    gzip_types         text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;
    ... ...
}

搜索引擎优化(SEO)

添加百度主动推送代码,让搜索引擎最快发现文章 .

方法: 在 <博客根目录>/themes/yilia/layout/_partial/article.ejs 的尾部评论位置, 添加:

<% if (!index){ %>
<script>
(function(){
    var bp = document.createElement('script');
    bp.src = '//push.zhanzhang.baidu.com/push.js';
    var s = document.getElementsByTagName("script")[0];
    s.parentNode.insertBefore(bp, s);
})();
</script>     
<% } %>

之后,每次用户访问界面,都会去调用推送代码


相关文章:

Hexo折腾记——基本配置篇

Hexo折腾记——自动部署篇

目录
相关文章
websocket封装带心跳和重连机制(vue3+ts+vite)
websocket封装带心跳和重连机制(vue3+ts+vite)
2124 0
|
存储 缓存 NoSQL
Redis的5.0/6.0/7.0版本重点介绍以及使用!
1. Stream数据类型:Redis 5.0引入了Stream数据类型,它是一种日志结构,用于高性能、持久化和实时处理的数据流。Stream可以按照时间顺序存储和检索消息,并支持消费者组和消费者偏移量管理等功能。 2. 基于模块的全文搜索:Redis 5.0通过引入Redis Search模块,提供了全文搜索的功能。它支持对文本字段进行索引和搜索,包括分词、词项权重、布尔查询等功能。 3. 客户端缓存:Redis 5.0引入了客户端缓存(Client-side caching)功能。客户端可以缓存服务器返回的数据,减少对服务器的请求,提高性能和响应速度。
4124 1
|
6月前
|
JSON 测试技术 数据格式
货拉拉跑腿抢单辅助器,货拉拉抢单开挂神器,运满满抢货神器脚本
本内容涵盖HTTP协议基础、Python的`requests`库使用、Web自动化测试工具Selenium的应用,以及一个订单系统模拟器的实现。
|
域名解析 运维 JavaScript
只需5步!在轻量应用服务器部署Hexo博客
轻量应用服务器征文活动投稿教程帖,只需5步完成Hexo博客的部署实践,步骤完整,操作性强~
只需5步!在轻量应用服务器部署Hexo博客
|
安全 前端开发 关系型数据库
单机手动部署OceanBase集群
单机手动部署OceanBase的实验步骤,有详细截图
1467 0
|
7月前
|
人工智能 自然语言处理 数据可视化
阿里云 Bolt.diy:一键开启全能开发,简单强大零门槛
Bolt.diy是Bolt.new的开源版本,通过自然语言交互简化开发流程,支持全栈开发与二次开发。依托多模态智能调度引擎和主流大模型,实现任务智能匹配、模块化部署及私有模型集成,大幅提升开发效率。平台提供代码自动生成、实时诊断优化与可视化工具,降低开发门槛。体验中发现其简单易用,但存在偶发卡顿问题。总体而言,Bolt.diy是一款高效实用的开发工具,适合新手与企业使用。
345 7
|
8月前
|
人工智能 搜索推荐 IDE
突破网页数据集获取难题:Web Unlocker API 助力 AI 训练与微调数据集全方位解决方案
本文介绍了Web Unlocker API、Web-Scraper和SERP API三大工具,助力解决AI训练与微调数据集获取难题。Web Unlocker API通过智能代理和CAPTCHA绕过技术,高效解锁高防护网站数据;Web-Scraper支持动态内容加载,精准抓取复杂网页信息;SERP API专注搜索引擎结果页数据抓取,适用于SEO分析与市场研究。这些工具大幅降低数据获取成本,提供合规保障,特别适合中小企业使用。粉丝专属体验入口提供2刀额度,助您轻松上手!
405 2
|
9月前
|
缓存 数据中心 网络架构
5个减少网络延迟的简单方法
高速互联网对工作与娱乐至关重要,延迟和断线会严重影响效率和体验。本文探讨了导致连接缓慢的三个关键因素:吞吐量、带宽和延迟,并提供了减少延迟的实用方法。包括重启设备、关闭占用带宽的程序、使用有线连接、优化数据中心位置以及添加内容分发网络 (CDN) 等策略。虽然完全消除延迟不可能,但通过这些方法可显著改善网络性能。
2144 7
|
前端开发 C# 开发者
WPF开发者必读:MVVM模式实战,轻松构建可维护的应用程序,让你的代码更上一层楼!
【8月更文挑战第31天】在WPF应用程序开发中,MVVM(Model-View-ViewModel)模式通过分离关注点,提高了代码的可维护性和可扩展性。本文详细介绍了MVVM模式的三个核心组件:Model(数据模型)、View(用户界面)和ViewModel(处理数据绑定与逻辑),并通过示例代码展示了如何在WPF项目中实现MVVM模式。通过这种模式,开发者可以更高效地构建桌面应用程序。希望本文能帮助你在WPF开发中更好地应用MVVM模式。
864 1
|
前端开发 开发者 C#
WPF开发者必读:MVVM模式实战,轻松实现现代桌面应用架构,让你的代码更上一层楼!
【8月更文挑战第31天】在WPF应用程序开发中,MVVM(Model-View-ViewModel)模式通过分离应用程序的逻辑和界面,提高了代码的可维护性和可扩展性。本文介绍了MVVM模式的三个核心组件:Model(数据模型)、View(用户界面)和ViewModel(处理数据绑定和逻辑),并通过示例代码展示了如何在WPF项目中实现MVVM模式。通过这种方式,开发者可以构建更加高效和可扩展的桌面应用程序。
791 0