WS的博客日志

奔赴山海,保持热爱

性能优化目标

  • 保证资源更快的 加载速度(网络层面)
  • 保证视图更快的 渲染速度/交互速度 (浏览器层面)

性能检测工具

  • Network

  • performance 面板(提供一个具体的执行过程)

  • lighthouse 面板(网站整体评估)

  • webPageTestwebpack-bundle-analyze(依赖打包构建图)、 speed-measure-webpack-plugin(构建费时分析)

性能指标数据收集

  • performance API

    浏览器端的全局对象 window 上有一个名为 performance 的属性,它是一个用于支持 IE9 以上及 webkit 内核浏览器中用于记录页面 加载解析 过程中关键时间点的机制

  • Web Vitals 模块化库

阅读全文 »

前端网络安全是Web开发中非常重要的一部分,确保应用程序的安全性可以防止各种攻击,保护用户数据和隐私。以下是一些常见的前端攻击类型及其防御措施:

常见的前端攻击类型

  1. 跨站脚本攻击(XSS)

    • 描述:攻击者在网页中注入恶意脚本,当用户访问该网页时,脚本会在用户的浏览器中执行,窃取用户数据或执行其他恶意操作。

    • 防御措施

      • 输入验证和输出编码:对用户输入进行严格验证,并对输出进行编码,防止恶意脚本注入。
      • 使用安全的库和框架:使用经过安全审计的库和框架,如React、Angular等,它们内置了防御XSS的机制。
      • 内容安全策略(CSP):配置CSP头,限制页面可以加载的资源,防止恶意脚本执行。
  2. 跨站请求伪造(CSRF)

    • 描述:攻击者诱导用户在已登录的情况下访问恶意网站,利用用户的身份执行未授权的操作。

    • 防御措施

      • CSRF令牌:在表单提交或AJAX请求中加入CSRF令牌,服务器验证令牌的有效性。
      • SameSite Cookie属性:设置Cookie的SameSite属性为Strict或Lax,限制跨站请求携带Cookie。
      • 双重提交Cookie:在请求中同时提交Cookie和表单字段,服务器验证两者是否一致。
  3. 点击劫持(Clickjacking)

    • 描述:攻击者在透明的iframe中嵌入目标网站,诱导用户点击,执行未授权的操作。

    • 防御措施

      • X-Frame-Options:设置HTTP头X-Frame-Options为DENY或SAMEORIGIN,防止页面被嵌入iframe。
      • **Content Security Policy (CSP)**:配置CSP头,使用frame-ancestors指令限制页面可以被嵌入的来源。
  4. SQL注入

    • 描述:攻击者通过输入恶意SQL语句,操纵数据库查询,窃取或篡改数据。

    • 防御措施

      • 参数化查询:使用参数化查询或预编译语句,防止SQL注入。
      • 输入验证:对用户输入进行严格验证,过滤特殊字符。
  5. 本地存储攻击

    • 描述:攻击者通过XSS或其他手段获取本地存储中的敏感数据。

    • 防御措施

      • 敏感数据加密:对存储在本地存储中的敏感数据进行加密。
      • 减少本地存储使用:尽量减少在本地存储中保存敏感数据,使用更安全的存储方式。
阅读全文 »

文件上传是一个常见的需求,尤其是大文件的上传。为了提高上传效率和用户体验,我们可以采用并发切片上传和秒传技术。本文将介绍如何使用这些技术,并提供一个完整的实现示例。

1. 实现思路

  • 文件切片:将大文件分成多个小切片,每个切片大小为1MB。
  • 并发上传:使用并发池控制同时上传的切片数量,避免过多并发请求导致服务器压力过大。
  • 秒传:在上传前通过文件的哈希值验证文件是否已经存在,如果存在则直接返回上传成功。
  • 进度条:实时显示上传进度,提升用户体验。
阅读全文 »

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
export default class WorkerWrapper {
constructor(work, options) {
this.worker = new work();
this.callbacks = new Map();
this.worker.onmessage = (event) => {
const { id, data } = event.data;
const callback = this.callbacks.get(id);
if (callback) {
callback(data);
this.callbacks.delete(id);
}
};
}

postMessage(data, callback) {
const id = Math.random().toString(36).substr(2);
if (callback) {
this.callbacks.set(id, callback);
}
this.worker.postMessage({ id, data });
}

// 终止进程
terminate() {
this.worker.terminate();
}
}

