内容有点多,也请你静下来,慢阅读,今后多多关照。
说到web前端开发高级,必须要掌握的是HTML和css代码的优化,前端优化很重要,这是成功你进阶的道路上需要重视的知识点,面对代码优化,首先我们要学习的就是前端命名规范,HTML代码优化,和css代码优化。
前端命名规范是很重要的,一直说很重要,当你用过别人的代码进行重构时,你会知道,如果你看到一长串代码,不了解之前的人是怎么写的,开局全靠猜,结局就是不断地浪费时间。
掌握前端优化目录的学习
前端命名规范,前端结构的组织,文件的命名规范,在一个项目中代码的组织结构要清晰易懂,同类型文件可以归类到到相同的文件夹中,文件命名规则需要统一且命名要有意义。这里要有意义是指命名要通俗易懂,英文单词可以写缩写,不必故步自封,写那么长的单词。
命名规范在前端领域,涉及HTML,css,JavaScript,在HTML代码所有的标签名和属性应该都为小写,属性值应该用引号括起来。元素的id和class都要按照规定命名,代码缩进时要缩进,进行格式化,让代码美观,有时可以给HTML代码添加必要注解。
对于css命名的规范,尽量使用class选择器进行样式的定义,类命名时取父元素的class名作为前缀,使用-符号进行连接。类名与样式之间以空格进行分割。
对于JavaScript命名规范,变量名是区分大小写,第一个字符是不允许为数字的,不允许是空格,不允许其他标签符号,尽量使用有意义的命名,不要使用JavaScript的关键词,或者是保留字。
进行前端代码的优化,优化HTML代码为了能够使网站更好的搜索,让用户更快速搜索到我们的网站,写好HTML代码使用正确的闭合HTML标签,进行HTML代码层级间的合理缩进,属性值需要使用双引号,结构与样式进行有效的分离,结构与行为进行有效的分离。
进行HTML语义化标签,HTML5提供的一些新的语义化元素来明确一个web页面的不同部分,有:
优化前端效果,可以删除多余容器元素,让代码层次少,避免使用table进行页面的布局,换成用div+css的样式布局。
css代码优化,在各个浏览器中,相同元素解析的结果不同,就需要手动重置一些样式。
去除标签的默认样式,如p,li,input等。 HTML5新标签设置为display:block。 重置一些元素的样式如超链接,字号等样式。
css样式选择器的优先级
对于css样式选择器,优先级高的会覆盖优先级低的。
第一,id选择器的权重为100,第二,类选择器的权重为10,第三,标签选择器的权重为1。
注意,css样式中尽量不要使用id选择器,会降低代码的复用性,尽量不要使用!important,会降低代码的复用性,尽量减少子选择器的层级。
css样式多余样式去除,和结构优化
定义简洁的css样式规则,合并相关css样式规则,定义简洁的属性值,合并相同的,删除无效的。
sprite拼合图
css sprite,也叫 css 精灵,雪碧图。
是一种将雪散的背景图合并成一张大图,再次利用css的background-position属性进行背景的定位从而达到减少图片请求数量达到加快加载速度的网页应用处理方式。
background属性
background-color,描述规定要使用的背景颜色
background-position,描述规定背景图片的位置
background-size,描述规定背景图片的尺寸
background-repeat,描述规定如何重复背景图像
background-origin,描述规定背景图片的定位区域
background-clip,描述规定背景的绘制区域
background-attachment,描述规定背景图片是否固定或者随着页面的其余部分滚动
background-image,描述规定要使用的背景图像
background-position属性
top,left,center,right,center等等,top表示垂直位置最头部,bottom表示垂直位置最底部,left表示水平位置最左边,center表示水平位置居中,right表示为水平位置最右边。
css sprite的制作工具
css sprite制作工具,photoshop和打包工具webpack来制作。
打包工具,现在流行的很多前端打包工具都有支持css sprite的集成,如
webpack中只要安装webpack-spritesmith依赖,然后在配置文件中引用依赖var SpritesmithPlugin = require('webpack-spritesmith'),最后在配置文件中添加代码。
代码压缩,打包工具
前端优化,压缩JavaScript和css是非常重要的。目前最常用的压缩JavaScript代码的工具之一有UglifyJS,它会分析JavaScript代码语法树,理解代码含义,从而能做到诸如去掉无效代码,去掉日志输出代码,缩短变量名等优化。
在webpack中接入UglifyJS需要通过插件的形式,UgllifyJsPlugin是比较常用的插件,通过在webpack的配置文件webpack.config.js中加入以下代码即可。
压缩css代码常用的是CSSNANO,是基于PostCSS的,可以让我们的代码达到提升加载速度和代码混淆的作用。
图片的预加载
预加载简单来说就是将所有所需的资源提前请求加载到本地,这样需要用到时就可以直接从缓存中取资源了。
图片的懒加载
首屏的加载,就是用图片懒加载技术,即是到可视区域再加载。
图片懒加载,使用jquery.lazyload.js,该js是一个基于Jquery的懒加载插件,里面封装了懒加载用到的方法以及实现,第二种是echo.js,它是一款非常简单实用轻量级的图片延时加载插件。
JavaScript代码优化
JavaScript代码可维护性
什么是代码与结构分离呢
代码与结构分离,就是把HTML代码和JavaScript代码进行分离,第一在HTML中分离JavaScript,第二,在JavaScript中分离HTML。
什么是样式与结构分离呢
样式与结构分离,就是把css代码和HTML代码进行有效分离。
什么是数据与代码分离呢
数据与代码分离,也可以认为是前后端分离的表现,后端接口只负责返回json格式的数据,不会返回带标签甚至是带样式或者带JavaScript的组合数据。
JavaScript的代码可调式性
代码可调式性,可以用console.log,debugger,alert,try...catch捕获异常来进行JavaScript的调试。
console.log,即通过在JavaScript中添加console.log(msg)
msg为需要打印的信息,可以是变量,字符串,变量类型可以是数组,对象,数字等等。
debugger关键字用于停止执行JavaScript,并调式函数,这个关键字与调式工具中设置断点的效果是一样的。
alert和console.log一样,alert通过在JavaScript中添加alert(msg),Msg为需要弹窗的信息,值得一提的是这个弹框是强制阻塞的,只要关闭该弹窗才能解除阻塞,所以要谨慎使用。
try...catch,用于try...catch...finally来进行异常的捕获,try代码块表示可能发生异常的代码,catch表示捕获异常对象,finally无论是否发生异常都执行。
JavaScript dom的优化
提升文件的加载速度,合并JavaScript代码,尽量少用script标签,无堵塞加载JavaScript,通过给script标签增加defer属性或者是async属性来实现
动态创建script标签来加载,JavaScript dom操作优化,dom访问和修改,都说访问dom耗性能,用循环访问也是如此,所以要减少dom的访问。
重排和重绘
用cssText改变样式,批量修改dom。
JavaScript dom 脚本加载优化
学习前端高级层次,掌握webpack入门
modules with dependencies webpack static assets
webpack是一个module bundler模块构建工具,由于JavaScript应用程序的复杂性不断增加,构建工具已经成为web开发中不可或缺的一部分。
它帮助我们去打包,编译和管理项目需要的众多资源文件和依赖库。webpack支持CommoonJS,AMD和ES6模块系统,并且兼容多种JS书写规范,可以处理模块间的依赖关系,所以具有更强大的JS模块化的功能,它能压缩图片,对css, js 文件进行语法检查,压缩,编译打包。
构建工具没有标准
现在开发者可以用的构造构建工具有
webpack,gulp,bowserify,npm scripts,grunt等。
缺点有,不适合web开发的初学者,对于css,图片,以及其他非Js资源文件时,需要先混淆处理,文档不够完善,变化很大,不同版本的使用方法存在较大的差异。
安装
全局安装,用于全局使用命令行打包文件
新建项目文件夹
进入项目文件夹,打开cmd命令行窗口
基本应用
SPA是什么,它是单页应用程序。
single page web application,是webpack打包的典型应用,一个典型的SPA应用,主要由以下几个部分组成。
index.html主文件,js文件,有多个js文件,可以通过webpack合并打包为一个文件,css文件,可以多个css文件,可以通过webpack合并打包为一个文件。图片可以通过webpack压缩优化。
新建src文件夹,该文件夹存放开发用的文件,在src目录下创建文件。
新建dist文件夹
该文件存放打包后的文件,可以先不创建,打包时可以自动创建。
打包,webpack-mode development,经过打包后,已经根据三个js依赖关系,打包合并为dist/main.js。
webpack --output文件名,输出文件路径
webpack --config文件名,用于指定其他配置文
默认为webpack.config.js
webpack --mode模式,打包模式 production,生成模式,developement开发模式。
webpack --watch 监听文件变化并自动打包
webpack -p 压缩混淆脚本
webpack -d 生成Map映射文件
webpack --progress 显示进度,打印出编译进度的百分比值
webpack --color 用不同颜色标记不同的信息
webpack --profile 显示每一步编译的具体时间,可帮助优化构建性能
webpack --hot 热替换
webpack --bail 如果编译过程出现error,立马停止编译
配置文件入门
通过定义配置文件进行复杂操作,文件名webpack.config.js
一个配置文件的基本结构:
entry,入口定义入口文件,默认文件./src/index.js
output,输出定义出口文件,默认文件./dist/main.js
resolve,解析路径映射,省略后缀名等
module,模块定义不同loader,让webpack能够处理非JavaScript模块
plugins,插件扩展webpack功能
devServer,开发服务器用于配置webpack-dev-server选项
简单的配置文件
hello wrold例子:
修改webpack.json文件
配置详细entry和output
entry入口配置是指页面中的入口文件,默认入口文件./src/index.js
output出口配置是指生成的文件输出到哪个地方去,./dist/main.js
path,输出路径,filename,输出文件名
module,webpack只能打包js文件,无法识别其他语法的文件,如果要让webpack打包其他文件,首先需要让webpack识别不同的文件。
loader分类
<col>
分类
说明
转换编译
script-loader,babel-loader,ts-loader,coffee-loader
处理样式
style-loader,css-loader,less-loader,sass-loader,postcss-loader
处理文件
raw--loader,url-loader,file-loader
处理数据
csv-loader,xml-loader
处理模板语言
html-loader,pug-loader,jade-loader,markdown-loader
清理和测试
mocha-loader,eslint-loader
常用loader
loader
css-loader
解析css语句
style-loader
将css-loader解析后的文本,添加<style>标签
babel-loader
将ES6+、JSX语法转成ES5低版本语法
url-loader
url-loader对未设置或者小于limit byte设置的图片以base64的格式进行转换<br />对于大于limit byte的图片用file-loader进行解析
file-loader
解析项目中的url引入(包括img的src和background的url)<br />修改打包后文件引用路径,使之指向正确的文件
less-loader
less编译器
vue-loader
Vue也推出了自己的vue-loader,可以方便的打包 .vue文件 的代码。<br />在vue-cli(快速构建单页应用的脚手架)中得到应用。
babel loader
babel是一个js编译器,它是通过语法转换器支持最新版本的JavaScript,这插件允许你使用新语法,无需等待浏览器支持。
使用babel首先要配置.babelrc文件,该文件用来设置转码规则和插件,存放在项目的根目录下。
在linux系统中,rc结尾的文件通常代表运行时自动加载的文件、配置等等。
在.babelrc配置文件中,主要是对预设和插件进行配置。
配置项
presets
预设 对js最新的语法糖进行编译,并不负责转译新增的api和全局对象。例如:let/const可以被编译,而String.includes、Object.assign等对象新增方法并不能被编译。<br />常用转译器:babel-preset-env、babel-preset-es2015(2016、2017)、babel-preset-latest等
plugins
插件 控制如何转换代码,babel默认只转换新的js语法,而不转换新的API,比如 Set,,Maps,Symbol,Promise 等全局对象,transform-runtime 用来解决以上问题
插件可以扩展webpack的功能,Loader不能做的处理都能交给plugin来做。
resolve配置webpack如何寻找模块对应的文件,webpack在启动后会从配置的入口模块触发,找出所有依赖的模块,默认会采用模块化标准里约定号的规则去寻找。
属性
alias
(译:别名)通过别名将原来导入路径映射成一个新的导入路径
extensions
(译:扩展)数组 导入模块时,可以省略的文件后缀名
其他配置
devtool
是否生成以及如何生成sourcemap
devserver
开启一个本地开发服务器
watch
监听文件变化并自动打包
watchoption
用来定制watch模式的选项
performance
打包后命令行如何展示性能提示,如果超过某个大小是警告还是报错
webpack-dev-server
它是一个小型的web服务器,可以自动监视项目文件的变化,自动刷新浏览器,其HMR方式只替换更新的部分,而不是重载页面,大大提高了刷新效率
默认值
inline
自动刷新<br />当我们对业务代码做了一些修改,保存(ctrl+s)后,页面会自动刷新,所做的修改会直接同步到页面上,不需要手动刷新页面或重启服务
true
hot
热模块替换<br /> 不用配置(通常是通过命令行 --hot 选项启动,会自动加载webpack.HotModuleReplacementPlugin插件)
host
主机地址
open
自动打开浏览器,可以指定浏览器,例如:--open 'Chrome'
false
port
端口
默认8080
overlay
编译出错的时候,在浏览器页面上显示错误
stats
用来控制编译的时候shell上的输出内容<br />stats: "errors-only" 只打印错误<br /> 还有"minimal","normal","verbose"
compress
true:对所有服务器资源采用gzip压缩
contentBase
指定了服务器资源的根目录,<br />如果不写入contentBase的值,那么contentBase默认是项目的目录
"./"
historyApiFallback
它使用的是HTML5 History Api,任意的跳转或404响应可以指向 index.html 页面
例子:
运行
npm start
运行后,webpack-dev-server将开始运行,打开浏览器,直接输入127.0.0.1:8080/index.html,打包后的页面已经可以使用了
注意: index.html内无需引入main.js文件,打包后的index.html文件中会自动引入该文件。 webpack-dev-server运行后,浏览器中输出的页面,都是运行在内存中的,只有build以后,才会在dist目录中得到最终的结果文件。
ES6基础
ECMAScript和JavaScript到底是什么关系?
ECMAScript是JavaScript语言的国际标准,JavaScript是ECMAScript的实现。ESMAScript6的简称为es6是JavaScript语言的下一代标准。
symbol数据类型,Symbol是一种唯一标识符,可以用作对象的唯一属性名,这样就不会有人改写或覆盖你设置的属性值了。
Symbol作为对象属性名
Symbol永远不相等,创建它们的时候传入相同值的参数,也不相等,因此,可借助此特性解决属性名的冲突问题,也是该数据类型存在的主要用途。
Symbol 值不能与其他类型的值进行运算,可以显式转为字符串。
使用场景
为某个对象添加属性,新添加属性与原有属性重名,新添加的属性仅作为标记使用,不需要用遍历器遍历处理。
let与const
用var声明的变量会造成全局污染。
let用来声明变量,要先声明后使用
const
const声明一个只读的常量,一旦声明,常量的值就不能改变。
特性
var
let
作用域级别
函数级
块级
初始值
否
声明时必须赋值
变量提升
是
重复声明
变量的解构赋值
set与Map
js原有的2种数据结构,array和object;es6新增两种数据结构,set和map
set数据结构
set类似于数组,成员的值都是唯一的,没有重复的值。
主要用于数据的去重。
set本身就是一个构造函数,用来生成set数据结构。set实例时一个类数组的对象。
方法
add(value)
添加某个值,返回:Set结构本身
delete(value)
删除某个值,返回:bool(删除是否成功)
has(value)
表示该值是否为Set的成员 返回:bool
clear()
清除所有成员,返回:无
map数据结构,map也是一个数据集合,与数据类似。
它是对object的一个补充,map的key可以是任意类型,而传统对象的key必须是字符串。
遍历object得到的结果是无序的,遍历Map得到的结果是有序的
clear
从Map中移除所有元素
delete
从Map中移除指定的元素
forEach
对Map中的每个元素执行指定操作
get
返回Map中的指定元素
has
如果Map包含指定元素,则返回 true
set
添加一个新建元素到Map
toString
返回Map的字符串表示形式(序列化)
valueOf
返回指定对象的原始值
array set map
类别
Array
Set
Map
长度
arr.length
set.size
map.size
增
arr.push(新增值)
set.add(4)
map.set('t', 1)
删
arr.splice(索引,删除数量)
set.delete(2)
map.delete('t')
改
arr.splice(索引,删除数量,[新增值])
遍历
map.set('t',2)
查
set.has(1)
map.has('t')
清空
arr = []
set.clear()
map.clear()
共同变量方法
keys()
返回键名的遍历器
values()
返回键值的遍历器
entries()
返回键值对的遍历器
forEach()
使用回调函数遍历每个成员
箭头函数,匿名函数
参数格式
箭头函数中的this
函数的扩展
对象的扩展
在es6中允许向对象直接写入变量和函数,作为对象的属性和方法。
es6中允许使用表达式作为对象属性,并且函数名称定义也可以采用相同的方法。
setter和getter。
方法名称
方法描述
Object.is()
比较两个值是否相等
Object.assign()
用于将对象进行合并
Object.getOwnPropertyDescriptor
返回对象属性的描述
Object.keys()
返回一个数组,包括对象自身的所有的可枚举属性
数组的扩展
copyWithin(target,start,end)
在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组。也就是说,使用这个方法,会修改当前数组。参数说明:<br />target(必需):从该位置开始替换数据。负值:倒数。<br />start(可选):从该位置开始读取数据,默认:0。负值:倒数。<br /> end(可选):到该位置前停止读取数据,默认等于数组长度。负值:倒数。
find()
数组实例的find方法,用于找出第一个符合条件的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined。
findIndex()
findIndex方法的用法与find方法非常类似,返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1。
fill()
fill方法使用给定值,填充一个数组,fill方法用于空数组的初始化非常方便。数组中已有的元素,会被全部抹去,如果填充的类型为对象,那么被赋值的是同一个内存地址的对象,而不是深拷贝对象。
includes()
该方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes方法类似。
ES6高级操作
promise对象
JavaScript本身就是单线程的,所以为了解决单线程带来的问题,在异步编程中,许多操作都会放在回调函数中,同步与异步的混杂,过多的回调嵌套都会让代码变得难以维护。
promise对象用于处理异步操作的,异步处理成功了就执行成功的操作,异步处理失败了就捕获错误或者是停止后续操作。
一个promise代表是一个任务结果,这个任务有可能完成没完成。promise模式唯一需要的一个接口是调用then方法,它可以用来注册当promise完成或者失败时调用的回调函数,可以把promise对象看成一条工厂的流水线。
promise是一个类,需要New实例化:
then方法
then方法是promise原型上的方法,它把原来的回调写法分离出来了。
iterator方法
Iterator遍历器是一种接口,为各种不同的数据结构提供统一的访问机制,任何数据结构只要部署Iterator接口,就可以完成遍历操作。
array,set,map,string都是可迭代对象
它们原型中都有一个symbol.iterator方法,通过调用symbol.iterator方法来获取默认迭代器。
generator是es6提供的一种异步编程解决方案。
执行函数后,返回的是一个指向内部状态的指针对象,yield表达式是暂停执行的标记,next方法可以恢复执行。
yield表达式在Generator中是作为一个暂停标志,当碰到yield时,函数暂停执行,等到下一次next()执行时,函数才从当前yield位置开始执行。
Class,在传统的JavaScript中只有对象,没有类的概念,它是基于原型的面向对象语言,原型对象特点就是将自身的属性共享给新对象。我们可以通过class关键字可以定义类。