1.如何⽤ webpack 来优化前端性能?

2.如何提⾼ webpack 的打包速度?

3.如何提⾼ webpack 的构建速度?

同上

4.webpack 的构建流程

5. babel 是什么,怎么做到的?

babel是一个广泛使用的js编译器,将当前或旧版本的js代码转换为向后兼容的js代码,以便在当前或旧版本的浏览器中运行。这是因为它具备以下的特点:

6. webpack 热更新的机制原理?

7. 是否有写过 webpack 插件?

没有,但是了解过。

class MyWebpackPlugin{
	constructor(options){
		this.options = options;
	}
	apply(compiler){
		compiler.hooks.emit.tap("MyWebpackPlugin", compilation => {
			console.log("Webpack is emitting files...");
		})
	}
}

// ------

const MyWebpackPlugin = require("./MyWebpackPlugin")

module.exports = {
	plugins: [
		new MyWebpackPlugin({
			
		})
	]
}

8. 谈下 webpack loader 机制?

webpack loader机制是webpack提供的一种机制,用于处理项目中各种js模块、css、图片、字体等。通过loader机制,webpack可以将不同类型的文件转换为模块,并且可以在转换过程应用各种转换操作,例如编译、压缩、转译等;
特点:

  1. 安装loader模块,需要通过npm、yarn安装所需的loader模块,例如babel-loader用于处理js文件、css-loader用于处理css文件
  2. 配置loader,在webpack的配置文件中,通过module.rules配置项配置需要使用loader,可以指定loader的名称、处理的文件类型、loader的配置选项等
  3. 链式调用,如果需要对文件进行多步转换,可以通过数组的方式指定多个loader,并且可以通过!符号指定loader的执行顺序

9.uglify 原理?

uglify是一个js代码压缩工具,它的主要原理是通过删除代码中的空白符,注释、简化变量名等方式,从而减小代码体积,提高加载速度。Uglify的原理可以简单概括为词法分析、语法分析和代码压缩三个步骤。

10. babel 原理?

babel是一个广泛使用的js编译器,它主要用于将es2015+的代码转换为向后兼容的js版本,以便在现有环境中运行。babel的主要原理包括词法分析、语法分析、转换和生成代码4个步骤

11. webpack 插件机制?

webpack的插件机制可以监听webpack构建生命周期中的各个钩子,并且可以访问webpack的编译实例以及整个构建过程中的各种资源,从而实现对构建过程的干预和定制化处理。

12. 白屏怎么优化?

白屏问题通常是指页面加载时间长,用户看到的是空白的页面,而非期望的内容。以下是一些优化白屏问题的方法:

13.动画性能?

14. 渲染合成层?

浏览器为了提升动画的性能,为了在动画的每一帧的过程中不必要每次都重新绘制整个页面。在特定方式下可以触发一个合成层,合成层拥有单独的graphicslayer。
需要进行动画的元素包含在这个合成层下,这样动画的每一帧只需要去重新绘制这个graphicslayer即可,从而达到提升动画性能的目的。
如果我们想尽可能的优化我们的css动画,或者在日常css开发中,尽可能的提升css的性能,这是一个非常重要的概念。通过生成独立的graphicslayer,让此层内的重绘重排不引起整个页面的重绘重排。
这也就是我们常说的,css 3d硬件加速的本质原因。
那么元素什么时候会触发一个graphics layer层?

15.tree shaking 是什么,有什么作用,原理是什么?

tress shaking是一种js模块优化技术。

作用是在打包过程中去除未被引用的代码,以减少最终生成的包体积,优化资源利用

原理是基于es6模块的静态结构分析,识别未被引用的代码。

16. 前端微服务?

是指前端应用拆分为多个小型、独立的服务单元,每个单元负责特定的功能或页面。

优点是:

17. CDN 的概念

CDN,内容分发网络,content delivery network,是一种通过互联网互相连接的电脑网络系统,利用最靠近每位用户的服务器,更快、更可靠地将音乐、图片、视频、应用程序及其他文件发送给用户,来提高性能、可扩展性以及低成本的网络内容传递用户。