前言

迎的两大框架。无论是企业级应用,还是个人项目,开发者常常面临“Vue 和 React 该选哪个?”的问题。本文将从设计理念、响应式原理、虚拟 DOM、生态体系、性能、学习曲线等多个维度深入剖析两者的异同,帮助开发者做出更合适的技术选型。


一、设计理念对比

特性 Vue React
定位 渐进式框架 UI 库
编程范式 选项式(Option API) + 组合式(Composition API) 函数式
架构设计 内聚(内建路由、状态管理) 解耦(核心只管视图,其他靠社区)
模板语言 模板 + JS JSX(JS + XML)

Vue 更强调易用性和渐进增强,适合快速开发;React 更强调灵活性和函数式编程,更适合复杂业务需求。

阅读全文 »

1、JS的异步

js是单线程的语言,它运行在浏览器的渲染主线程中,而渲染主线程只有一个。

渲染主线程承担着诸多工作,例如解析、渲染页面、执行js都在其中,如果使用同步会极有可能产生阻塞,从而导致消息队列中许多其他任务无法得到执行,造成1主线程白白的消耗时间 2页面无法及时更新,产生页面卡死现象

所以浏览器采用异步的方式来解决,具体做法是(事件循环)当某些任务发生时,例如计时器、网络、事件监听,主线程将其交给其他线程处理,自身继续执行后续代码,当其他线程结束后,将事先传递的回调函数包装成任务加入到消息队列末尾,等待主线程的调度执行

在这种异步模式下,浏览器永不阻塞,最大限度的保证了单线程的流畅运行。

阅读全文 »

本文将全面对比 Vue 2 和 Vue 3,从语法、性能、架构、开发体验等多个维度,带你了解两者之间的核心区别。

性能提升

  1. 模板编译器优化

    • Vue 2:模板编译结果中包含了较多的运行时代码,运行时成本较高。
    • Vue 3:通过静态提升(Static Hoisting)和静态节点标记(Patch Flag)优化了虚拟 DOM 的 patch 过程,减少了运行时的开销。
  2. diff算法优化

    • Vue 2:在比较新旧虚拟DOM树时,采用的是深度优先遍历,逐层比较节点,这种方式在处理大量节点时可能会有性能问题。
    • Vue 3:进行了优化,它会根据节点的类型和属性进行更高效的比较,减少不必要的更新。
      • 静态提升:Vue 3会将静态节点提升到编译阶段,避免在每次渲染时重新创建这些节点。
      • 缓存优化:Vue 3会缓存一些计算结果,避免重复计算。
      • 块级优化:Vue 3会将模板分成多个块,每个块只包含动态内容,静态内容会被提升到块外部。这使得块内的比较更加高效。
  3. Tree-shaking 支持

    • Vue 2:整体打包,无法按需引入。
    • Vue 3:基于 ES Module 架构,支持 Tree-shaking,减小打包体积。
  4. 更小更快

    • Vue 3 的体积比 Vue 2 更小,且在大多数性能测试中表现更好。
阅读全文 »

前言

使用el-table做跨行跨列表格渲染,接口数据格式为对象数组,即需从对象中提取columns,且需要设置对应的跨行跨列关系。为此要实现一种更优雅的构造方法,即配置化跨行跨列动态渲染
基于element-ui v2.4.11版本,实现对于该版本表格组件,跨行跨列的构造方法可以通过arraySpanMethod构造,由于笔者使用的是vue2写法,vue3雷同使用。

传送门:https://element.eleme.cn/2.4/#/zh-CN/component/table

1
2
3
4
5
6
7
8
9
10
11
12
methods: {
arraySpanMethod({ row, column, rowIndex, columnIndex }) {
if (rowIndex % 2 === 0) {
if (columnIndex === 0) {

return [1, 2];
} else if (columnIndex === 1) {
return [0, 0];
}
}
}
}
阅读全文 »
0%