前端开发项目优化总结

117 阅读8分钟

整体优化

  1. 将js文件和css文件放在html外部,因为js文件和css文件会被缓存在浏览器。如果js文件和css文件在html中浏览器每次请求html文档会重新下载
  2. favicon.ico要足够小最好在1k以下,如果以后想换的话不要重命名
  3. 图片尽量使用webp格式图片
  4. 对于一些不必要立即显示的节点,我们可以采用懒加载技术。在需要使用到的时候,再去加载该文件
  5. 骨架屏提升用户体验
  6. 使用字体图标/矢量图代替图片图标,
  7. 减少重绘重排
  8. 使用css3动画或者cavas动画,js部分动画改为requestAnimationFrame动画

html优化

  1. 路由懒加载
  2. 减少DOM数量,document.getElementsByTagName('*').length可以获取页面dom数量
  3. 尽量减少iframe标签的使用
  4. 不要使用html缩放图片,例如:1.jpg是一张500x500的图,<img src="./img/1.jpg" width="100px" height="100px" alt="">,如果需要100x100的图,那么就不要使用设置宽高种方式,可以直接将1.jpg原图变成100x100的
  5. img的src不要为空,这种情况浏览器会向服务器发送另一个请求
  6. 响应式图片
        <source srcset="banner_w1000.jpg" media="(min-width: 801px)"> 
        <source srcset="banner_w800.jpg" media="(max-width: 800px)"> 
        <img src="banner_w800.jpg" alt="">
    

css优化

  1. 静态资源上传cdn,使用cdn分散服务器的压力
  2. 少用css表达式,例如 width: calc(100% - 10px);
  3. 选择link标签舍弃@import
  4. 样式放在顶部
  5. 动画能用css别用js
  6. 降低 CSS 选择器的复杂性,CSS 选择器优先级内联 > ID选择器 > 类选择器 > 标签选择器。浏览器读取选择器,遵循的原则是从选择器的右边到左边读取。看个示例
        #block .text p {
                color: red;
        }
    
    第一步:查找所有 P 元素
    第二步:查找结果 1 中的元素是否有类名为 text 的父元素
    第三步:查找结果 2 中的元素是否有 id 为 block 的父元素
    结论: 选择器越短越好。尽量使用高优先级的选择器,例如 ID 和类选择器。