18.CDN 的作用

19. CDN 的原理

用户请求资源,经过CDN的DNS服务器将全局负载均衡设备IP地址返回给用户,用户向缓存IP发起请求,缓存服务器逐级请求上一级缓存服务器,如果最后缓存服务器没有,就会去自己的服务器去获取资源。

20、CDN 的使用场景

21. 懒加载的概念

懒加载也叫做延迟加载、按需加载,指的是在长网页中延迟加载图片数据,是一种较好的网页性能优化的方式。在比较长的网页或应用中,如果图片很多,所有的图片都被加载出来,而用户智能看到可是窗口的那一部分,这样就浪费了性能。如果在滚动屏幕之前,可视化区域之外的图片不会进行加载,在滚动屏幕时才加载。这样网页的加载速度更快,减少了服务器的负担。

22.懒加载的特点

23. 懒加载的实现原理

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Lazy Load Images</title>
<style>
  .placeholder {
    height: 300px; /* 设置一个占位符的高度,以保持页面布局不变 */
  }
</style>
</head>
<body>

<div class="placeholder"></div>
<img data-src="https://via.placeholder.com/300" alt="Lazy Loaded Image" class="lazy-load">
<div class="placeholder"></div>

<script>
  // 获取所有带有 'lazy-load' 类的图片元素
  const lazyImages = document.querySelectorAll('.lazy-load');

  function lazyLoad() {
    // 循环遍历每个图片元素
    lazyImages.forEach(img => {
      // 判断图片是否在视口中可见
      if (img.getBoundingClientRect().top < window.innerHeight) {
        // 将 data-src 属性的值赋给 src 属性,实现图片加载
        img.src = img.dataset.src;
        // 移除 'lazy-load' 类,避免重复加载
        img.classList.remove('lazy-load');
      }
    });
  }

  // 页面加载完毕后立即执行一次
  lazyLoad();

  // 监听页面滚动事件,在滚动时执行 lazyLoad 函数
  window.addEventListener('scroll', lazyLoad);
</script>

</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Lazy Load Images with Intersection Observer</title>
<style>
  .placeholder {
    height: 300px; /* 设置一个占位符的高度,以保持页面布局不变 */
  }
</style>
</head>
<body>

<div class="placeholder"></div>
<img data-src="https://via.placeholder.com/300" alt="Lazy Loaded Image" class="lazy-load">
<div class="placeholder"></div>

<script>
  // 获取所有带有 'lazy-load' 类的图片元素
  const lazyImages = document.querySelectorAll('.lazy-load');

  // 创建 Intersection Observer 实例
  const observer = new IntersectionObserver((entries, observer) => {
    // 遍历观察到的每个 entry
    entries.forEach(entry => {
      // 如果 entry 是可见的
      if (entry.isIntersecting) {
        const img = entry.target;
        // 将 data-src 属性的值赋给 src 属性,实现图片加载
        img.src = img.dataset.src;
        // 移除 'lazy-load' 类,避免重复加载
        img.classList.remove('lazy-load');
        // 停止观察该图片
        observer.unobserve(img);
      }
    });
  });

  // 遍历每个图片元素,开始观察
  lazyImages.forEach(img => {
    observer.observe(img);
  });
</script>

</body>
</html>

24. 懒加载与预加载的区别

一个是提前加载,一个是迟缓甚至不加载。懒加载对服务器前端有一定的缓解压力作用,预加载则会增加服务器前端压力

25. 回流与重绘的概念及触发条件

26. 如何避免回流与重绘?

27.documentFragment 是什么?用它跟直接操作 DOM 的区别是什么?

documentFragment是一个没有父对象的最小文档对象。

和直接操作DOM对比,它的对象不会触发DOM树的重新渲染,不会导致性能问题。

28.对节流与防抖的理解

函数防抖:事件被触发n秒后再执行回调,如果在这n秒事件又被触发,则重新计时。这可以使用点击事件上,避免用户的多次请求。
函数节流:在规定的单位时间内,只能有一次触发时间、节流可以使用scroll函数事件监听上,通过事件节流来降低事件调用的频率。

