npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ztwcom

v1.0.13

Published

优化

Readme

目录


1. three.js 加载速度优化工具loadModel

1.1 背景

加载大量或者体积大的3D模型时,页面会出现加载缓慢问题,本插件目的在于解决此种问题。

1.2 优化逻辑

1.使用浏览器indexedDB浏览器缓存机制,模型缓存到浏览器内,只有首次进行后台接口加载,其余都存缓存中取,只消耗页面渲染的时间,节省资源调用的时间。 2.通过时间参数进行计算,超过时间进行接口调用自动更新模型,保证模型是最新状态。 3.可以在控制台Application中,indexedDB中查看缓存的模型文件。

1.3 准备

由于本插件暂时只支持以three.js为基础的底层逻辑,所以务必请使用three.js渲染3D模型,不适用于其他插件,暂时只支持加载GLB模型文件

1.4 参数设置

loadModel(db,glbUrl, GLTFLoader, timestamp = 1000 * 60 * 60 * 24)

|属性|说明|类型|默认值| |-|-|-|-| |db|数据库名称|Object|| |glbUrl|GLB模型路径|String|| |GLTFLoader|import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";引入||| |timestamp|模型更新时间戳(毫秒)|Number|1000 * 60 * 60 * 24|

1.5 返回值

此函数为Promise返回,返回值为模型的属性。

1.6 调用案例

1.通过 npm i ztwcom 下载依赖 2.使用 import {loadModel} from "ztwcom" 引入插件 3.引入three.jsGLTFLoader 4.调用 loadModel 5.具体调用实例

import { loadModel } from "ztwcom"
import * as THREE from "three";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"; // 引入glb文件格式
let db = {
    tdb: "time", // 时间库
    mdb: "modeldb" // 模型库
}
loadModel(db,'/static/mainMap/测试模型.glb',new GLTFLoader,1000 * 60 * 60 *1).then((res)=>{
  console.log(res.model,res.gltf)
})

1.7 实际效果

首次加载模型文件加载耗时168ms 首次加载 缓存加载模型文件未进行加载,直接调用缓存,无耗时 缓存加载

1.8 优化效果

1.优化后模型首次加载时间不变,缓存加载未调用模型资源,文件体量越大,文件数量越多,优化效果越明显,呈爆炸性增长效果显著。 2.拿本项目举例,首次消耗总时间199ms,二次消耗时间14ms,消耗时间为之前的十四分之一,效率提高了14倍

1.9 不足

1.暂时只支持three.js中GLB文件格式。 2.首次加载依旧需要调用接口。

1.10 浏览器兼容性

indexDB浏览器兼容性

1.11 indexedDB优势

1.优化效果显著。 2.大容量存储,通常没有存储容量的限制,对比cookie和localStorage。 3.支持复杂数据结构。 4.支持离线


2. OBJ文件转成GLB文件(3D模型后台支撑)

2.1 背景

项目上需要展示3D矿图效果,当时前端框架选用了three.js进行渲染引擎,成功的满足了需求进行效果展示,但在后期一直有性能问题的困扰,前端同学做了一些优化,包括分布加载、采用nginx请求头缓存配置、浏览器缓存等机制。 在实践中,我们发现glb格式要比obj格式的文件小一些,此外,obj在加载的过程也容易丢失样式、纹理等文件,由于obj模型文件通常为一组格式mlt(纹理、样式)、png(贴图),因此在做前端浏览器缓存时,也存在问题,后来和前端同学商量后,我们决定将obj转成glb进行尝试。

2.2 两种文件格式简介

obj文件格式:

obj文件专注于存储3D模型的几何数据(顶点、纹理坐标、法线等),通过纯文本描述模型结构,是一组可读的文本语句,eg:v表示顶点定义模型;ojb会依赖外部文件,材质信息需客外MTL文件存储,不支持动画功能,支持贴图文件,png/jpeg

glb文件格式:

