项目优化

85 阅读6分钟

JS优化

  1. 闭包返回的函数中不要使用eval原因
  2. 尽量不要使用with语句原因
  3. 不使用的变量通过GC回收掉(就是赋值null)原因
  4. 分包,拆包,打包打包优化,按需分割代码块
  • 浏览器加载当前页面所需要最少的代码量,可以显著提高加载速度,可以使用rollup

  • 平时通过浏览器的performance面板来对页面性能进行分析,了解整个页面的资源加载情况以及程序的执行时间,但项目上线时我们希望对项目整体文件依赖和访问速度进行优化,此时就需要一些插件来对包体积大小进行分析,这里用 (rollup-plugin-visualizer插件体积大小可视化。使用步骤(这里以vue3+vite项目举例)

    npm install rollup-plugin-visualizer --dev
    //然后在vite.config.js文件中配置
    import {visualizer} from "rollup-plugin-visualizer";
    export default defineConfig({
        plugins: [
            visualizer({
                open: true, //打包后自动跳转到浏览器打开
            })
        ]
    })
    //完成上述操作项目打包就会多一个html文件,运行即可查看每个包占用的体积大小
    
  1. 批量修改元素样式dom.className 代替dom.style.xxx
  2. 需要要对元素进行复杂的操作时,可以先隐藏(display:"none"),操作完成后再显示需要创建多个 DOM 节点时,使用 DocumentFragment 创建完后一次性的加入document
  3. 缓存 Layout 属性值,如:var left = dom.offsetLeft; 这样,多次使用left 只产生一次回流

CSS优化

讲优化之前先聊聊页面的重绘回流
回流:当 render tree 的一部分或全部的元素因改变了自身的宽高,布局,显示或隐藏,或者元素内部的文字结构发生变化 导致需要重新构建页面的时候,回流就产生了
重绘:当一个元素自身的宽高,布局,及显示或隐藏没有改变,而只是改变了元素的外观风格的时候,就会产生重绘。例如你改变了元素的 background-color
结论:回流必定触发重绘,而重绘不一定触发回流

  1. 尽量使用 css 属性简写,如:用 border 代替 border-width, border-style,border-color
  2. 尽量避免用 table 布局(table 元素一旦触发回流就会导致 table 里所有的其它元素回流)
  3. 避免使用 css 表达式(expression),因为每次调用都会重新计算值(包括加载页面)

webpack优化

webpack构建流程其中一个步骤是要找出所有的模块文件进行编译处理,那么我们可以在以下几个点上做优化处理

  1. 缩小文件的搜索范围,从而提升查找效率可以用 alias extensions 等配置缩小范围
  2. 减少需要解析的文件,使用 noParse 配置告诉webpack排除忽略指定文件,不对它们进行解析
  3. 避免重复编译第三方库,可以将第三方库单独打包到一个文件中,它不会跟着业务代码一起重新打包,它也能对webpack构建速度起到优化作用
  4. webpack在对代码进行压缩打包时,如果有多个js文件需要被压缩,它会一个一个进行压缩,可以使用parallelUglifyPlugin插件来开启多个子进程,采用并行方式对多个js文件进行压缩,从而提高构建速度。

vue优化

  1. v-if和v-show使用场景
  2. computed 和 watch区分使用场景
    • computed是计算属性,以来其他属性值,并且computed值有缓存,只有它依赖的属性值发生改变,下一次获取到的computed值才会重新计算。
    • watch是监听,每当监听的数据变化都会执行回调函数
    • 运用场景:
      • 当我们需要进行数值计算,并且依赖于其他数据时,应该使用computed,因为可以利用computed的缓存特性,避免每次获取值时,都要重新计算。
      • 当我们需要在数据变化时执行异步或开销较大的操作时,应该使用watch,使用watch选项允许我们执行异步操作(访问一个API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的
  3. 使用v-for时必须添加key,并避免同时使用v-if
    • v-for遍历必须添加key的原因:在列表数据进行遍历渲染时,需要为每一项item设置唯一的key值,方便vue内部机制精准找到该条列表数据。当state更新时,新的状态值和旧的状态值对比,较快的定位到diff
    • v-for遍历避免同时使用v-if的原因:v-for比v-if优先级高,如果每次都需要遍历整个数组,将会影响速度,尤其是当之需要渲染很小一部分的时候,必要情况下应该替换成computed属性。如下:
    <ul>
        <li v-for="user in userData" :key="user.id"></li>
    </ul>
    
    computed: {
        userData() {
            return this.users.filter((item) => item.isActive);
        },
    }
    
  4. 阻止数据劫持
    • vue会通过 Object.defineProperty 对数据进行劫持,来实现试图响应数据的变化,然而有时候我们的组件就是纯粹的数据展示,不会有任何改变,此时我们就不需要vue来劫持我们的数据,大量数据情况下,这能够很明显减少组件初始化时间,可以通过Object.freeze方法冻结一个对象,一旦被冻结的对象就无法被修改了
    export default {
        name: "",
        data() {
            return {
                users: {}
            };
        },
        async created() {
            const users = await axios.get("/api/uasrs/");
            this.users = Object.freeze(users)
        }
    }
    
  5. 事件销毁
    • vue组件销毁时,会自动清理它与其它实例的连接,解绑它的全部指令及事件监听器,但是仅限于组件本身的事件,如果使用addEventListene等方式是不会自动销毁的,所以需要手动销毁,避免造成内存泄露
  6. 图片懒加载
    • 未出现在用户可视区域的图片不加载,等到滚动到可视区域再去加载。(推荐插件 vue-lazyload)
  7. 路由懒加载
  8. 无限列表窗口化
    • 应用内存在非常长或者无限滚动的列表,采用窗口化
  9. 第三方插件按需加载
  10. 服务端渲染
  • 优点:
    • 更好的SEO,SPA页面是通过ajax获取,搜索引擎爬取工具(SEO)不会等待ajax异步完成之后再去爬取,所以在SPA中是抓取不到页面通过ajax获取到的内容。而SSR是直接由服务端返回已经渲染好的页面(数据已经包含在页面中),所以搜索引擎爬取工具可以抓取渲染好的页面
    • 更快的内容到达时间(首屏加载更快),SPA会等待所有的vue编译后的js文件都下载完之后才开始页面渲染,文件下载需要时间,所以首屏渲染需要一定的时间。而SSR直接由服务端渲染好页面之后返回显示,无需等待js文件加载再去渲染,所以SSR时间更快 - 缺点:
    • 服务端渲染支支持beforeCreate 和created两个钩子函数,这会导致一些外部扩展库需要特殊处理,才能在服务端渲染应用程序中运行,而且还需要处于Node.js server运行环境
    • 更多的服务器负载,在node.js中渲染比仅仅提供静态文件的server占用更多的CPU资源