合集:2023年最全前端面试题考点HTML5+CSS3+JS+Vue3+React18+八股文+手写+项目+笔试_参宿7的博客-CSDN博客

*表示回顾基础知识

项目为二面三面,面试官基本就是照着简历里面的项目技术点切入然后深入展开。

为了简洁,相关文章参考链接在标题里

目录

模块化规范

懒加载(性能优化)

scroll版

IntersectionObserver 版

require与import的区别和使用

js的运行环境

浏览器

Node

特点

js包管理器

npm

yarn(实际开发)

优势

用法区别

项目规范

命令(创建运行)

项目文件结构

package.json

package-lock.json

node_modules

git代码管理

常用命令

分支

git多人协同merge冲突

暂时保存更改

性能优化

webpack打包管理

原理

Babel

loader

plugin

loader和plugin的区别

热加载原理

TS4 加分项

区别

为什么推荐使用TypeScript?

TypeScript和JavaScript的区别

控制类成员可见性的访问关键字有哪些?

接口interface与类型别名type

类型

never,any,unknown

类型断言as与非空断言!

函数类型和void

泛型

应用

变量

*类型注解

数组

函数

类型判断

is

Narrowing down sets

样式

Ant Design

Css、less、Sass (SCSS)

Sass

嵌套

选择器嵌套

属性嵌套

伪类嵌套

变量

全局变量

局部变量

默认值

混入指令/混合指令/宏指令@mixin

不带参数混合宏

带参数混合宏

带特别多参数混合宏

调用混合宏@include

继承@extend

占位符 %placeholder

混合宏VS继承VS占位符

基础语法

插值#{}

注释

加减法

乘法

除法

@if, @else if ,@else条件

@for

@while循环

@each循环

@import引入 SCSS 和 Sass

瀑布流

css

js

共性

问项目中有哪些难点,怎么解决的

代码遇到冲突怎么办

业务系统的搭建过程

复盘过程

拆分组件

如何实现自适应页面

*个性

介绍

实现功能

后端接口

登陆注册

*0.0.0.0,localhost,127.0.0.1

0.0.0.0

localhost

127.0.0.1

分页

弹窗组件modal

如何实现点击弹窗外面区域,弹窗消失

相关技术

模块化规范

一个模块是实现一个特定功能一组方法

  1. 由于函数具有独立作用域的特点,最原始的写法是使用函数来作为模块,几个函数作为一个模块,但是这种方式容易造成全局变量的污染,并且模块间没有联系
  2. 后面提出了对象,通过将函数作为一个对象的方法来实现,但是这种办法会暴露所 有的所有的模块成员,外部代码可以修改内部属性的值
  3. 现在最常用的是立即执行函数的写法,通过利用闭包来实现模块私有作用域的建立,同时不会对全局作用域造成污染
  • ES6 :使用 import 和 export 的形式来导入导出模块。
  • CommonJS : require 来引入模块,通过 module.exports 定义模块的输出接口。

这种模块加载方案是服务器端的解决方案,它是以同步的方式来引入模块的,因为在服务端文件都存储在本地磁盘,所以读取非常快,所以以同步的方式加载没有问题。

但如果是在浏览器端,由于模块的加载是使用网络请求,因此使用异步加载的方式更加合适。

  • AMD :Asynchronous Module Definition,这种方案采用异步加载的方式来加载模块,模块的加载不影响后面语句的执行,所有依赖这个模块的语句都定义在一个回调函数里,等到加载完成后再执行回调函数require.js 实现了 AMD 规范。
  • CMD :Common Module Definition,这种方案和 AMD 方案都是为了解决异步模块加载的问题,sea.js 实现了 CMD 规范。

AMD是预加载,CMD是懒加载。

AMD是提前执行,CMD是延迟执行。

AMD在对应的加载之前导入,CMD在用的时候导入

懒加载(性能优化)

(Load On Demand)延迟加载、按需加载

可视化区域之外的图片不会进行加载,在滚动屏幕时才加载。这样使得网页的加载速度更快,减少了服务器的负载。懒加载适用于图片较多,页面列表较长(长列表)的场景中。