glb是GLTF标准的二进制版本,全称为“GL传输格式二进制文件”,将3D模型、纹理、材质、动画甚至场景光源打包为单一二进制文件。是一体化封装文件,所有资源饭知JSON元数据、纹理等都可以整合一体,其设计目标就是快速加载与高效解析,适配WEB和移动端

|对比维度|OBJ|GLB| |-|-|-| |文件大小|文本格式冗余,所以文件相对大|二进制压缩,相对小| |功能支持|无动画/场景支持|支持动画、光照、相机视角| |文件可读性|文本格式易上手|二进制文件难理解难编辑| |兼容性|广泛支持(3D打印/建模软件)|主流引擎/WebGL原生支持| |材质管理|需额外的MLT、PNG|内嵌纹理与材制裁|

2.3 转换案例

1.选用Node插件进行转换,首先可以用npm install obj2gltf安装插件,然后通过命令进行转换

# 安装node插件
npm install obj2gltf

# 格式转换命令
obj2gltf -i   源文件.obj -o 目标文件.glb

# 示例如下所示:
obj2gltf -i  D:\data\mainMap\主要系统巷道\主要大巷.3dmobj\主要大巷_offset.obj -o D:\data\mainMap\主要系统巷道\主要大巷.3dmobj\主要大巷.glb 

2.这个搞定了,剩的工作就简单了,如何动达转换呢,我们可以通过Java程序监听指定目录的新增、修改操作,然后对其变化的文件执行脚本调用,进行转换,思路有了,来码代码,先容我再啰嗦两句,把步骤描述如下所示: (1) obj2gltf是通过npm install obj2gltf安装的插件,用于模型格式转换操作 (2) 包下的node_module是将npm install 时产生的所有npm依赖都copy进去了。否则缺少依赖; (3) application.yml 中需要配置脚本文件的绝对路径,需引用obj2gltf下的bin下的obj2gltf.js (4) java引入Pom依赖 (5) java调用IO包中的Process类执行命令脚本 代码结果如下所示: obj转glb obj2gltf -i D:\data\mainMap\主要系统巷道\主要大巷.3dmobj\主要大巷_offset.obj -o D:\data\mainMap\主要系统巷道\主要大巷.3dmobj\主要大巷.glb

2.4 模型转换工具类

写了一个转换工具类,参数如下所示:

pom.xml依赖

<dependency>
    <groupId>de.javagl</groupId>
    <artifactId>jgltf-model</artifactId>
    <version>2.0.0</version>
</dependency>

<!-- https://mvnrepository.com/artifact/de.javagl/obj -->
<dependency>
    <groupId>de.javagl</groupId>
    <artifactId>obj</artifactId>
    <version>0.3.0</version>
</dependency>

Util工具类

