1引言
1.1 概述
为规范公司项目前端设计开发流程和模式,对设计标准、开发标准进行统一,实现公司前端的标准化、规范化,特制订此文档。此规范文档一经确认,前端设计人员、开发人员必须按照本文档规范进行前端设计与开发。本文档如有不对或者不合适的地方请及时提出,经讨论决定后可以更改。
1.2基本准则
UI方面,符合山东港口企业vi基本设计原则,严格遵守企业视觉识别系统规定的标志图形、标准字、标准色、标准组合。
前端开发方面,符合web开发标准,代码要求简洁、明了、有序、注释合理,语义化HTML,结构表现行为分离,兼容性好。
性能方面,要充分发挥所选前端框架特性,尽可能的减小服务器负载,保证最快的加载和解析速度。
外包协作方面,采取科技公司主导、外包辅助的方式,严格进行代码管理和成本控制,确保前端标准统一规范、核心代码自主掌控、外包成本控制合理。
2前端开发流程
前端开发流程主要分为需求确认、UI设计、任务分解、开发排期、前端开发、代码集成审核、前端测试、接口联调8个部分。
2.1需求确认
明确用户需求,避免误解,前端与后端的合作开发可以更加明确、有序、快速,避免不必要的沟通和返工;在需求确认阶段完成后,从UI设计开始,前端团队正式接入并进入开发阶段。
(1)需求文档编写
按照科技公司前端需求说明书编写要求(附件1),进行需求调研和文档编写,充分发掘用户真正的需求和潜在的需求,文档编写完成后组织项目人员与前端团队进行评审。
(2)接口文档编写
前端需求文档评审通过后,根据前端接口说明书编写要求(附件2),进行接口文档编写,文档编写完成后组织项目人员与前端团队进行评审。
(3)原型设计
原型要按照行业规范和用户要求进行排版布局和交互设计,不合理的地方要按照产品化思路有意识的引导用户进行修改,做到布局合理、符合行业规范、满足市场化需求;充分考虑用户体验,操作过程要清晰、明确,原型设计尽可能的与实际系统一致。
(4)原型评审
组织项目相关人员进行评审,对存在的问题进行讨论,项目经理要总体把握原型效果是否符合用户预期,前端开发人员要针对原型提出前端实现的意见,不易于实现的或者难以实现的,可以在会上提出是否可以用其他方案进行替换。
(5)用户确认
将原型提交给用户,确认是否满足客户需求,若不满足,与用户沟通修改,若满足,需用户填写需求确认单。
(6)工具要求:Axure、Sketch。
2.2UI设计
设计师根据用户需求、原型设计以及基准设计规范进行UI设计,设计完成后需要与用户、原型设计师和项目经理进行确认,确认后将设计图、标注文件(需要标注界面元素的大小以及颜色方便开发)、切图文件提交给项目团队。
2.3任务分解
按照基本准则要求,通过任务分解和功能排期的方法,对前端进行统一标准规范、外包资源统一调配、外包工作量精准评估,实现前端的规范管理、成本控制和自主运维。
根据需求和原型,按照科技公司主导,外包辅助的方式进行任务分解。
其中科技公司负责前端框架搭建(详情查看开发框架要求)、核心代码开发、示例代码开发、框架说明文档、任务包需求文档、任务包接口文档,向外包输出前端开发框架源码、框架说明文档、任务包需求文档、任务包接口文档。
1、任务包分解要求
在进行任务包分解时,科技公司代码层面要完全掌控,不能出现整个模块由外包人员独立开发的情况,科技公司开发人员要深入每个模块,根据实际工期和成本,按照3/7或者2/8等方式进行模块功能划分,外包人员要完全按照科技公司的开发标准和要求进行开发,不得随意更改或引入第三方代码。
2.4功能排期
1、工作量评估
按照功能复杂程度、技术开发难度、单模块化原则进行外包工作量评估,评估标准按照我公司前端人员实际开发能力进行评估,要求外包人员工作效率必须高于或等于我们公司前端人员。
2、排期
根据项目整体进度要求和项目开发计划,根据前端总体工作量评估情况外包资源调配和排期,排期制定过程中要与项目经理和后端开发人员沟通好排期时间,充分考虑项目整体计划和可能发生的意外情况,做好应急处理,确保项目按时、高效、有序的进行开发。
2.5前端代码开发
前端开发人员与后端开发人员约定接口规范,整理出接口规范文档,按照接口文档和前端开发规范进行代码开发,前端在接口未开发完成前,调用本地模拟数据,采用mock方式进行开发,在后端接口开发完成后,协调后端技术人员,进行实际接口测试。
(3)开发工具要求:vscode、Hbuilder。
(4)版本控制软件要求:svn、git。
(5)开发框架要求:
新项目前端框架推荐采用vue2.0框架,UI框架采用iview、element、ant框架,如需引入其他框架,请与科技公司联系。
历史项目先评估框架更改工作量,工期和成本不满足的情况下,根据项目本身的框架进行开发。
2.6代码集成审核
外包人员根据计划开发完成的任务包代码,需提交科技公司审核,审核通过后,集成到公司内部开发环境相应模块进行调试和测试,确认无误后计入有效工作量。
2.7前端代码测试
前端代码开发完成后,在本地进行前端代码测试,主要针对功能点击是否正常、页面调试是否有bug,系统操作体验是否流畅、页面加载是否卡顿、是否符合用户习惯,测试过程中出现的问题要及时提交到bug提交与跟踪平台,后续及时跟踪解决情况。
bug提交与跟踪平台:禅道。
2.8前后端接口联调、测试
前端开发人员与后端开发人员开发完成后,先通过本地调用对方服务进行接口数据测试,针对测试的问题进行修复,本地测试完成后,部署服务器测试环境进行功能联调测试,检查功能是否正常,针对出现的问题及时沟通解决。
测试环境联调测试通过后,项目经理组织UI设计师、原型设计师和前端开发人员进行测试环境演示,UI设计师确认是否与UI设计一致,项目经理确认系统功能与产品原型是否一致,针对不一致的问题与前端开发人员进行沟通修改。针对不一致的问题与前端开发人员进行沟通修改,问题修改完成后提交给用户确认。
2.9上线试运行
用户确认后,发布正式环境,组织进行项目上线、验收。
3前端开发规范
(1)文件目录、命名规范
Html,Vue,Jsp,css,js,images文件均归档至相应约定的目录中。
前端项目结构目录
html文件命名:单一词汇使用英文小写,多词汇使用英文驼峰式命名,文件名.html。按实际模块需求命名。
Vue文件命名:单一词汇使用英文小写,多词汇使用英文驼峰式命名,文件名.vue。按实际模块需求命名。
jsp文件命名:单一词汇使用英文小写,多词汇使用英文驼峰式命名,文件名.jsp。按实际模块需求命名。
css文件命名:单一词汇使用英文小写,多词汇使用英文驼峰式命名,文件名.css。共用common.css,首页index.css,其他页面按实际模块需求命名。
js文件命名:单一词汇使用英文小写,多词汇使用英文驼峰式命名,文件名.js。共用common.js,其他依实际模块需求命名。
(2)html书写规范
文档类型声明及编码: 统一为H5的声明类型<!DOCTYPE html>;编码统一为<meta charset="utf-8"/>,书写时利用IDE实现层次分明的缩进。
非特殊情况下css文件必须在<head>...</head>之间引入,选择link方式引入而非@import形式。
非特殊情况下js文件必须在页面底部引入。
引入JS库文件,文件名须包含库名称及版本号及是否为压缩版,比如:
jquery-1.4.1.min.js;
引入插件,文件名格式为库名称+插件名称,比如:jQuery.cookie.js。
所有HTML标签嵌套必须是正确的,禁止出现多出或者少出闭合标签的情况。
所有编码均遵循xhtml标准,标签、属性、属性命名必须由小写字母及下划线数字组成,且所有标签必须闭合,包括br(<br />),hr(<hr />)等;属性值必须用双引号包括。
充分利用无兼容性问题的html自身标签,比如span、em、strong、optgroup、label……
需要为html元素添加自定义属性的时候,首先要考虑下有没有默认的已有的合适标签去设置,如果没有,须以"data-"为前缀来添加自定义属性,避免使用"data:"等其他命名方式。
语义化html,如标题根据重要性用h2-h6(同一页面只能有一个h2),段落标记用p,列表用ul,内联元素中不可嵌套块状元素。
尽可能减少div的嵌套层数。
在页面中尽量避免使用内嵌样式表,即在标签内使用style="…"。
以背景形式呈现的图片,尽量写入css样式中;重要图片必须加上alt属性;
特殊符号使用:尽可能使用代码替代:比如<(<)、>(>)、空格( )、&(&)、“”(")等等;
尽量避免使用过度复杂的HTML结构。
(3)css书写规范
编码统一为utf-8。
为了避免一些浏览器兼容性问题以及增加样式重用性,每个页面必须引入common.css(见文章最后),此类文件不可随意修改。
class与id的使用:id是唯一的并是父级的,class是子级的并可以重复的,所以id仅使用在大的模块上,class可用在重复使用率高及子级中。
为JavaScript预留命名,请以js_起始,比如:js_hide,js_show。
class与id命名:使用英文命名,命名要语义化,简明化,但不要使用诸如first,last之类的命名。使用驼峰式和下划线分隔相结合的命名规则,即命名应以父级加子级的命名规范,如:父级的类为simple 子级的类应该为simple_first,以此类推,但是尽量避免出现超过四级的类命名。
css属性书写顺序,建议遵循:自身属性-->布局定位属性-->文本属性-->其他属性。此条可根据自身习惯书写,但尽量保证同类属性写在一起。
书写代码前,考虑并提高样式重复使用率。
充分利用html自身属性及样式继承原理减少代码量。
样式表中中文字体名,请务必转码成unicode码,以避免编码错误时乱码。
背景图片请尽可能使用精灵sprite技术,减小http请求,考虑到多人协作开发,sprite按模块制作。
使用table标签时(尽量避免使用table标签),请不要用width、height、cellspacing、cellpadding等table属性直接定义表现,应尽可能的利用table自身私有属性分离结构与表现,如:thead、tr、th、td、tbody、tfoot、colgroup、scope。
用png图片做图片时,要求图片格式为png-8格式,若png-8实在影响图片质量或其中有半透明效果,请为ie6单独定义背景:
避免兼容性属性的使用,比如text-shadow、css3的相关属性;
减少使用影响性能的属性,比如position:absolute、float;
代码缩进与格式:开发阶段单行书写,系统交付时可再将所有css进行压缩;使用Tab键进行缩进,每层缩进一个Tab键
背景重复,确保使用的图片在与迭代方向相同的长度要大于1像素而小于10像素。简单点说,就是x轴迭代,宽度要在1和10之间,y轴迭代,长度要在1和10之间。
JavaScript书写规范
文件编码统一为utf-8,书写过程过,每条语句必须以分号结束。
为了避免一些浏览器兼容性问题以及增加样式重用性,每个页面必须引入common.js(见文章最后),此类文件不可随意修改。
变量命名:驼峰式命名。首字母须小写,如:iTaoLun。
类命名:驼峰式命名。首字母大写,如:ITaoLun。
函数命名:驼峰式命名。首字母小写。如:iTaoLun()。
构造函数命名:全部大写。
命名语义化,尽可能利用英文单词或其缩写。
尽量避免使用存在兼容性及消耗资源的方法或属性,比如eval()、innerText。
后期优化中,JavaScript非注释类中文字符须转换成unicode编码使用,以避免编码错误时乱码显示。
代码结构明了,加适量注释。提高函数重用率。
注重与html分离,减小reflow,注重性能。
减少DOM访问次数。方法是将得到的元素用变量存储起来。
减少DOM事件绑定。
将自己写的JS用匿名函数包起来,避免变量冲突。
(4)图片规范
所有页面元素类图片均放入images文件夹,测试用图片放于images/demo文件夹;
图片格式仅限于gif、png、jpg;
命名全部用小写英文字母、数字、_的组合,其中不得包含汉字、空格、特殊字符;尽量用易懂的词汇。
在保证视觉效果的情况下选择最小的图片格式与图片质量,以减少加载时间。
尽量避免使用半透明的png图片。
运用csssprite技术集中小的背景图或图标,减小页面http请求,但注意,请务必在对应的psd源图中划参考线,并保存至images目录下。
(5)注释规范
html注释:注释格式<!--注释-->,'--'只能在注释的始末位置,不可置入注释文字区域;
css注释:注释格式/*注释*/;
JavaScript注释,单行注释使用'//单行注释',多行注释使用/*多行注释*/。
(6)语言组织类
新增,而非“添加,增加”之类的词语
编辑,而非“修改,更新”之类的词语
保存,而非“提交”之类的词语
所有操作除了保存表单外,保存用户操作统一使用“确定”词语
4前端性能优化
前端项目的开发过程中,性能至关重要,直接影响了用户体验,页面的加载响应速度是用户体验的关键。
(1)代码层面优化
v-if 条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建,也是惰性的,如果在初始渲染时条件为假,则什么也不做,直到条件第一次变为真时,才会开始渲染条件块。
v-show 无论初始条件是什么,元素总是会被渲染,并且只是简单地基于CSS的display属性进行切换。
v-if 适用于在运行时很少改变条件,不需要频繁切换条件的场景;v-show适用于需要非常频繁切换条件的场景。
computed: 是计算属性,依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed的值。
watch: 更多的是观察的作用,类似于某些数据的监听回调,每当监听的数据变化时都会执行回调进行后续操作。
运用场景:
当我们需要进行数值计算,并且依赖于其它数据时,应该使用 computed,因为可以利用 computed 的缓存特性,避免每次获取值时,都要重新计算。
当我们需要在数据变化时执行异步或开销较大的操作时,应该使用 watch,使用 watch 选项允许我们执行异步操作 ( 访问一个 API ),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。
v-for 遍历必须为 item 添加 key,在列表数据进行遍历渲染时,需要为每一项 item 设置唯一 key 值,方便 Vue.js 内部机制精准找到该条列表数据。当 state 更新时,新的状态值和旧的状态值对比,较快地定位到 diff 。
v-for 遍历避免同时使用 v-if,v-for 比 v-if 优先级高,如果每一次都需要遍历整个数组,将会影响速度,尤其是当之需要渲染很小一部分的时候,必要情况下应该替换成 computed 属性。
推荐:
<ul> <li v-for="user in activeUsers" :key="user.id"> {{ user.name }} </li></ul>
computed: { activeUsers: function () { return this.users.filter(function (user) { return user.isActive }) }}
不推荐:
<ul> <li v-for="user in users" v-if="user.isActive" :key="user.id"> {{ user.name }} </li></ul>
Vue 会通过 Object.defineProperty 对数据进行劫持,来实现视图响应数据的变化,然而有些时候组件就是纯粹的数据展示,不会有任何改变,就不需要 Vue 来劫持数据,在大量数据展示的情况下,这能够很明显的减少组件初始化的时间,可以通过 Object.freeze 方法来冻结一个对象,一旦被冻结的对象就再也不能被修改了。export default { data: () => ({ users: {} }), async created() { const users = await axios.get("/api/users"); this.users = Object.freeze(users); }};
Vue 组件销毁时,会自动清理它与其它实例的连接,解绑它的全部指令及事件监听器,但是仅限于组件本身的事件。
created() { addEventListener('click', this.click, false)},beforeDestroy() { removeEventListener('click', this.click, false)}
对于图片过多的页面,为了加速页面加载速度,可以将页面内未出现在可视区域内的图片先不做加载,等到滚动到可视区域后再去加载。这样对于页面加载性能上会有很大的提升,也提高了用户体验。我们在项目中使用 Vue 的 vue-lazyload 插件:
Ø 安装插件
npm install vue-lazyload --save-dev
Ø 在入口文件 man.js 中引入并使用
import VueLazyload from 'vue-lazyload'
Ø 在 vue 中直接使用
Vue.use(VueLazyload)
Ø 或者添加自定义选项
Vue.use(VueLazyload, {preLoad: 1.3,error: 'dist/error.png',loading: 'dist/loading.gif',attempt: 1})
在 vue 文件中将 img 标签的 src 属性直接改为 v-lazy ,从而将图片显示方式更改为懒加载显示:
<img v-lazy="/static/img/1.png">
以上为 vue-lazyload 插件的简单使用,如果要看插件的更多参数选项,可以查看 vue-lazyload 的 github 地址。
Vue 是单页面应用,会有很多的路由引入 ,导致使用 webpcak 打包后的文件很大,当进入首页时,加载的资源过多,页面会出现白屏的情况,不利于用户体验。通过将不同路由对应的组件分割成不同的代码块,当路由被访问的时候才加载对应的组件,可以更加高效,会大大提高首屏显示的速度,但是对其他页面的速度会有影响。
路由懒加载:
const Foo = () => import('./Foo.vue')const router = new VueRouter({ routes: [ { path: '/foo', component: Foo } ]})
在项目中经常会需要引入第三方插件,如果直接引入整个插件,会导致项目的体积太大,所以可以借助 babel-plugin-component ,只引入需要的组件,以达到减小项目体积的目的。以下为项目中引入 element-ui 组件库为例:
Ø 首先,安装 babel-plugin-component :
npm install babel-plugin-component -D
Ø 然后,将 .babelrc 修改为:
{ "presets": [["es2015", { "modules": false }]], "plugins": [ [ "component", { "libraryName": "element-ui", "styleLibraryName": "theme-chalk" } ] ]}
Ø 在 main.js 中引入部分组件:
import Vue from 'vue';import { Button, Select } from 'element-ui';
Vue.use(Button) Vue.use(Select)
当应用存在非常长或者无限滚动的列表时,需要采用窗口化的技术来优化性能,只需要渲染少部分区域的内容,减少重新渲染组件和创建 dom 节点的时间。可以通过vue-virtual-scroll-list来进行优化。
Ø 安装 vue-virtual-scroll-list:
npm install vue-virtual-scroll-list –save
Ø 引入下载好的组件,记得局部注册一下组件:
import virtualList from 'vue-virtual-scroll-list'
Ø v-for循环的方式循环数据:
<template>
<div>
<virtual-list :size="40" :remain="8">
<div
v-for="item of items" :key="item.id">{{ item }}
</div>
</virtual-list>
</div>
</template>
将Vue 在客户端将标签渲染成的整个 html 片段的工作在服务端完成,服务端形成的 html 片段直接返回给客户端。
Ø 服务端渲染的优点:
更好的 SEO:SPA 页面的内容是通过 Ajax 获取,而搜索引擎爬取工具并不会等待 Ajax 异步完成后再抓取页面内容,所以在 SPA 中是抓取不到页面通过 Ajax 获取到的内容;而 SSR 是直接由服务端返回已经渲染好的页面(数据已经包含在页面中),所以搜索引擎爬取工具可以抓取渲染好的页面;
更快的内容到达时间(首屏加载更快):SPA 会等待所有 Vue 编译后的 js 文件都下载完成后,才开始进行页面的渲染,文件下载等需要一定的时间等,所以首屏渲染需要一定的时间;SSR 直接由服务端渲染好页面直接返回显示,无需等待下载 js 文件及再去渲染等,所以 SSR 有更快的内容到达时间;
Ø 服务端渲染的缺点:
更多的开发条件限制:例如服务端渲染只支持 beforCreate 和 created 两个钩子函数,这会导致一些外部扩展库需要特殊处理,才能在服务端渲染应用程序中运行;并且与可以部署在任何静态文件服务器上的完全静态单页面应用程序 SPA 不同,服务端渲染应用程序,需要处于 Node.js server 运行环境;
更多的服务器负载:在 Node.js 中渲染完整的应用程序,显然会比仅仅提供静态文件的 server 更加大量占用CPU 资源,因此如果你预料在高流量环境下使用,请准备相应的服务器负载,并明智地采用缓存策略。
(2)Webpack 层面的优化
在 vue 项目中除了可以在 webpack.base.conf.js 中 url-loader 中设置 limit 大小来对图片处理,对小于 limit 的图片转化为 base64 格式,其余的不做操作。所以对有些较大的图片资源,在请求资源的时候,加载会很慢,我们可以用 image-webpack-loader来压缩图片:
Ø 首先,安装 image-webpack-loader :
npm install image-webpack-loader --save-dev
Ø 然后,在 webpack.base.conf.js 中进行配置:
{ test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, use:[ { loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('img/[name].[hash:7].[ext]') } }, { loader: 'image-webpack-loader', options: { bypassOnDebug: true, } } ]}
Babel 插件会在将 ES6 代码转换成 ES5 代码时会注入一些辅助函数,例如下面的 ES6 代码:
class HelloWebpack extends Component{...}
这段代码再被转换成能正常运行的 ES5 代码时需要以下两个辅助函数:
babel-runtime/helpers/createClass // 用于实现 class 语法
babel-runtime/helpers/inherits // 用于实现 extends 语法
在默认情况下, Babel 会在每个输出文件中内嵌这些依赖的辅助函数代码,如果多个源代码文件都依赖这些辅助函数,那么这些辅助函数的代码将会出现很多次,造成代码冗余。为了不让这些辅助函数的代码重复出现,可以在依赖它们时通过 require('babel-runtime/helpers/createClass') 的方式导入,这样就能做到只让它们出现一次。babel-plugin-transform-runtime 插件就是用来实现这个作用的,将相关辅助函数进行替换成导入语句,从而减小 babel 编译出来的代码的文件大小。
Ø 首先,安装 babel-plugin-transform-runtime :
npm install babel-plugin-transform-runtime --save-dev
Ø 然后,修改 .babelrc 配置文件为:
"plugins": [ "transform-runtime"]
如果项目中没有去将每个页面的第三方库和公共模块提取出来,则项目会存在以下问题:
相同的资源被重复加载,浪费用户的流量和服务器的成本。每个页面需要加载的资源太大,导致网页首屏加载缓慢,影响用户体验。所以我们需要将多个页面的公共代码抽离成单独的文件,来优化以上问题 。Webpack 内置了专门用于提取多个Chunk 中的公共部分的插件 CommonsChunkPlugin,我们在项目中CommonsChunkPlugin 的配置如下:
//所有在 package.json 里面依赖的包,都会被打包进 vendor.js 这个文件中。
new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', minChunks: function(module, count) { return ( module.resource && /\.js$/.test(module.resource) && module.resource.indexOf( path.join(__dirname, '../node_modules') ) === 0 ); }}),
// 抽取出代码模块的映射关系
new webpack.optimize.CommonsChunkPlugin({ name: 'manifest', chunks: ['vendor']})
当使用 DOM 内模板或 JavaScript 内的字符串模板时,模板会在运行时被编译为渲染函数。通常情况下这个过程已经足够快了,但对性能敏感的应用还是最好避免这种用法。
预编译模板最简单的方式就是使用单文件组件——相关的构建设置会自动把预编译处理好,所以构建好的代码已经包含了编译出来的渲染函数而不是原始的模板字符串。
如果你使用 webpack,并且喜欢分离 JavaScript 和模板文件,你可以使用 vue-template-loader,它也可以在构建过程中把模板文件转换成为 JavaScript 渲染函数。
当使用单文件组件时,组件内的 CSS 会以 style 标签的方式通过 JavaScript 动态注入。这有一些小小的运行时开销,如果你使用服务端渲染,这会导致一段 “无样式内容闪烁 (fouc) ” 。将所有组件的 CSS 提取到同一个文件可以避免这个问题,也会让 CSS 更好地进行压缩和缓存。
我们在项目进行打包后,会将开发中的多个文件代码打包到一个文件中,并且经过压缩、去掉多余的空格、babel编译化后,最终将编译得到的代码会用于线上环境,那么这样处理后的代码和源代码会有很大的差别,当有 bug的时候,我们只能定位到压缩处理后的代码位置,无法定位到开发环境中的代码,对于开发来说不好调式定位问题,因此 sourceMap 出现了,它就是为了解决不好调式代码问题的。
SourceMap 的可选值如下(+ 号越多,代表速度越快,- 号越多,代表速度越慢, o 代表中等速度 )
开发环境推荐:cheap-module-eval-source-map
生产环境推荐:cheap-module-source-map
原因如下:
cheap:源代码中的列信息是没有任何作用,因此我们打包后的文件不希望包含列相关信息,只有行信息能建立打包前后的依赖关系。因此不管是开发环境或生产环境,我们都希望添加 cheap 的基本类型来忽略打包前后的列信息;
module :不管是开发环境还是正式环境,我们都希望能定位到bug的源代码具体的位置,比如说某个 Vue 文件报错了,我们希望能定位到具体的 Vue 文件,因此我们也需要 module 配置;
soure-map :source-map 会为每一个打包后的模块生成独立的 soucemap 文件 ,因此我们需要增加source-map 属性;
eval-source-map:eval 打包代码的速度非常快,因为它不生成 map 文件,但是可以对 eval 组合使用 eval-source-map 使用会将 map 文件以 DataURL 的形式存在打包后的 js 文件中。在正式环境中不要使用 eval-source-map, 因为它会增加文件的大小,但是在开发环境中,可以试用下,因为他们打包的速度很快。
Webpack 输出的代码可读性非常差而且文件非常大。为了更简单、直观地分析输出结果,社区中出现了许多可视化分析工具。这些工具以图形的方式将结果更直观地展示出来,让我们快速了解问题所在。接下来讲解我们在 Vue 项目中用到的分析工具:webpack-bundle-analyzer 。
我们在项目中 webpack.prod.conf.js 进行配置:if (config.build.bundleAnalyzerReport) { var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; webpackConfig.plugins.push(new BundleAnalyzerPlugin());},执行 $ npm run build --report 后生成分析报告。
如果Vue 项目使用 Webpack 编译,需要对项目的 Webpack 配置进行优化,提高 Webpack 的构建效率。
(3)基础的 Web 技术优化
gzip 是 GNUzip 的缩写,最早用于 UNIX 系统的文件压缩。HTTP 协议上的 gzip 编码是一种用来改进 web 应用程序性能的技术,web 服务器和客户端(浏览器)必须共同支持 gzip。目前主流的浏览器,Chrome,firefox,IE等都支持该协议。常见的服务器如 Apache,Nginx,IIS 同样支持,gzip 压缩效率非常高,通常可以达到 70% 的压缩率,也就是说,如果你的网页有 30K,压缩之后就变成了 9K 左右。
以下我们以服务端使用我们熟悉的 express 为例,开启 gzip 非常简单,相关步骤如下:
安装:
npm install compression --save
添加代码逻辑:
var compression = require('compression');
var app = express();app.use(compression())
重启服务,观察网络面板里面的 response header,查看 gzip 是否开启成功。
为了提高用户加载页面的速度,对静态资源进行缓存是非常必要的,根据是否需要重新向服务器发起请求来分类,将 HTTP 缓存规则分为两大类(强制缓存,对比缓存),如果对缓存机制还不是了解很清楚的,可以参考文章《深入理解HTTP缓存机制及原理》。
浏览器从服务器上下载 CSS、js 和图片等文件时都要和服务器连接,而大部分服务器的带宽有限,如果超过限制,网页就半天反应不过来。而 CDN 可以通过不同的域名来加载文件,从而使下载文件的并发连接数大大增加,且CDN 具有更好的可用性,更低的网络延迟和丢包率 。
Chrome 的 Performance 面板可以录制一段时间内的 js 执行细节及时间。使用 Chrome 开发者工具分析页面性能的步骤如下:
打开 Chrome 开发者工具,切换到 Performance 面板→点击 Record 开始录制→刷新页面或展开某个节点→点击 Stop 停止录制。