hookehuyr

perf: 优化代码分割与懒加载以提升应用性能

- 将 PdfViewer 和 VideoPlayer 组件改为异步加载,减少初始包体积
- 为视频播放器相关依赖添加动态导入,避免未使用时加载
- 在打包配置中添加手动分包策略,将 vue-office 和图像工具库分离为独立 chunk
- 优化 Safari 浏览器检测逻辑,避免直接导入 video.js 以支持懒加载
......@@ -116,8 +116,9 @@
</template>
<script setup>
import { ref, watch, nextTick, onUnmounted } from 'vue';
import PDF from "pdf-vue3";
import { defineAsyncComponent, ref, watch, nextTick, onUnmounted } from 'vue';
const PDF = defineAsyncComponent(() => import("pdf-vue3"));
/**
* 组件属性定义
......
......@@ -62,11 +62,18 @@
</template>
<script setup>
import { ref } from "vue";
import { VideoPlayer } from "@videojs-player/vue";
import "video.js/dist/video-js.css";
import { defineAsyncComponent, ref } from "vue";
import { useVideoPlayer } from "@/composables/useVideoPlayer";
const VideoPlayer = defineAsyncComponent(async () => {
await import("video.js/dist/video-js.css");
await import("videojs-hls-quality-selector/dist/videojs-hls-quality-selector.css");
await import("videojs-contrib-quality-levels");
await import("videojs-hls-quality-selector");
const mod = await import("@videojs-player/vue");
return mod.VideoPlayer;
});
const props = defineProps({
options: {
type: Object,
......
import { ref, computed, watch, onMounted, onBeforeUnmount } from 'vue';
import { wxInfo } from "@/utils/tools";
import videojs from "video.js";
import { buildVideoSources, canPlayHlsNatively } from "./videoPlayerSource";
import { useVideoProbe } from "./useVideoProbe";
import { useVideoPlaybackOverlays } from "./useVideoPlaybackOverlays";
// 新增:引入多码率切换插件
import 'videojs-contrib-quality-levels'; // 用于读取 m3u8 中的多码率信息
import 'videojs-hls-quality-selector'; // 用于在播放器控制条显示“清晰度”切换菜单(支持 Auto/720p/480p 等)。
import 'videojs-hls-quality-selector/dist/videojs-hls-quality-selector.css';
const is_safari_browser = () => {
if (typeof navigator === 'undefined') return false;
const ua = navigator.userAgent || '';
const is_safari = /safari/i.test(ua) && !/chrome|crios|android|fxios|edg/i.test(ua);
return is_safari;
};
/**
* - 使用方法 :您无需修改业务代码。只要传入的视频 URL 是七牛云生成的多码率 .m3u8 地址,播放器控制条右下角会自动出现“齿轮”图标,用户点击即可切换清晰度(或选择 Auto 自动切换)。
......@@ -271,7 +273,7 @@ export function useVideoPlayer(props, emit, videoRef, nativeVideoRef) {
// 5. Video.js 播放器逻辑 (PC/Android)
const shouldOverrideNativeHls = computed(() => {
if (!isM3U8.value) return false;
if (videojs.browser.IS_SAFARI) return false;
if (is_safari_browser()) return false;
// 非 Safari 且不具备原生 HLS 时,强制 video.js 的 VHS 来解 m3u8
return !canPlayHlsNatively();
});
......
<!--
* @Date: 2025-10-22 10:45:51
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-10-22 10:54:10
* @LastEditTime: 2026-01-24 14:00:37
* @FilePath: /mlaj/src/views/study/PdfPreviewPage.vue
* @Description: 文件描述
* @Description: PDF预览页
-->
<template>
<div class="pdf-preview-page">
......@@ -12,9 +12,10 @@
</template>
<script setup>
import { computed, onMounted, onBeforeUnmount } from 'vue'
import { computed, defineAsyncComponent, onMounted, onBeforeUnmount } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import PdfViewer from '@/components/media/PdfViewer.vue'
const PdfViewer = defineAsyncComponent(() => import('@/components/media/PdfViewer.vue'))
const route = useRoute()
const router = useRouter()
......@@ -37,7 +38,7 @@ const pdfTitle = computed(() => {
const handleClose = () => {
// 清除刷新标记
sessionStorage.removeItem('pdf-preview-refreshed')
const returnId = route.query.returnId
const openMaterials = route.query.openMaterials
if (returnId) {
......
/*
* @Date: 2025-03-20 19:53:12
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2026-01-18 23:17:57
* @LastEditTime: 2026-01-24 13:56:05
* @FilePath: /mlaj/vite.config.js
* @Description: 文件描述
*/
......@@ -111,6 +111,11 @@ export default ({ mode }) => {
chunkFileNames: 'static/js/[name]-[hash].js',
entryFileNames: 'static/js/[name]-[hash].js',
assetFileNames: 'static/[ext]/[name]-[hash].[ext]',
manualChunks: (id) => {
if (!id.includes('node_modules')) return;
if (id.includes('@vue-office/docx') || id.includes('@vue-office/excel') || id.includes('@vue-office/pptx')) return 'vue-office';
if (id.includes('html2canvas') || id.includes('html-to-image')) return 'image-tools';
},
},
input: { // 多页面应用模式, 打包时配置,运行配置要处理root
main: path.resolve(__dirname, 'index.html'),
......