一个页面从输入url到页面显示加载完成,这个过程发生了什么?
1.浏览器根据请求的URL交给DNS域名解析,找到真实的IP,向服务器发起请求。
2.服务器交给后台处理完成后返回数据,浏览器接收文件(html,css,js图像等)、
3.浏览器对加载到的资源进行语法解析,建立对应的内部数据结构(如html,的dom)
4.载入解析到的资源文件,渲染页面完成。
虚拟dom与实体dom的区别:
1虚拟DOM不会进行排版与重绘操作
2虚拟DOM进行频繁修改,然后一次性比较并修改真实DOM中需要改的部分(注意!),最后并在真实DOM中进行排版与重绘,减少过多DOM节点排版与重绘损耗
3真实DOM频繁排版与重绘的效率是相当低的
4虚拟DOM有效降低大面积(真实DOM节点)的重绘与排版,因为最终与真实DOM比较差异,可以只渲染局部(同2)
一切为了减弱频繁的大面积重绘引发的性能问题,不同框架不一定需要虚拟DOM,关键看框架是否频繁会引发大面积的DOM操作
DMO加载过程:
网页文档加载都是按顺序执行的。一般浏览器渲染操作顺序大致是一下几个步骤:
1.解析HTML结构
2.加载外部脚本和样式表文件
3.解析并执行脚本代码
4.构造HTML DOM模型
5.加载图片等外部文件
6.页面加载完毕
ajax和jsonp跨域原理
1.创建XmlHttpRequest对象,也就是创建一个异步调用对象。
2.创建一个新的HTTP请求,并指定该http请求的方法,url及认证信息。
3.设置响应http请求状态变化的函数。
4.发送http请求。
5.获取异步调用返回的数据。
6.使用javascript和dom实现局部刷新。
jsonp跨域原理
动态创建了一个全局方法,并动态生成script标签请求数据,在请求回来的数据中执行请求是动态生成的js方法,传递参数是请求的数据,生成了假象的ajax。
gulp使用
var gulp = require('gulp'); var rimraf = require('gulp-rimraf'); var del = require('del'); // 清除开发时构建目录 gulp.task('clean', function () { return del(['build']); }); // 清理发布时构建目录 gulp.task('clean-dist', function () { return del(['dist']); }); // 清理发布时构建目录(带有aot预编译) gulp.task('clean-aot', function () { return del(['dist', 'compiled']); }); // 编译sass(release) gulp.task('sass-dist', function () { return gulp.src('src/themes/default/scss/default.scss') .pipe(sass().on('error', sass.logError)) .pipe(cleanCss()) .pipe(md5(20)) .pipe(rename({ suffix: '.min' })) .pipe(gulp.dest(config.build.themes + '/css')) }) gulp.task('watch-sass', function () { var watcher = gulp.watch('./src/themes/**/*.scss', ['sass-build']); watcher.on('change', function (event) { gutil.log('File ' + event.path + ' was ' + event.type + ', running tasks...'); }) });
webpack代码
entry 入口
output 输入路径
loads 加载器
plugs 插件
又问 用过什么!看你水平了。 当然是说你用的,下面是代码,回忆一下!
var webpack = require('webpack'); var webpackMerge = require('webpack-merge'); var commonConfig = require('./webpack.common'); var helpers = require('../helpers.js'); const ENV = process.env.ENV = process.env.NODE_ENV = 'development'; const HOST = process.env.HOST || 'localhost'; const PORT = process.env.PORT || 3000; const PUBLIC = process.env.PUBLIC || undefined; const HMR = helpers.hasProcessFlag('hot'); const METADATA = webpackMerge(commonConfig({ env: ENV }).metadata, { host: HOST, port: PORT, public: PUBLIC, ENV: ENV, HMR: HMR }); module.exports = function (env) { return webpackMerge(commonConfig({ env: ENV }), { devtool: 'cheap-module-eval-source-map', output: { path: helpers.root('build'), filename: 'scripts/[name].bundle.js', chunkFilename: 'scripts/[id].chunk.js' }, devServer: { historyApiFallback: true, stats: 'minimal' }, node: { global: true, crypto: 'empty', process: true, module: false, clearImmediate: false, setImmediate: false } }) }; var helpers = require('../helpers'); var webpack = require('webpack'); var path = require('path'); module.exports = { devtool: 'inline-source-map', resolve: { extensions: ['.ts', '.js', '.json'] }, module: { rules: [ { test: /.ts$/, loader: 'tslint-loader', exclude: [helpers.root('node_modules')] }, { test: /.ts$/, loaders: [ 'ts-loader', 'angular2-router-loader', 'angular2-template-loader' ], }, { test: /.html$/, loader: 'raw-loader' }, { test: /.json$/, loader: 'json-loader' }, { test: /.ts/, include: [helpers.root('src')], loader: 'sourcemap-istanbul-instrumenter-loader?force-sourcemap=true', exclude: [/.spec.ts/, /.e2e.ts/, /node_modules/], enforce: 'post' } ] }, stats: { colors: true, reasons: true }, watch: true, plugins: [ new webpack.LoaderOptionsPlugin({ debug: true }), new webpack.ContextReplacementPlugin(/angular(\|/)core(\|/)@angular/, path.join(__dirname)) ] };
vue路由跳转方式?
①直接修改地址栏中的路由地址
②通过router-link实现跳转
<router-link to="/myRegister">注册</router-link>
③通过js的编程的方式
jumpToLogin: function () { this.$router.push('/myLogin'); }
什么是闭包
function wrapper(){ var a = 1 function inner(){ a+=1 } return inner } 这就是闭包
了解数据解构吗?
队列(先进先出,请参考电影票是不是先买票的先走) 映射到数组就是 push() shift()
栈:后进先出,汉诺塔上面的盘子移走才能移动下面的盘子。映射到数组就是 push() pop()
树(二叉树/满二叉树/完全二叉树)
堆(最大堆/最小堆)
性能优化手段?
- 后台设置gzip压缩
- 后台设置cache-control 头指定过期时间(更详尽可以看)
- 图片压缩合并(精灵图这是很久以前的了)
- js压缩打包,css压缩打包,html压缩打包(webpack解决了这个问题)
- dns预解析,减少同一域名解析时间
- 图片懒加载,根据滚动距离高度来判断是否进行加载图片
- 指定img的宽高,避免网速波动造成页面重排(腾地)
- 异步加载组件vue
做一个css动画 从0到200px 速度线性
div{100px;animation:move 5s linear; } @keyframes move{ 0%{100px;} 50%{150px;} 100%{200px;} }
倒计时60秒
vue路由守卫
路由守卫为:
全局守卫:beforeEach
后置守卫:afterEach
全局解析守卫:beforeResolve
路由独享守卫:beforeEnter
组内路由守卫:beforeRouteEnter,beforeRouteUpdate,beforeRouteLeave
vue路由原理
更新视图但不重新请求页面,是前端路由原理的核心之一,目前在浏览器环境中这一功能的实现主要有2种方式:
- 利用URL中的hash("#");
- 利用History interface在HTML5中新增的方法;
vue-router是Vue.js框架的路由插件,它是通过mode这一参数控制路由的实现模式的:
const router=new VueRouter({ mode:'history', routes:[...] })
- 在初始化对应的history之前,会对mode做一些校验:若浏览器不支持HTML5History方式(通过supportsPushState变量判断),则mode设为hash;若不是在浏览器环境下运行,则mode设为abstract;
- VueRouter类中的onReady(),push()等方法只是一个代理,实际是调用的具体history对象的对应方法,在init()方法中初始化时,也是根据history对象具体的类别执行不同操作
HashHistory.push()
pushState 和 replaceState ,通过这两个 API 可以改变 url 地址且不会发送请求。
前端路由是直接找到与地址匹配的一个组件或对象并将其渲染出来。改变浏览器地址而不向服务器发出请求有两种方式:
1. 在地址中加入#以欺骗浏览器,地址的改变是由于正在进行页内导航
2. 使用H5的window.history功能,使用URL的Hash来模拟一个完整的URL。
未完待续>>>>>
温故而知新~