scroll版

  1. 图片的 src 属性设为默认图片
  2. 图片的真实路径则设置在data-src属性中,
  3. 绑定 window 的 scroll 事件,对其进行事件监听。
  4. //节流
    window.addEventListener('scroll', throttle(lazyload, 200))
  5. 在scroll事件的回调中,判断我们的懒加载的图片是否进入可视区域,
  6. 如果图片在可视区内将图片的 src 属性设置为data-src的值
<html lang="en">
<head><meta charset="UTF-8"><title>Lazyload</title><style>.image-item {display: block;margin-bottom: 50px;height: 200px;//一定记得设置图片高度}</style>
</head>
<body><img src="./img/default.png" data-src="./img/1.jpg" />...<img src="./img/default.png" data-src="./img/10.jpg" /><script>
function lazyload() {let viewHeight = document.body.clientHeight //获取可视区高度
//用属性选择器返回属性名为data-src的img元素列表let imgs = document.querySelectorAll('img[data-src]')imgs.forEach((item, index) => {if (item.dataset.src === '') return// 用于获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置let rect = item.getBoundingClientRect()if (rect.bottom >= 0 && rect.top < viewHeight) {item.src = item.dataset.srcitem.removeAttribute('data-src')//移除属性,下次不再遍历}})
}lazyload()//刚开始还没滚动屏幕时,要先触发一次函数,初始化首页的页面图片
document.addEventListener("scroll",lazyload)
</script>
</body>
</html>

IntersectionObserver 版

IntersectionObserver "交叉观察器"。可见(visible)本质是,目标元素与视口产生一个交叉区

callback 一般会触发两次。一次是目标元素刚刚进入视口(开始可见),另一次是完全离开视口(开始不可见)

//callback 是可见性变化时的回调函数,option 是配置对象(该参数可选)
var io = new IntersectionObserver(callback, option)// 开始观察
io.observe(document.getElementById('example'))// 停止观察
io.unobserve(element)// 关闭观察器
io.disconnect()

callback 函数的参数(entries)是一个数组,每个成员都是一个 IntersectionObserverEntry 对象。举例来说,如果同时有两个被观察的对象的可见性发生变化,entries 数组就会有两个成员。

  • time:可见性发生变化的时间,是一个高精度时间戳,单位为毫秒
  • target:被观察的目标元素,是一个 DOM 节点对象
  • isIntersecting: 目标是否可见
  • rootBounds:根元素的矩形区域的信息,getBoundingClientRect()方法的返回值,如果没有根元素(即直接相对于视口滚动),则返回 null
  • boundingClientRect:目标元素的矩形区域的信息
  • intersectionRect:目标元素与视口(或根元素)的交叉区域的信息
  • intersectionRatio:目标元素的可见比例,即 intersectionRectboundingClientRect 的比例,完全可见时为 1,完全不可见时小于等于 0
const config = {rootMargin: '0px',threshold: 0,
}
let observer = new IntersectionObserver((entries, self) => {entries.forEach((entry) => {if (entry.isIntersecting) {let img = entry.targetlet src = img.dataset.srcif (src) {img.src = srcimg.removeAttribute('data-src')}// 解除观察self.unobserve(entry.target)}})
}, config)imgs.forEach((image) => {observer.observe(image)
})

require与import的区别和使用

require/import// CommonJS 的写法
const moduleA = require('moduleA');
const func1 = moduleA.func1;
const func2 = moduleA.func2;
// ES6 的写法
import { func1, func2 } from 'moduleA';module.exports/export// commonJS 的写法
var React = require('react');
var Breadcrumbs = React.createClass({render() {return <nav />;}
});
module.exports = Breadcrumbs;// ES6 的写法
import React from 'react';
class Breadcrumbs extends React.Component {render() {return <nav />;}
};
export default Breadcrumbs;
  1. 规范:require是CommonJS,AMD规范的模块化语法,import是ECMAScript 6规范的模块化语法,如果要兼容浏览器的话必须转化成es5的语法;CommonJS模块默认export的是一个对象,即使导出的是基础数据类型
  2. 本质:require是赋值过程,其实require 的结果就是对象、数字、字符串、函数等,再把require的结果赋值给某个变量,引入复杂数据类型时,数据浅拷贝该对象。。import是解构过程。
  3. 加载:require是运行时加载,import是编译时加载;
  4. 位置:require可以写在代码的任意位置,import只能写在文件的最顶端且不可在条件语句或函数作用域中使用;
  5. 改变:require通过module.exports导出的不能再变,import通过export导出的值可以改变;

js的运行环境

脚本语言需要一个解析器才能运行,每一种解析器都是一个运行环境

JavaScript是脚本语言,在不同的位置有不一样的解析器,

浏览器

写入html的js语言,浏览器是它的解析器角色。

浏览器中的js的用途是操作DOM,浏览器就提供了document之类的内置对象。

Node

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,独立于浏览器的运行环境

nodejs中的js的用途是操作磁盘文件或搭建http服务器,nodejs就相应提供了fs,http等内置对象。

特点

  • 简单:javascript,json进行编码,
  • 强大:非阻塞IO,可以适应分块传输数据,较慢的网络环境,尤其擅长高并发访问
  • 轻量:node本身既是代码,又是服务器前后端使用统一语言;
  • 可扩展体:轻松应对多实例多服务器架构,同时有海量的第三方应用组件

js包管理器

npm

Node Package Manager ,即:node包管理器,Node.js社区开发

是nodeJS的一个程序包管理和分发的管理工具,npm完全用 JavaScript 写成

允许用户从NPM服务器下载安装上传

yarn(实际开发)

yarn由Facebook为解决npm的一些问题而创建的

优势

快速

  • 本地缓存+并行下载 - Yarn并行下载,还可以直接从硬盘缓存中读取包,因此可以显著提高速度。
  • 网络连接问题处理 - 当Yarn发现任何网络连接问题时,它会自动重试请求,保存响应并继续构建 - 这使得它更容易处理比npm更可靠且快速的环境。

稳定

  • 确定性安装 - Yarn能够在包含区别式锁文件(yarn.lock)的情况下进行精确的依赖项安装,每次运行生成相同的代码版本,与开发者上次运行相同。npm也有类似的功能,但是许多开发人员选择使用Yarn锁定其依赖关系以消除任何可能的不确定性。
  • 强制命令 - 通过添加--force标志,Yarn可以强制执行某些操作。这可能看起来像是一种强制手段,但它实际上是保证操作按期望进行的一种方法。npm也有许多命令选项,但是Yarn的操作强迫执行机制通常要好得多。

用法区别

  • 安装包

    • Yarn: yarn add
    • npm: npm install
  • 移除包
    • Yarn: yarn remove
    • npm: npm uninstall
  • 更新
    • Yarn: yarn upgrade
    • npm: npm update

项目规范

整个项目不再使用class组件,统一使用函数式组件,并且全面用Hooks;

所有的函数式组件,为了避免不必要的渲染,全部使用memo进行包裹;

组件内部的状态,使用useState、业务数据全部放在redux中管理;

函数组件内部逻辑代码基本按照如下顺序编写代码:

组件内部state管理;redux的hooks代码;其他hooks相关代码(比如自定义hooks);其他逻辑代码;返回JSX代码;

redux代码规范如下:

redux目前我们学习了两种模式, 根据自己的情况选择普通模式还是rtk模式每个模块有自己独立的reducer或者slice,之后合并在一起;redux中会存在共享的状态、从服务器获取到的数据状态;

网络请求采用axios

对axios进行二次封装;所有的模块请求会放到一个请求文件中单独管理;项目使用AntDesign或者MUI(Material UI)其他规范在项目中根据实际情况决定和编写

命令(创建运行)

npm run start 来运行启动项目并打开页面
npx create-react-app my-app //创建项目
cd my-app
npm start

安装命令:

npx create-react-app 项目名称 --template typescript

项目文件结构

主要开发代码在src目录下。App.js为组件,index.js为入口模块,index.css为全局样式文件。

package.json

配置jsconfig.json:这个文件在Vue通过脚手架创建项目时自动生成, React是没有自动生成

package.json相当于说明书,其重点字段:

{"name": "react-ts-app","version": "0.1.0","private": true,//是否私有,设置为 true 时,npm 拒绝发布"dependencies": {//生产环境下,项目运行所需依赖"@ant-design/icons": "^4.8.0",..."@types/node": "^16.18.6","@types/react": "^18.0.26","@types/react-dom": "^18.0.9","antd": "^5.0.4","axios": "^1.2.1","classnames": "^2.3.2","lodash": "^4.17.21","react": "^18.2.0","react-dom": "^18.2.0","react-redux": "^8.0.5","react-router-dom": "^6.4.4","react-scripts": "5.0.1","redux": "^4.2.0","redux-persist": "^6.0.0","sass": "^1.56.1","typescript": "^4.9.3","web-vitals": "^2.1.4"},"scripts": {//执行npm脚本命令简写,比如“start" : "react-scripts start",执行npm start就是运行“react-scripts start""start": "SET PORT=8080 && react-scripts start","build": "react-scripts build","test": "react-scripts test","eject": "react-scripts eject"},
...."devDependencies": {//开发环境下,项目所需依赖"@types/lodash": "^4.14.191"}
}

package-lock.json

用一句话来概括很简单,就是锁定安装时的包的版本号,并且需要上传到git,以保证其他人在npm install时大家的依赖能保证一致。

node_modules

是安装node后用来存放用包管理工具下载安装的的文件夹。比如webpack、gulp、grunt这些工具。

git代码管理

常用命令

git init 初始化git仓库

git status 查看文件状态

git add 文件列表 追踪文件

git commit -m 提交信息 向仓库中提交代码

git log 查看提交记录

分支

1.分支明细

(1)主分支(master):第一次向 git 仓库中提交更新记录时自动产生的一个分支。

(2)开发分支(develop):作为开发的分支,基于 master 分支创建。

(3)功能分支(feature):作为开发具体功能的分支,基于开发分支创建

2.分支命令

(1)git branch 查看分支

(2)git branch 分支名称 创建分支

(3)git checkout 分支名称 切换分支

(4)git merge 来源分支 合并分支 (备注:必须在master分支上才能合并develop分支)

(5)git branch -d 分支名称 删除分支(分支被合并后才允许删除)(-D 强制删除)

git多人协同merge冲突

是当前修改是左箭头方向,传入的是右箭头的方向,

中间用等于号分割,等号上边是当前修改(本地),下边是传入的修改(线上的代码)。

两人同时提交可能会出现冲突,解决办法是手动修改冲突

暂时保存更改

存储临时改动:git stash(藏匿)

恢复改动:git stash pop

  • 应用场景:

对于多人并行开发,维护同一仓库工作场景,经常会出现文件合并冲突的情况

  • 作用:

能够将所有未提交的修改(工作区和暂存区)保存至堆栈中,用于后续恢复当前工作目录。

git add

只是把文件加到 git 版本控制

性能优化

压缩js,css,js分包,优化图片(webp),开启gzip(后端开启),配置缓存(强制缓存协商缓存),使用cdn,
webpack分包,减少重绘回流

webpack打包管理

它将根据模块的依赖关系进行静态分析,然后将这些模块( js、css、less )按照指定的规则生成对应的静态资源减少了页面的请求。Webpack是以公共JS的形式来书写脚本的,方便旧项目进行代码迁移

原理

Webpack通过一个给定的主文件(如:index.js)开始找到项目的所有依赖文件,

使用loaders处理它们,plugin可以压缩代码和图片

把所有依赖打包成一个 或多个bundle.js文件(捆bundle)浏览器可识别的JavaScript文件。

Babel

JavaScript 编译器

将es6、es7、es8等语法转换成浏览器可识别的es5或es3语法,即浏览器兼容的语法,比如将箭头函数转换为普通函数

将jsx转换成浏览器认的js

loader

webpack只认识JS和JSON,所以Loader相当于翻译官,将其他类型资源进行预处理,最终变为js代码。

  • less-loader:将less文件编译成css文件(开发中,会使用less预处理器编写css样式,使开发效率提高)
  • css-loader:将css文件变成commonjs模块(模块化的规范)加载到js中,模块内容是样式字符串
  • style-loader:创建style标签,将js中的样式资源插入标签内,并将标签添加到head中生效
  • ts-loader:打包编译Typescript文件

plugin

Plugin解决loader 无法实现的事情,比如打包优化代码压缩等。

  • html-webpack-plugin 处理html资源,默认会创建一个的HTML,自动引入打包输出的所有资源(js/css)
  • mini-css-extract-plugin 打包过后的css在js文件里,该插件可以把css单独抽出来
  • clean-webpack-plugin 每次打包时候,CleanWebpackPlugin 插件就会自动把上一次打的包删除

loader和plugin的区别

运行时机
1.loader运行在编译阶段
2.plugins 在整个周期都起作用

热加载原理

浏览器热更新:开发时能够在浏览器页面实时看到我们代码的变化产生效果的流程。

热加载是通过内置的 HotModuleReplacementPlugin 实现的

  1. 构建 bundle 的时候,监听文件变化。
  2. 文件修改会触发 webpack 重新构建
  3. 服务器通过向浏览器发送更新消息
  4. 浏览器通过 jsonp 拉取更新的模块文件,
  5. jsonp 回调触发模块热替换逻辑

TS4 加分项

一般面试官不会考察,但是你可以写在简历项目或者技能中,面试时主动提出使用了ts,解释下为什么要使用ts及ts与js,java(类成员可见性,多的类型(any,void,泛型,断言等))的区别,然后引导面试官提问,回答完其问题再自己拓展一些相关,是不错的加分项。

但既然是加分项,一般不会问太深,毕竟还有更关键的要问你,所以会试探一下你是否真的用过,还是纯背。

面试官一般是看你简历问的,没有问的才会问八股文之类。

面试一定要把握主动权,不要干等着面试官问,尽量展示自己所会的,并且回答不必太急,最后能条理清晰。

区别

为什么推荐使用TypeScript?

  • JS的超集,扩展新功能
  • 强制类型,防止报错
  • 自动类型推断,保证变量的类型稳定
// let a: string  ->  类型推断
let a = 'hello'
a = 123;   // error
  • 强大的类型系统,包括泛型
  • 支持静态类型。(主要改进)更有利于构建大型应用

TypeScript和JavaScript的区别

  • TypeScript是JavaScript  的超集,可以被编译成JS。用JS编写的代码,在TS中依然有效。
  • TypeScript通过TypeScript编译器Babel转译为JavaScript代码
  • TypeScript 是纯面向对象的编程语言,包含类和接口的概念。
  • JavaScript弱类型语言,动态类型

类型强弱是针对类型转换是否显示来区分,静态和动态类型是针对类型检查的时机来区分。

  • 在JS中只有变量声明空间,比如let a = 123。但在TS中还存在类型声明空间,可通过类型注解结合这两个空间

可以通过type关键字来定义类型声明空间,type在TS中叫做类型别名。为了能够更好的区分两个空间,所以人为规定类型空间定义的名字首字母要大写,例如:type A = number

控制类成员可见性的访问关键字有哪些?

  • 公共(public),类的所有成员,其子类以及该类的实例都可以访问。
  • 受保护(protected),该类及其子类都可以访问它们。 但是该类的实例无法访问。
  • 私有(private),只有类的成员可以访问它们。

TS与java不同,TS默认隐式公共的,TS符合 JS 的便利性,java默认private,符合安全性

接口interface与类型别名type

接口是一系列抽象方法的声明,是一些方法特征的集合。

接口类型别名类似都是用来定义类型注解的,但接口只能操作对象,且有继承,合并

interface A {username: string;age: number;
}
let a: A = {username: 'xiaoming',age: 20
}

接口可以进行合并操作。

interface A {username: string;
}
interface A {age: number;
}
let a: A = {username: 'xiaoming',age: 20
}

接口具备继承能力。

interface A {username: string
}
interface B extends A {age: number
}
let b: B = {username: 'xiaoming',age: 20
}

类型

never,any,unknown

never类型表示永不存在的值的类型,当一个值不存在的时候就会被自动类型推断成never类型。

出问题的时候会被自动转成never。

any类型表示任意类型,而unknown类型表示为未知类型,是any类型对应的安全类型。

类型断言as与非空断言!

当 TypeScript 推断出来类型并不满足需求,需要手动指定一个类型,强制说明类型,让TS编译不报错

let a: unknown = 'hello';
a = 123;
(a as []).map(()=>{})    // success

因为b可能是字符串也可能是undefined,所以b.length的时候就会报错,这样我们可以采用非空断言来告诉TS,这个b肯定不是undefined,所以b只能是字符串,那么b.length就不会报错了。

let b: string|undefined = undefined;
b!.length   // success

函数类型和void

function foo(n: number, m?: string): number{return 123;
}
foo(123, 'hello');
foo(123);     // success

当函数没有returnreturn undefined的时候返回void类型。

let foo = function(){   // void
}let foo = function(): undefined{   // undefined 不能不写return的
}  // error

泛型

泛型是指在定义函数、接口、类时,未指定其参数类型,只有在运行时传入才能确定。泛型简单来说就是对类型进行传参处理。

应用

变量

*类型注解

类型注解:把变量空间与类型空间结合在一起

type关键字+类型别名

let a: string = 'hello'//也可以通过类型别名进行连接
type A = string
let a: A = 'hello'

数组

let arr: Array<number> = [1, 2, 3];
//自定义MyArray实现
type MyArray<T> = T[];
let arr2: MyArray<number> = [1, 2, 3];

函数

function foo(n: number, m?: string): number{return 123;
}
foo(123, 'hello');
foo(123);     // successfunction foo<T>(n: T){
}
foo<string>('hello');
foo(123);   // 泛型会自动类型推断

class Foo {//第一种写法//username: string = 'xiaoming';//第二种写法// username: string;// constructor(){//   this.username = 'xiaoming';// }//第三种写法username: string;constructor(username: string){this.username = username;}
}interface A {username: stringage: numbershowName(n: string): string
}class Foo implements A {username: string = 'xiaoming'age: number = 20gender: string = 'male'  showName = (n: string): string => {return n}
}class Foo {...showAge = (n: number): number => {return n;}
}class Foo<T> {username!: T;  //不给初始值可通过非空断言
}
let f = new Foo<string>();
f.username = 'hello';class Foo<T> {username!: T
}
class Baz extends Foo<string> {}
let f = new Baz()
f.username = 'hello'

类型判断

is

is 让 ts 分辨类型

function toUpperCase(x: unknown) {if(isString(x)) {x.toUpperCase(); // ⚡️ x is still of type unknown}
}
  • 但是由于这个检验函数(isString)被包裹在 toUpperCase()函数中,ts 在判断的时候还是抛出了错误提示

  • 使用 is ,这里让我们主动明确的告诉 ts ,在 isString() 这个函数的参数是一个 string。

// !!! 使用 is 来确认参数 s 是一个 string 类型
function isString(s): s is string {return typeof s === 'string';
}

Narrowing down sets

function pipsAreValid(pips: number) {// we check for every discrete value, as number can // be something between 1 and 2 as well.return pips === 1 || pips === 2 || pips === 3 ||pips === 4 || pips === 5 || pips === 6;
}function evalThrow(count: number) {if (pipsAreValid(count)) {// my types are lying 												

2023年高频前端面试项目考点(npm,git,webpack,TS4,sass,瀑布流,懒加载)相关推荐

  1. web前端高级React - React从入门到进阶之组件的懒加载及上下文Context

    第二部分:React进阶 系列文章目录 第一章:React从入门到进阶之初识React 第一章:React从入门到进阶之JSX简介 第三章:React从入门到进阶之元素渲染 第四章:React从入门到 ...

  2. 前端性能优化的重要方案:图片懒加载

    大家好,我是前端岚枫,一枚二线城市的程序媛,今天主要跟大家分享我整理的前端性能优化的重要方案:图片懒加载,主要包括其原理,我们常用的一些插件,及编写源码实现图片懒加载功能等,图片懒加载是项目比较常见的 ...

  3. dll文件懒加载_前端性能优化

    # 前端性能优化 写在最前面:下面都是我对webpack的一些性能优化,想系统的学习性能优化方面的知识 推荐大家看看这本书 很系统 感觉面试也能如鱼得水 ## 构建优化 ### webpack优化 ( ...

  4. 前端性能优化不完全手册 【已更新至React、原生JS懒加载和Nginx负载均衡】

    性能优化是一门大学问,本文仅对个人一些积累知识的阐述,欢迎下面补充. 抛出一个问题,从输入url地址栏到所有内容显示到界面上做了哪些事? 1.浏览器向DNS服务器请求解析该 URL 中的域名所对应的 ...

  5. Vue 单文件组件||Vue 单文件组件的基本用法||webpack 中配置 vue 组件的加载器|| 在 webpack 项目中使用 vue

    Vue 单文件组件 传统组件的问题和解决方案 1. 问题 1. 全局定义的组件必须保证组件的名称不重复 2. 字符串模板缺乏语法高亮,在 HTML 有多行的时候,需要用到丑陋的 \ 3. 不支持 CS ...

  6. iframe懒加载_前端常见问题

    原地址:https://blog.csdn.net/Mr_JavaScript/article/details/84311068 1. flex布局:又叫做弹性布局 任何一个容器都可以指定flex布局 ...

  7. 前端学习(2742):重读vue电商网站52之路由懒加载

    当打包构建项目时,JavaScript 包会变得非常大,影响页面加载.如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了. 具体需要 3 步: 安 ...

  8. vue路由懒加载_优化vue项目的首屏加载速度

    最近使用vue-cli3构建了一个小型的博客系统,完工之后,build打包出来发现一个chunk-vendors包就有1.1m,部署上去之后,访问的时候,首屏加载非常慢.居然需要21s,体验极差. 这 ...

  9. vue 图片拖动加载 类似于地图_前端性能优化之图片懒加载(附vue自定义指令)...

    作者:lzg9527 链接:https://juejin.cn/post/6903774214780616718 在类电商类项目,往往存在大量的图片,如 banner 广告图,菜单导航图,美团等商家列 ...

最新文章

  1. 被面试官问懵B了,十亿级数据ES搜索怎么优化?
  2. 关于bash的执行过程
  3. vim 忽略大小写查找字符串
  4. sql经验 convert函数转换日期
  5. STM32 地址偏移问题及怎么运用
  6. Effective Java(一)———— 代替构造器和Setter的构建器模式
  7. 特斯拉维权车主发声:方式会变,维权不会变,绝不妥协!
  8. netsh 禁用端口
  9. Windows7不再卡五叶草,更新了bootx64.efi和bootmgfw.efi文件,支持安全启动,不用关闭安全启动和打开csm支持.
  10. 架构真经 | 缓存为王
  11. 【标书应用场景】畅写Office为电子招投标提速赋能,助力项目招投标业务数字化转型
  12. 程序员常用的25个技术网站,良心推荐!
  13. 爬取京东收件地址下得所有数据
  14. fatal: unsafe repository is owned by someone else 的解决方法
  15. 【python】(四)python常用数据结构
  16. 计算二分类的特异性和灵敏度
  17. Git 删除 GitHub仓库的文件——详细操作 githua如何删除文件
  18. 互联网日报 | 董明珠2020年直播带货476亿;滴滴橙心优选启动“小店战略”;苹果开始自研调制解调器...
  19. ngnix 配置多个前端项目(首次上传vue)
  20. USB协议基础知识点整理

热门文章

  1. stm32f4xx-GPIO
  2. Service简单介绍
  3. 道林·格雷的画像读后感
  4. 《庶女:明兰传》知否知否应是绿肥红瘦 epub格式下载
  5. untiy 脚本API之可视化辅助类Gizmos
  6. 【BZOJ4943】【UOJ315】【NOI2017】蚯蚓
  7. 解决sublime打开GBK或GB2312乱码
  8. 冲压模具材料的选用及热处理要求
  9. 宽带的调制调节器LAN1和LAN2口的区别
  10. 深度学习实战5-卷积神经网络(CNN)中文OCR识别项目