js优化

  1. 延迟加载组件,可以使用onload事件。例如拖放以及动画的库这种就可以延迟加载
  2. 预加载,在浏览器空闲时间请求将来会用到的组件
  3. 减少DOM的访问,JavaScript访问DOM元素是很慢的,所以为了让页面反应更迅速,应该
    • 缓存已访问过的元素的索引
    • 先“离线”更新节点,再把它们添到DOM树上
    • 避免用JavaScript修复布局问题
  4. 优化事件处理器,太多事件处理器被添加到了DOM树的不同元素上会导致页面不够灵敏,例如一个div中有10个按钮,那么应该给div添加一个事件处理器,点击按钮会冒泡到div上,然后通过event.target区分点击的是哪个按钮
  5. 脚本放在底部
  6. moment.js换成day.js 因为moment.js有70多kb,但是day.js只有2kb
  7. if-else和switch判断条件数量越多时,使用查找表,如下:
        switch (index) { 
            case '0': 
                return result0 
            case '1': 
                return result1 
            case '2': 
                return result2
    
    转换为查找表
        const results = [result0,result1,result2] 
        return results[index]
    
  8. 不要覆盖原生方法,无论你的 JavaScript 代码如何优化,都比不上原生方法。因为原生方法是用低级语言写的(C/C++),并且被编译成机器码,成为浏览器的一部分。当原生方法可用时,尽量使用它们,特别是数学运算和 DOM 操作。

数据请求优化

  1. 尽量减少http请求次数
  2. 尽量避免重定向
  3. 利用缓存存放数据,例如localStorage
  4. 并发
    • 队列: 创建一个请求队列,并且同时只处理一定数量的请求。一旦当前处理的请求完成,就从队列中取出下一个请求进行处理。

    • 批处理: 将多个请求合并成一个批量请求,如果 API 支持的话。这减少了请求数量,但可能需要服务器端的支持。

    • 节流: 在特定时间内限制请求的数量。例如,每秒只允许发出一个请求。

    • 防抖: 如果有大量连续的请求,在一定的延迟后只执行最后一次请求,这通常用于搜索框等场景。

    • Promise控制: 使用 Promise.all 来管理多个请求,或者使用 Promise.race 来处理多个请求中最快返回的结果。

  5. cookie,保证cookie尽可能小,并设置合适的有效期
  6. 压缩可以通过减少HTTP响应的大小来缩短响应时间。Content-Encoding: gzip,服务器看到这个请求头,它就会用客户端列出的一种方式来压缩响应。web服务器通过Content-Encoding响应头来通知客户端
  7. 尽量使用get请求,因为get比post快。原因请移步该文章
  8. 尽早清空缓存区
    • 当用户请求一个页面时,服务器需要用大约200到500毫秒来组装HTML页面,在这期间,浏览器闲等着数据到达。PHP中有一个flush()函数,允许给浏览器发送一部分已经准备完毕的HTML响应,以便浏览器可以在后台准备剩余部分的同时开始获取组件,好处主要体现在很忙的后台或者很“轻”的前端页面上。
    • 较理想的清空缓冲区的位置是HEAD后面,因为HTML的HEAD部分通常更容易生成,并且允许引入任何CSS和JavaScript文件,这样就可以让浏览器在后台还在处理的时候就开始并行获取组件。
          </head>
          <?php flush(); ?>
          <body>
      
  9. 使用CDN
    • 使用CDN的原因
      • 用户与服务器之间的实际地理距离。这个距离越远,数据传输的时间就越长,这就可能导致网页加载速度变慢。
      • 用户80%到90%的响应时间都花在下载页面组件上了(当用户访问一个网页时,大部分的加载时间其实都是在下载网页的各个组件,如图片、样式表、JavaScript 文件等。因此,通过优化这些组件的加载速度,可以显著提高网页的整体加载速度)。
      • CDN 在决定从哪个服务器向用户发送内容时,会考虑网络距离。通常,CDN 会选择距离用户最近的服务器,以此来减少数据传输的时间,提高加载速度。
    • 内容分发网络(CDN) :CDN 是一种解决方案,它通过在全球各地部署服务器的方式,将网站内容分散到多个地理位置。这样,用户可以从离他们最近的服务器获取内容,从而减少数据传输的时间,提高网页的加载速度。所以将你的静态内容(如图片、样式表、JavaScript 文件等)部署到 CDN,然后让 CDN 来处理内容的分发。
  10. 通过设置 HTTP 头部信息来控制浏览器缓存的行为。(Expires和Cache-Control)
    • Expires:这是一个 HTTP 响应头,它告诉浏览器资源的过期时间。例如,Expires: Thu, 15 Apr 2010 20:00:00 GMT 表示该资源在 2010-04-15 20:00:00 后过期。过期后,浏览器在下次需要这个资源时,会向服务器发送新的请求
    • Cache-Control:这也是一个 HTTP 响应头,它提供了更多的控制缓存行为的选项。例如,Cache-Control: max-age=3600 表示资源将在 3600 秒(即1小时)后过期。Cache-Control 还可以设置为 no-cache,表示浏览器必须在使用缓存的资源之前,先向服务器验证资源是否已更新
    • 如果你用的是Apache服务器,用ExpiresDefault指令来设置相对于当前日期的有效期。ExpiresDefault "access plus 10 years"这个表示从请求时间起10年的有效期
  11. 合并请求
    • 为了减少请求时间,为了减小服务器压力。ajax请求并不是没有成本的。每次请求都需要进行TCP的三次握手和四次挥手,解析报文等一系列的过程,这些过程都需要时间去执行。并且,浏览器在同一域名下的请求并发数有限制,同一域名下同一个请求只能并发一个,不同类型请求(比如GET/POST)并发个数基本在4-6个之间。假设当前浏览器的并发请求有6个。那么第7个请求就需要等前6个请求中任意一个完成以后才可以从任务队列中被拉出去执行。所以,合并请求可以在一定程度上减少资源响应时间,给用户带来更好的使用体验。

Vue优化

  1. v-for 遍历必须为 item 添加 key,且避免同时使用 v-if
  2. Object.freeze 方法来冻结一个对象,一旦被冻结的对象就再也不能被修改了,可以禁止Object.defineProperty 对数据进行劫持
  3. 组件销毁时清除页面事件,例如定时器等
  4. 第三方插件按需引入

本文部分内容参考了并发雅虎前端优化35军规