7.5 KiB
7.5 KiB
JS加载配置优化经验总结
问题背景
在开发共享单车项目时,遇到了JavaScript文件加载的重复和冲突问题。项目存在多种JS加载方式:
- Nuxt.js 全局配置加载
- Vue组件动态加载
- 页面级手动加载
- 重复依赖加载
问题分析
1. 多重加载方式冲突
方式一:Nuxt.js 全局配置
// nuxt.config.ts
app: {
head: {
script: [
{
src: '/js/jquery-1.10.2.js',
type: 'text/javascript',
defer: true
},
{
src: '/js/bootstrap.min.js',
type: 'text/javascript',
defer: true
}
]
}
}
方式二:Vue组件动态加载
// 各个组件中的重复代码
const loadJSFiles = () => {
const jsFiles = [
'/js/jquery-1.10.2.js',
'/js/bootstrap.min.js',
'/js/index.js',
'/js/gopcOm.js'
]
jsFiles.forEach(src => {
const existingScript = document.querySelector(`script[src="${src}"]`)
if (!existingScript) {
const script = document.createElement('script')
script.src = src
script.type = 'text/javascript'
document.head.appendChild(script)
}
})
}
方式三:页面级手动加载
// 首页组件中的配置化加载
const loadResources = () => {
pageConfig.jsFiles.forEach(src => {
if (!document.querySelector(`script[src="${src}"]`)) {
const script = document.createElement('script')
script.src = src
script.type = 'text/javascript'
document.head.appendChild(script)
}
})
}
2. 重复加载问题
问题表现:
- 同一个JS文件被多次加载
- 不同组件中重复相同的加载逻辑
- 加载顺序不一致导致依赖问题
- 性能浪费和潜在冲突
重复代码统计:
loadJSFiles函数在 8个组件 中重复出现- 相同的JS文件列表在多个地方维护
- 缺乏统一的加载策略
3. 依赖关系混乱
// 不同组件中的加载顺序不一致
// 组件A: jquery -> bootstrap -> index -> gopcOm
// 组件B: bootstrap -> gopcOm -> index -> jquery
// 组件C: index -> jquery -> bootstrap -> gopcOm
解决方案演进
阶段一:识别问题
通过代码分析发现:
- 8个组件中存在相同的JS加载逻辑
- 缺乏统一的资源管理策略
- 重复代码维护困难
阶段二:配置化改造
将硬编码的JS文件列表提取到配置文件:
// app/data/indexData.ts
export const pageConfig = {
jsFiles: [
'/js/jquery-1.10.2.js',
'/js/bootstrap.min.js',
'/js/index.js',
'/js/gopcOm.js'
],
cssFiles: [
'/css/bootstrap.min.css',
'/css/main2.css',
'/css/main.css',
'/css/yuxi2019.css'
]
}
阶段三:全局配置优化
最终选择Nuxt.js全局配置作为主要加载方式:
// nuxt.config.ts
export default defineNuxtConfig({
app: {
head: {
script: [
{
src: '/js/jquery-1.10.2.js',
type: 'text/javascript',
defer: true
},
{
src: '/js/bootstrap.min.js',
type: 'text/javascript',
defer: true
},
{
src: '/js/index.js',
type: 'text/javascript',
defer: true
},
{
src: '/js/gopcOm.js',
type: 'text/javascript',
defer: true
}
]
}
}
})
最终解决方案
1. 全局配置策略
选择理由:
- 统一管理:所有JS文件在nuxt.config.ts中统一配置
- 性能优化:利用Nuxt.js的预加载和缓存机制
- 依赖管理:确保加载顺序正确
- 维护简单:只需在一个地方修改配置
2. 移除重复代码
清理各组件中的重复加载逻辑:
// 移除前:每个组件都有
const loadJSFiles = () => {
const jsFiles = ['/js/jquery-1.10.2.js', ...]
// 重复的加载逻辑
}
// 移除后:依赖全局配置
// 组件中不再需要手动加载JS文件
3. 配置优化
// 优化后的全局配置
app: {
head: {
script: [
// 基础依赖
{
src: '/js/jquery-1.10.2.js',
type: 'text/javascript',
defer: true
},
{
src: '/js/bootstrap.min.js',
type: 'text/javascript',
defer: true
},
// 业务逻辑
{
src: '/js/index.js',
type: 'text/javascript',
defer: true
},
{
src: '/js/gopcOm.js',
type: 'text/javascript',
defer: true
}
]
}
}
技术要点
1. 加载顺序管理
// 正确的依赖顺序
1. jQuery (基础库)
2. Bootstrap (UI框架)
3. 业务逻辑 (index.js, gopcOm.js)
2. 性能优化
// 使用defer属性优化加载
{
src: '/js/jquery-1.10.2.js',
type: 'text/javascript',
defer: true // 异步加载,不阻塞页面渲染
}
3. 重复加载检测
// 组件中的重复检测逻辑
const existingScript = document.querySelector(`script[src="${src}"]`)
if (!existingScript) {
// 只有不存在时才加载
}
最佳实践
1. 统一配置原则
- 所有全局JS文件在nuxt.config.ts中配置
- 避免在组件中重复加载
- 使用配置文件管理资源列表
2. 依赖关系管理
- 确保加载顺序正确
- 基础库优先加载
- 业务逻辑后加载
3. 性能优化
- 使用defer属性异步加载
- 避免重复加载
- 利用浏览器缓存
4. 维护性考虑
- 集中管理配置
- 减少重复代码
- 便于后续维护
经验总结
1. 问题识别
- 通过代码分析快速发现重复加载问题
- 识别多种加载方式的冲突
- 理解依赖关系的重要性
2. 解决方案选择
- 全局配置 vs 组件级加载
- 性能 vs 灵活性权衡
- 维护性 vs 功能完整性
3. 实施过程
- 渐进式重构,避免破坏现有功能
- 充分测试,确保加载顺序正确
- 文档记录,便于后续维护
4. 技术决策
- 选择Nuxt.js全局配置作为主要方式
- 移除组件中的重复加载逻辑
- 优化加载性能和依赖管理
配置对比
优化前:分散式加载
// 8个组件中都有相同的加载逻辑
const loadJSFiles = () => {
const jsFiles = ['/js/jquery-1.10.2.js', ...]
// 重复代码
}
优化后:集中式配置
// nuxt.config.ts 统一配置
app: {
head: {
script: [
{ src: '/js/jquery-1.10.2.js', defer: true },
{ src: '/js/bootstrap.min.js', defer: true },
{ src: '/js/index.js', defer: true },
{ src: '/js/gopcOm.js', defer: true }
]
}
}
面试者简答
面试官:请描述一次你优化前端资源加载的经历。
我:在开发共享单车项目时,发现项目存在严重的JS文件重复加载问题。8个组件中都有相同的loadJSFiles函数,导致同一个jQuery文件被多次加载,不仅浪费性能,还可能导致依赖冲突。
我首先通过代码分析识别了问题:项目同时存在Nuxt.js全局配置、Vue组件动态加载和页面级手动加载三种方式,缺乏统一的资源管理策略。然后我选择了全局配置作为主要解决方案,将所有JS文件统一在nuxt.config.ts中配置,并移除了组件中的重复加载逻辑。
最终实现了集中式资源管理,减少了重复代码,优化了加载性能,并确保了依赖关系的正确性。这次经历让我深刻理解了前端资源管理的重要性,以及如何通过合理的架构设计来避免重复加载问题。