MENU

网站字体瘦身最最小化

February 7, 2023 • 默认分类,Typecho,Python阅读设置

本站使用后woff2字体文件只有148kb,仅比FiraCode的woff2字体文件大8kb,而且完全不会影响后期其他生僻字的添加与修改,如果我们删除了一些含有生僻字的文章,字体文件也会相对应减少。
最近在十年之约群里面看到大家讨论网站的字体,大家都是用fonttools进行字体瘦身,使用常用的3500字或者6500字来瘦身,我早在一年前也是这样做的,但是最近两天发文章 胡鑫宇事件 和电视剧《狂飙》的这两篇文章的时候,我就发现鑫和飙这两个字竟然没有在常用3500字里面。
我就想这样如果我每次遇到没在字体里面的字就打开电脑进行一次瘦身的话,就很麻烦。联想到另一个群有个人的网站友链中,如果有人的网站301到了另外一个域名,他的网站会自动更新到301的域名,我就想字体能不能也自动根据博客文章里面的文字更新。
于是方法来了
思路:
首先Typecho的文字全存在数据库,那么我们只需要获取数据库里面的中文就可以了,那就直接把数据库里面含有中文的几个表导出下来,全部合成一个txt文件,然后使用fonttools进行字体瘦身,顺便直接转为woof2格式就可以了,然后写出来一个Python脚本,让这个脚本定时去执行或者我们手动去执行就可以了。

首先我们需要导出的Typecho表只需要这六个
typecho数据库
导出为CSV之后,我们可以通过正则表达式,只保留中文以及中文符号,然后把他合成为一个txt文件,文件里面的汉字也不需要去重
网站数据库中的中文
然后使用fonttools进行瘦身就可以了,瘦身完再把字体转成woff2,然后更新到网站目录上面就可以了,比如现在这个“慧”是没有的,它是第一次在我的网站中出现,当脚本自动执行之后,他就可以正常显示了
下面是最终的python代码,我也懒得优化,反正能跑就可以

import re
import os
import pymysql
import pandas as pd
import sys
from fontTools.subset import main as ss
from fontTools.ttLib import TTFont


class MysqlSave:

    def __init__(self):
        self.content = pymysql.Connect(
            host='172.1.2.255',
            port=3306,
            user='user',
            password='password',
            database='typecho',
            charset='utf8',  # 使用字符集
        )
        self.cursor = self.content.cursor()

    def search_and_save(self, sql, csv_file):
        self.cursor.execute(sql)

        des = self.cursor.description
        title = [each[0] for each in des]

        result_list = []
        for each in self.cursor.fetchall():
            result_list.append(list(each))

        df_dealed = pd.DataFrame(result_list, columns=title)
        df_dealed.to_csv(csv_file, index=None, encoding='utf_8_sig')


def go(path):
    f = open(path, "r", encoding='utf-8')
    print(path)
    data = f.readlines()
    f.close()

    for line in data:
        regular = re.findall('[\u3002\uff1b\uff0c\uff1a\u201c\u201d\uff08\uff09\u3001\uff1f\u300a\u300b\u4e00-\u9fa5]',
                             line)
        str1 = "".join(regular)
        f1 = open("ss.txt", "a+", encoding='utf-8')
        f1.writelines(str1)

        f1.close()


if __name__ == '__main__':
    mysql = MysqlSave()
    mysql.search_and_save('SELECT * FROM typecho_comments', './sql/typecho_comments.csv')
    mysql.search_and_save('SELECT * FROM typecho_contents', './sql/typecho_contents.csv')
    mysql.search_and_save('SELECT * FROM typecho_metas', './sql/typecho_metas.csv')
    mysql.search_and_save('SELECT * FROM typecho_options', './sql/typecho_options.csv')
    mysql.search_and_save('SELECT * FROM typecho_users', './sql/typecho_users.csv')

    sql_list = os.listdir('./sql/')
    for paths in sql_list:
        go("./sql/" + paths)

    sys.argv = [None, 'PingFang_Bold.ttf', '--text-file=./ss.txt']
    ss()
    f = TTFont('PingFang_Bold.subset.ttf')
    f.flavor = 'woff2'
    f.save('PingFang_Bold.woff2')
    os.remove("ss.txt")

然后我放到了宝塔的计划任务,每天凌晨执行一次应该就可以了,也可以在加上CDN的API刷新一下字体文件的缓存

Leave a Comment

3 Comments
  1. 确实是个优化字体的好办法 @(哈哈) 感谢分享

  2. 博主您好,但如果使用这个方案后再使用 ajax 获取一言呢?可能还是遇到字体缺失的问题吧。

    1. @Star_caorui把一言中的文字子集化