29.实现节流函数和防抖函数

实现js在点击事件中的防抖

function debounce(func, delay){
	let timer;
	return function(){
		const context = this;
		const args = arguments;
		clearTimeout(timer);
		timer = setTimeout(()=>{
			func.apply(context, args);
		}, delay)
	}
}
function handleClick(){
	console.log("button clicked!");
}

const button = document.getElementById("myButton");
button.addEventListener("click", debouce(handleClick, 1000));

function debounce(func, delay){
	let timer;
	return function(){
		const context = this;
		const args = arguments;
		clearTimeout(timer);
		timer = setTimeout(()=>{
			func.apply(context, args)
		}, delay)
	}
}

function handleClick(){
	console.log("button clicked");
}

const button = document.getElementById("myButton");
button.addEventListener("click", debounce(handleClick, 1000))

function debounce(func, delay){
	let timer;
	return function(){
		const context = this;
		const args = arguments;
		clearTimeout(timer);
		timer = setTimeout(()=>{
			func.apply(context, args)
		}, delay)
	}
}
function handleClick(){
	console.log("button, click!");
}

const button = document.getElementById("myButton")

button.addEventListener("click", debounce(handleClick, 1000))
function throttle(func, delay){
	let lastExecTime = 0;
	return function(){
		const context = this;
		const args = arguments;
		const currentTime = Date.now();
		if(currentTime - lastExecTime >= delay){
			func.apply(context, args);
			lastExecTime = currentTime;
		}
	}
}

function handleScroll(){
	console.log("scrolling...")
}

window.addEventListener("scroll", throttle(handleScroll, 1000));

function throttle(func, delay){
	let lastExecTime = 0;
	return function(){
		const context = this;
		const args = arguments;
		const currentTime = Date.now();
		if(currentTime - lastExecTime >= delay){
			func.apply(context, args);
			lastExecTime = currentTime;
		}
	}
}
function handleScroll(){
	console.log("scrolling...")
}

window.addEventListener("scroll", throttle(handleScroll, 1000))

function throttle(func, delay){
	let lastExecTime = 0;
	return function(){
		const context = this;
		const args = arguments;
		const currentTime = Date.now();
		if(currentTime - lastExecTime >= delay){
			func.apply(context, args);
			lastExecTime = currentTime;
		}
	}
}
function handleScroll(){
	//...
}

window.addEventListener("scroll", throttle(handleScroll, 1000))

30.如何对项目中的图片进行优化?

  1. 用css替代图片
  2. 对于移动端可以根据屏幕宽度,优化对应的原图输出
  3. 小图使用base64
  4. 多个图标整合到一张图中
  5. 选择正确的图片格式
  6. 支持webp格式的浏览器尽量使用webp

31.常见的图片格式及使用场景

32.如何提⾼ webpack 的打包速度?

33.如何减少 Webpack 打包体积

34.浏览器渲染优化

35.Webpack vs Rollup 的区同点

36.如何理解前端工程化

前端工程化是通过工程化的方法和根据来提高前端开发效率,降低维护成本,提升项目质量的一种开发模式。前端工程化包括了项目构建、模块化开发、自动化测试、持续集成、部署流程等一系列技术和实践的整合,旨在优化前端开发过程和项目管理。

37.如何理解 Monorepo

monorepo是单个版本库repository中管理多个项目或组件的代码。通常,每个项目或组件都有自己的目录结构,但他们共享相同的版本控制和构建流程。monorepo提供了一种集中式的代码管理方式,可以用于管理大型项目或跨项目共享代码的情况。

38.除了 Webpack,你还了解哪些构件工具

39.SPA 首屏为什么加载慢

40.前端展示大批量图片如何优化

41.如何理解 RAIL 性能指标模型

RAIL:response/animation/idle/load

42.Vue的性能优化有哪些

43.详解 Vue 性能优化

同上

44.vite为什么比webpack快