package com.zhanglu.test.handle.util;
import com.zhanglu.test..handle.obj2gltf.ConvertObjToGltf;
import com.zhanglu.test..handle.obj2gltf.obj.BufferStrategy;
import com.zhanglu.test..handle.obj2gltf.obj.GltfWriteType;
import com.zhanglu.test..handle.obj2gltf.obj.IndicesComponentType;
import lombok.extern.slf4j.Slf4j;
import java.io.BufferedReader;
import java.io.InputStreamReader;
@Slf4j
@SuppressWarnings("all")
public class NodeJsExcutorUtil {
    public static void convertObjToGlb(String objPath,String glbPath,String scriptPath) {
        BufferedReader reader = null;
        try {
            // 构建命令(根据安装方式调整)
            String[] command = {
                   "node", //本地windows启动不加这个命令,不然会报错
                    scriptPath,  // 局部安装使用 npx
                    "-i", objPath.trim(),
                    "-o", glbPath.trim()
            };
            ProcessBuilder builder = new ProcessBuilder(command);
            System.out.println(builder.command());
            builder.redirectErrorStream(true); // 将错误输出和标准输出合并,便于读取
            Process process = builder.start();

             reader = new BufferedReader(new InputStreamReader(process.getInputStream(),"utf-8"));
            String line;
            while ((line = reader.readLine()) != null) {
              log.info(line);
            }
            process.waitFor(); // 等待进程结束
            log.info("【glb文件】转换成功");
        } catch (Exception err) {
            err.printStackTrace();
          log.error("【glb文件】转换失败:{}",err.getMessage());

        }finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
 
    public static void main(String[] args) {
      //本地如果是windows环境用以下脚本
        String scriptPath = "D:\\web\\node_modules\\.bin\\obj2gltf.cmd"; 
       //如果是Linux脚本用以下脚本 
      //  String scriptPath = "scriptPath: /data/webapp/calamity/handle/obj2gltf/bin/obj2gltf.js";
        String objPath="D:\\data\\mainMap\\主要系统巷道\\主要大巷.3dmobj\\主要大巷.obj";
        String glbPath="D:\\data\\mainMap\\主要系统巷道\\主要大巷.3dmobj";
        String glbFilePath="D:\\data\\mainMap\\主要系统巷道\\主要大巷.3dmobj\\主要大巷_1.glb";
        NodeJsExcutorUtil.convertObjToGlb(objPath,glbFilePath,scriptPath);
    }
}

Linux环境脚本引用说明

1.Linux环境脚本路径node安装obj2gltf包下的:obj2gltf/bin/obj2gltf.js; 2.命令:node /脚本实际路径/obj2gltf.js -i objFile.obj -o glbFile.glb

obj转glb

windows环境脚本引用说明

1.Windows 环境脚本路径node安装obj3gltf包下:node_modules\.bin\obj2gltf.cmd 2.命令: /脚本实际路径/obj2gltf.cmd -i objFile.obj -o glbFile.glb

obj转glb

感谢张璐组长技术支持,转自https://blog.csdn.net/xuxiannian/article/details/148792172


3. 页面自适应终极解决方案v-scale-screen

3.1 背景

大部分页面有2种自适应方式: 1.支持拉伸,长宽自适应,浏览器始终充满,图片可能会被异形屏(带鱼屏)拉扯变形。 2.固定比例宽高,如1920*1080,始终按照本比例自适应,修改窗口尺寸会出现空白,但图片不会被异常拉伸变形。 根据项目不同可能会选择对应的自适应方式,故需要一款能适应两种情况的自适应方案。

3.2 插件优势

1.v-scale-screen 插件基于vue.js,实现页面自适应,兼容PC端和移动端。 2.上述2种自适应方式都能满足,且更改方便。 3.无需转换单位,按照UI图px值即可自适应

3.3 配置项

|属性|说明|类型|默认值| |-|-|-|-| |width|大屏宽度|Number or String|1920| |height|大屏高度|Number or String|1080| |autoScale|自适应配置,配置为 boolean 类型时,为启动或者关闭自适应,配置为对象时,若 x 为 true,x 轴产生边距,y 为 true 时,y 轴产生边距,启用 fullScreen 时此配置失效|Boolean or {x:boolean,y:boolean}|true| |delay|窗口变化防抖延迟时间|Number or String|500| |fullScreen|全屏自适应,启用此配置项时会存在拉伸效果,同时 autoScale 失效,非必要情况下不建议开启|Boolean|false| |boxStyle|修改容器样式,如居中展示时侧边背景色,符合 Vue 双向绑定 style 标准格式|Object|| |wrapperStyle|修改自适应区域样式,符合 Vue 双向绑定 style 标准格式|Object|| |bodyOverflowHidden|启用后 body 的样式会自动设置为 overflow: hidden|Boolean|true|

3.4 调用案例

1.安装 npm i v-scale-screen。 2.在起始页面中引入 import VScaleScreen from "v-scale-screen"。 3.在components中注入组件。 4.最外层添加 VScaleScreen 标签。 5.传入相关配置项即可。

App.vue(template)

<template>
  <VScaleScreen :width="scaleScreen.width" :height="scaleScreen.height" :autoScale="scaleScreen.autoScale"
  :fullScreen="scaleScreen.fullScreen" :boxStyle="scaleScreen.boxStyle">
    <div id="app" :style="`width: ${scaleScreen.width}px; height: ${scaleScreen.height}px`">
      <router-view></router-view>
    </div>
  </VScaleScreen>
</template>

App.vue(script)

import VScaleScreen from 'v-scale-screen'
data () {
  return {
    scaleScreen: {
      width: 1920, // ui画布尺寸
      height: 1080, // ui画布尺寸
      autoScale: {
        x: true,
        y: true
      },
      fullScreen: true, // 是否拉伸(固定1920*1080带白边用false,拉伸长宽满屏用true)
      boxStyle: {
        background: 'blue' // 背景色
      }
    }
  }
}
components: {
  VScaleScreen
},

3.5 实际效果

固定1920*1080(窗口全屏) 固定1920*1080(全屏) 固定1920*1080(特异尺寸窗口) 固定1920*1080(特异尺寸窗口) 固定1920*1080(F11全屏) 固定1920*1080(F11全屏)

拉伸1920*1080(窗口全屏) 拉伸1920*1080(全屏) 拉伸1920*1080(特异尺寸窗口) 拉伸1920*1080(特异尺寸窗口) 拉伸1920*1080(F11全屏) 拉伸1920*1080(F11全屏)

3.6 v-scale-screen优势

1.适配各种需求的大屏。 2.只需修改一个参数fullScreen即可更改适配模式。 3.不用转换单位直接用px。 4.以1920*1080基础进行适配,虽有变形但为宽高等比形变

3.7 分辨率,调度大屏相关问题

1.页面清晰度与显示器分辨率有关系,显示器分辨率越高,页面越清晰,投到调度室大屏越清晰。 2.页面清晰度与元素尺寸有关系,尺寸越大,字号越大,字重越小,页面越清晰,投到调度室大屏越清晰。(与页面缩放无关,页面缩放感觉清晰了,根本原因是元素尺寸变大了) 3.已有自适应的页面投到大屏后模糊与前端逻辑无关优化方向着重UI,以及硬件设备显示器的分辨率。


4. 语音播报封装speaker

4.1 背景

1.本插件以原生SpeechSynthesisUtterance为基础封装。 2.众多项目对语音播报功能需求量大。 3.语音播报功能重新开发功能复杂不稳定,复用之前的代码会出现代码冗余性高。

4.2 准备

1.本插件出于简化逻辑,便于使用,提供语音按顺序循环播放消除播放暂停播放恢复播放

4.3 参数设置

speakMsg(soundDataMap,interval=2000) cancel() resume() pause()

|属性|说明|类型|默认值| |-|-|-|-| |soundDataMap|语音播报数据|Map|| |interval|每条播报之间的时间间隔|Number|2000|

4.5 调用案例

1.通过 npm i ztwcom 下载依赖 2.使用 import {speakMsg, cancel,resume,pause} from "ztwcom" 引入插件 3.调用 speakMsg, cancel,resume,pause 4.具体调用实例

import { speakMsg, cancel } from "ztwcom"
let msg = {
  test1:"语音播报测试数据1",
  test2:"语音播报测试数据2",
  test3:"语音播报测试数据3",
  }
speakMsg(msg,3000) // 语音开启播报
cancel() // 语音播报取消
resume() // 语音播报恢复
pause() // 语音播报暂停

4.6 排查语音播报失效原因

1.保障谷歌浏览器,360极速浏览器最新版本 speaker1.png

2.保障计算机声音为开启状态 speaker2.png speaker3.png 如果计算机能发出任何声音,此处就能判断为开启状态(包含不限于视频声音,会议声音,语音声音)

3.查看浏览器是否开启声音 (1)点击浏览器右上角设置 speaker4.png (2)点击隐私与安全->点击网站设置speaker5.png (3)查找即使项目的网址,下方声音选择允许speaker6.png

4.查找是否有中文语音包 (1)按下win+R (2)输入regedit speaker7.png (3)一级一级查找路径 【计算机/HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens】 speaker8.png CN为中文语音包,查看文件是否完整,若不完整则系统少装了TTS中文语音包,需要单位运维人员协助,安装符合公司版本需求的语音包

4.7 不足

语音播报无返回值