프런트 엔드 애플리케이션 최적화에서는 로드된 리소스의 크기를 제어하는 것이 매우 중요합니다. 대부분의 경우 우리가 할 수 있는 일은 패키징 및 컴파일 프로세스 중에 크기를 제어하고 리소스를 분할하고 재사용하는 것입니다. 이번 글에서는 webpack을 활용하여 리소스를 최적화하는 방법을 주로 소개하고 있는데, 에디터가 꽤 괜찮다고 생각해서 지금부터 공유하고 참고용으로 올려보겠습니다. 편집자를 따라 살펴보겠습니다. 모두에게 도움이 되기를 바랍니다.
머리말
이 글은 주로 웹팩 패키징을 기반으로 하며, 웹팩 패키징 수준에서 리소스와 캐시를 처리하는 방법을 설명하기 위해 React, vue 및 기타 생태학적 환경에서 개발된 단일 페이지 애플리케이션을 사용합니다. 해야 할 일은 소량의 비즈니스 코드 변경을 포함하면서 웹팩 구성 최적화를 수행하는 것입니다.
동시에 (webpack-contrib/webpack-bundle-analyzer) 플러그인을 사용하여 패키지된 리소스를 분석할 수 있습니다. 물론 이 기사에서는 이 플러그인을 선택적으로 사용할 수 있습니다. 주로 예시로 사용됩니다.
팁: 웹팩 버전 @3.6.0
1. 패키징 환경 및 코드 압축
먼저 기본 웹팩 구성이 있습니다:
// webpack.config.js const path = require('path'); const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; const PROJECT_ROOT = path.resolve(__dirname, './'); module.exports = { entry: { index: './src/index.js' }, output: { path: path.resolve(__dirname, 'dist'), filename: '[name].[chunkhash:4].js' }, module: { rules: [ { test: /\.js[x]?$/, use: 'babel-loader', include: PROJECT_ROOT, exclude: /node_modules/ } ] }, plugins: [ new BundleAnalyzerPlugin() ], resolve: { extensions: ['.js', '.jsx'] }, };
패키징을 실행하면 프로젝트의 js가 100만 개가 넘는 것을 확인할 수 있습니다.
Hash: e51afc2635f08322670b Version: webpack 3.6.0 Time: 2769ms Asset Size Chunks Chunk Names index.caa7.js 1.3 MB 0 [emitted] [big] index
이때 플러그인 `DefinePlugin` 및 `UglifyJSPlugin`만 추가하면 볼륨을 많이 줄일 수 있습니다. 플러그인에
// webpack.config.js ... { ... plugins: [ new BundleAnalyzerPlugin(), new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production') }), new UglifyJSPlugin({ uglifyOptions: { ie8: false, output: { comments: false, beautify: false, }, mangle: { keep_fnames: true }, compress: { warnings: false, drop_console: true }, } }) ] ... }
를 추가하면 이때 패키징 출력을 볼 수 있습니다.
Hash: 84338998472a6d3c5c25 Version: webpack 3.6.0 Time: 9940ms Asset Size Chunks Chunk Names index.89c2.js 346 kB 0 [emitted] [big] index
코드 크기가 1.3M에서 346K로 줄었습니다.
(1)DefinePlugin
DefinePlugin을 사용하면 컴파일 타임에 구성할 수 있는 전역 상수를 생성할 수 있습니다. 이는 개발 모드와 릴리스 모드 빌드에 대해 서로 다른 동작을 허용하는 데 유용할 수 있습니다. 개발 빌드에서는 로깅을 수행하지만 릴리스 빌드에서는 수행하지 않는 경우 전역 상수를 사용하여 로그 여부를 결정할 수 있습니다. 이것이 DefinePlugin이 들어오는 곳이며, 이를 설정하고 개발 및 릴리스 빌드에 대한 규칙은 잊어버리세요.
비즈니스 코드 및 타사 패키지 코드에서는 다른 처리를 수행하기 위해 `process.env.NODE_ENV`를 판단해야 하는 경우가 많지만 프로덕션 환경에서는 분명히 `프로덕션`이 아닌 처리 부분이 필요하지 않습니다.
여기에서는 `process.env.NODE_ENV`를 `JSON.stringify('production')`으로 설정했는데, 이는 패키징 환경이 프로덕션 환경으로 설정되었음을 의미합니다. 그런 다음 'UglifyJSPlugin' 플러그인을 사용하면 프로덕션 환경용으로 패키징할 때 일부 중복 코드를 제거할 수 있습니다.
(2) UglifyJSPlugin
UglifyJSPlugin은 js 코드를 구문 분석하고 압축하는 데 주로 사용됩니다. js 코드를 처리하기 위해 `uglify-es`를 기반으로 합니다. https://github.com/webpack. - contrib/uglifyjs-webpack-plugin.
코드를 압축하고 중복성을 제거함으로써 패키지된 리소스의 크기가 크게 줄어듭니다.
2. 코드 분할/주문형 로딩
React 또는 Vue로 구축된 단일 페이지 애플리케이션에서 페이지 라우팅 및 뷰 제어는 프런트 엔드에서 구현되며 해당 비즈니스 로직은 js 코드에 있습니다.
애플리케이션 디자인에 페이지와 로직이 많으면 최종 생성되는 js 파일 리소스도 상당히 커집니다.
그러나 URL에 해당하는 페이지를 열 때 실제로는 모든 js 코드가 필요하지 않습니다. 우리에게 필요한 것은 다음 뷰를 로드할 때 메인 런타임 코드와 해당 비즈니스 로직 코드뿐입니다. 해당 코드 부분을 로드합니다.
따라서 이와 관련하여 수행할 수 있는 최적화는 요청 시 js 코드를 로드하는 것입니다.
지연 로딩 또는 주문형 로딩은 웹 페이지나 애플리케이션을 최적화하는 좋은 방법입니다. 이 방법은 실제로 일부 논리적 중단점에서 코드를 분리한 다음 일부 코드 블록에서 특정 작업을 완료한 후 즉시 다른 새 코드 블록을 참조하거나 참조하려고 합니다. 이렇게 하면 특정 코드 블록이 로드되지 않을 수 있으므로 앱의 초기 로드 속도가 빨라지고 전체 크기가 줄어듭니다.
Webpack은 코드 분할을 달성하기 위해 동적 가져오기 기술을 제공합니다. 먼저 webpack 구성에서 각 분할 하위 모듈의 구성을 구성해야 합니다.
// webpack.config.js const path = require('path'); const webpack = require('webpack'); const UglifyJSPlugin = require('uglifyjs-webpack-plugin'); const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; const PROJECT_ROOT = path.resolve(__dirname, './'); module.exports = { entry: { index: './src/index.js' }, output: { path: path.resolve(__dirname, 'dist'), filename: '[name].[chunkhash:4].js', chunkFilename: '[name].[chunkhash:4].child.js', }, module: { rules: [ { test: /\.js[x]?$/, use: 'babel-loader', include: PROJECT_ROOT, exclude: /node_modules/ } ] }, plugins: [ new BundleAnalyzerPlugin(), new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production') }), new UglifyJSPlugin({ uglifyOptions: { ie8: false, output: { comments: false, beautify: false, }, mangle: { keep_fnames: true }, compress: { warnings: false, drop_console: true }, } }), ], resolve: { extensions: ['.js', '.jsx'] }, };
정의해야 할 주요 사항은 '출력'입니다. ChunkFilename`은 내보낸 분할 코드의 파일 이름입니다. 여기서는 `[name].[chunkhash:4].child.js`로 설정되어 있습니다. 여기서 `name`은 모듈 이름 또는 ID, `chunkhash에 해당합니다. `는 모듈 콘텐츠의 해시입니다.
나중에 webpack은 비즈니스 코드에서 동적으로 가져오는 두 가지 방법을 제공합니다:
`import('path/to/module') -> Promise`,
`require.ensure(종속성: 문자열 [] , callback: function(require), errorCallback: function(error), ChunkName: String)`
최신 버전의 webpack에서는 주로 `import()` 사용을 권장합니다(참고: import는 Promise를 사용하므로 코드에서 Promise 폴리필이 지원되는지 확인해야 합니다.
// src/index.js function getComponent() { return import( /* webpackChunkName: "lodash" */ 'lodash' ).then(_ => { var element = document.createElement('p'); element.innerHTML = _.join(['Hello', 'webpack'], ' '); return element; }).catch(error => 'An error occurred while loading the component'); } getComponent().then(component => { document.body.appendChild(component); })
패키징 정보를 볼 수 있습니다:
Hash: d6ba79fe5995bcf9fa4d Version: webpack 3.6.0 Time: 7022ms Asset Size Chunks Chunk Names lodash.89f0.child.js 85.4 kB 0 [emitted] lodash index.316e.js 1.96 kB 1 [emitted] index [0] ./src/index.js 441 bytes {1} [built] [2] (webpack)/buildin/global.js 509 bytes {0} [built] [3] (webpack)/buildin/module.js 517 bytes {0} [built] + 1 hidden module
패키징된 코드가 `index.316e.js`와 `lodash.89f0.child.js`라는 두 개의 파일을 생성하는 것을 볼 수 있으며, 후자는 `import`를 통해 전달됩니다. 분할을 달성합니다.
`import` 它接收一个 `path` 参数,指的是该子模块对于的路径,同时还注意到其中可以添加一行注释 `/* webpackChunkName: "lodash" */`,该注释并非是无用的,它定义了该子模块的 name,其对应与 `output.chunkFilename` 中的 `[name]`。
`import` 函数返回一个 Promise,当异步加载到子模块代码是会执行后续操作,比如更新视图等。
(1)React 中的按需加载
在 React 配合 React-Router 开发中,往往就需要代码根据路由按需加载的能力,下面是一个基于 webpack 代码动态导入技术实现的 React 动态载入的组件:
import React, { Component } from 'react'; export default function lazyLoader (importComponent) { class AsyncComponent extends Component { state = { Component: null } async componentDidMount () { const { default: Component } = await importComponent(); this.setState({ Component: Component }); } render () { const Component = this.state.Component; return Component ? <component></component> : null; } } return AsyncComponent; };
在 `Route` 中:
<switch> <route> import('./Home'))} /> <route> import('./About'))} /> <route> import('./NotFound'))} /> </route></route></route></switch>
在 `Route` 中渲染的是 `lazyLoader` 函数返回的组件,该组件在 mount 之后会去执行 `importComponent` 函数(既:`() => import('./About')`)动态加载其对于的组件模块(被拆分出来的代码),待加载成功之后渲染该组件。
使用该方式打包出来的代码:
Hash: 02a053d135a5653de985 Version: webpack 3.6.0 Time: 9399ms Asset Size Chunks Chunk Names 0.db22.child.js 5.82 kB 0 [emitted] 1.fcf5.child.js 4.4 kB 1 [emitted] 2.442d.child.js 3 kB 2 [emitted] index.1bbc.js 339 kB 3 [emitted] [big] index
三、抽离 Common 资源
(1)第三方库的长缓存
首先对于一些比较大的第三方库,比如在 React 中用到的 react、react-dom、react-router 等等,我们不希望它们被重复打包,并且在每次版本更新的时候也不希望去改变这部分的资源导致在用户端重新加载。
在这里可以使用 webpack 的 CommonsChunkPlugin 来抽离这些公共资源;
CommonsChunkPlugin 插件,是一个可选的用于建立一个独立文件(又称作 chunk)的功能,这个文件包括多个入口 chunk 的公共模块。通过将公共模块拆出来,最终合成的文件能够在最开始的时候加载一次,便存起来到缓存中供后续使用。这个带来速度上的提升,因为浏览器会迅速将公共的代码从缓存中取出来,而不是每次访问一个新页面时,再去加载一个更大的文件。
首先需要在 entry 中新增一个入口用来打包需要抽离出来的库,这里将 `'react', 'react-dom', 'react-router-dom', 'immutable'` 都给单独打包进 `vendor` 中;
之后在 plugins 中定义一个 `CommonsChunkPlugin` 插件,同时将其 `name` 设置为 `vendor` 是它们相关联,再将 `minChunks` 设置为 `Infinity` 防止其他代码被打包进来。
// webpack.config.js const path = require('path'); const webpack = require('webpack'); const UglifyJSPlugin = require('uglifyjs-webpack-plugin'); const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; const PROJECT_ROOT = path.resolve(__dirname, './'); module.exports = { entry: { index: './src0/index.js', vendor: ['react', 'react-dom', 'react-router-dom', 'immutable'] }, output: { path: path.resolve(__dirname, 'dist'), filename: '[name].[chunkhash:4].js', chunkFilename: '[name].[chunkhash:4].child.js', }, module: { rules: [ { test: /\.js[x]?$/, use: 'babel-loader', include: PROJECT_ROOT, exclude: /node_modules/ } ] }, plugins: [ new BundleAnalyzerPlugin(), new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production') }), new UglifyJSPlugin({ uglifyOptions: { ie8: false, output: { comments: false, beautify: false, }, mangle: { keep_fnames: true }, compress: { warnings: false, drop_console: true }, } }), new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', minChunks: Infinity, }), ], resolve: { extensions: ['.js', '.jsx'] }, };
运行打包可以看到:
Hash: 34a71fcfd9a24e810c21 Version: webpack 3.6.0 Time: 9618ms Asset Size Chunks Chunk Names 0.2c65.child.js 5.82 kB 0 [emitted] 1.6e26.child.js 4.4 kB 1 [emitted] 2.e4bc.child.js 3 kB 2 [emitted] index.4e2f.js 64.2 kB 3 [emitted] index vendor.5fd1.js 276 kB 4 [emitted] [big] vendor
可以看到 `vendor` 被单独打包出来了。
当我们改变业务代码时再次打包:
Hash: cd3f1bc16b28ac97e20a Version: webpack 3.6.0 Time: 9750ms Asset Size Chunks Chunk Names 0.2c65.child.js 5.82 kB 0 [emitted] 1.6e26.child.js 4.4 kB 1 [emitted] 2.e4bc.child.js 3 kB 2 [emitted] index.4d45.js 64.2 kB 3 [emitted] index vendor.bc85.js 276 kB 4 [emitted] [big] vendor
vendor 包同样被打包出来的,然而它的文件 hash 却发生了变化,这显然不符合我们长缓存的需求。
这是因为 webpack 在使用 CommoChunkPlugin 的时候会生成一段 runtime 代码(它主要用来处理代码模块的映射关系),而哪怕没有改变 vendor 里的代码,这个 runtime 仍然是会跟随着打包变化的并且打入 verdor 中,所以 hash 就会开始变化了。解决方案则是把这部分的 runtime 代码也单独抽离出来,修改之前的 `CommonsChunkPlugin` 为:
// webpack.config.js ... new webpack.optimize.CommonsChunkPlugin({ name: ['vendor', 'runtime'], minChunks: Infinity, }), ...
执行打包可以看到生成的代码中多了 `runtime` 文件,同时即使改变业务代码,vendor 的 hash 值也保持不变了。
当然这段 `runtime` 实际上非常短,我们可以直接 inline 在 html 中,如果使用的是 `html-webpack-plugin` 插件处理 html,则可以结合 [`html-webpack-inline-source-plugin`](DustinJackson/html-webpack-inline-source-plugin) 插件自动处理其 inline。
(2)公共资源抽离
在我们打包出来的 js 资源包括不同入口以及子模块的 js 资源包,然而它们之间也会重复载入相同的依赖模块或者代码,因此可以通过 CommonsChunkPlugin 插件将它们共同依赖的一些资源打包成一个公共的 js 资源。
// webpack.config.js plugins: [ new BundleAnalyzerPlugin(), new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production') }), new UglifyJSPlugin({ uglifyOptions: { ie8: false, output: { comments: false, beautify: false, }, mangle: { keep_fnames: true }, compress: { warnings: false, drop_console: true }, } }), new webpack.optimize.CommonsChunkPlugin({ name: ['vendor', 'runtime'], minChunks: Infinity, }), new webpack.optimize.CommonsChunkPlugin({ // ( 公共chunk(commnons chunk) 的名称) name: "commons", // ( 公共chunk 的文件名) filename: "commons.[chunkhash:4].js", // (模块必须被 3个 入口chunk 共享) minChunks: 3 }) ],
可以看到这里增加了 `commons` 的一个打包,当一个资源被三个以及以上 chunk 依赖时,这些资源会被单独抽离打包到 `commons.[chunkhash:4].js` 文件。
执行打包,看到结果如下:
Hash: 2577e42dc5d8b94114c8 Version: webpack 3.6.0 Time: 24009ms Asset Size Chunks Chunk Names 0.2eee.child.js 90.8 kB 0 [emitted] 1.cfbc.child.js 89.4 kB 1 [emitted] 2.557a.child.js 88 kB 2 [emitted] vendor.66fd.js 275 kB 3 [emitted] [big] vendor index.688b.js 64.2 kB 4 [emitted] index commons.a61e.js 1.78 kB 5 [emitted] commons
却发现这里的 `commons.[chunkhash].js` 基本没有实际内容,然而明明在每个子模块中也都依赖了一些相同的依赖。
借助 webpack-bundle-analyzer 来分析一波:
可以看到三个模块都依赖了 `lodash`,然而它并没有被抽离出来。
这是因为 CommonsChunkPlugin 中的 chunk 指的是 entry 中的每个入口,因此对于一个入口拆分出来的子模块(children chunk)是不生效的。
可以通过在 CommonsChunkPlugin 插件中配置 `children` 参数将拆分出来的子模块的公共依赖也打包进 `commons` 中:
// webpack.config.js plugins: [ new BundleAnalyzerPlugin(), new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production') }), new UglifyJSPlugin({ uglifyOptions: { ie8: false, output: { comments: false, beautify: false, }, mangle: { keep_fnames: true }, compress: { warnings: false, drop_console: true }, } }), new webpack.optimize.CommonsChunkPlugin({ name: ['vendor', 'runtime'], minChunks: Infinity, }), new webpack.optimize.CommonsChunkPlugin({ // ( 公共chunk(commnons chunk) 的名称) name: "commons", // ( 公共chunk 的文件名) filename: "commons.[chunkhash:4].js", // (模块必须被 3个 入口chunk 共享) minChunks: 3 }), new webpack.optimize.CommonsChunkPlugin({ // (选择所有被选 chunks 的子 chunks) children: true, // (在提取之前需要至少三个子 chunk 共享这个模块) minChunks: 3, }) ],
查看打包效果:
其子模块的公共资源都被打包到 `index` 之中了,并没有理想地打包进 `commons` 之中,还是因为 `commons` 对于的是 entry 中的入口模块,而这里并未有 3 个 entry 模块共用资源;
在单入口的应用中可以选择去除 `commons`,而在子模块的 `CommonsChunkPlugin` 的配置中配置 `async` 为 `true`:
// webpack.config.js plugins: [ new BundleAnalyzerPlugin(), new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production') }), new UglifyJSPlugin({ uglifyOptions: { ie8: false, output: { comments: false, beautify: false, }, mangle: { keep_fnames: true }, compress: { warnings: false, drop_console: true }, } }), new webpack.optimize.CommonsChunkPlugin({ name: ['vendor', 'runtime'], minChunks: Infinity, }), new webpack.optimize.CommonsChunkPlugin({ // (选择所有被选 chunks 的子 chunks) children: true, // (异步加载) async: true, // (在提取之前需要至少三个子 chunk 共享这个模块) minChunks: 3, }) ],
查看效果:
子模块的公共资源都被打包到 `0.9c90.child.js` 中了,该模块则是子模块的 commons。
四、tree shaking
tree shaking 是一个术语,通常用于描述移除 JavaScript 上下文中的未引用代码(dead-code)。它依赖于 ES2015 模块系统中的静态结构特性,例如 import 和 export。这个术语和概念实际上是兴起于 ES2015 模块打包工具 rollup。
在我们引入一个依赖的某个输出的时候,我们可能需要的仅仅是该依赖的某一部分代码,而另一部分代码则是 `unused` 的,如果能够去除这部分代码,那么最终打包出来的资源体积也是可以有可观的减小。
首先,webpack 中实现 tree shaking 是基于 webpack 内部支持的 es2015 的模块机制,在大部分时候我们使用 babel 来编译 js 代码,而 babel 会通过自己的模块加载机制处理一遍,这导致 webpack 中的 tree shaking 处理将会失效。因此在 babel 的配置中需要关闭对模块加载的处理:
// .babelrc { "presets": [ [ "env", { "modules": false, } ], "stage-0" ], ... }
然后我们来看下 webpack 是如何处理打包的代码,举例有一个入口文件 `index.js` 和一个 `utils.js` 文件:
// utils.js export function square(x) { return x * x; } export function cube(x) { return x * x * x; } " "js // index.js import { cube } from './utils.js'; console.log(cube(10)); " 打包出来的代码: " // index.bundle.js /* 1 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* unused harmony export square */ /* harmony export (immutable) */ __webpack_exports__["a"] = cube; function square(x) { return x * x; } function cube(x) { return x * x * x; }
可以看到仅有 `cube` 函数被 `__webpack_exports__` 导出来,而 `square` 函数被标记为 `unused harmony export square`,然而在打包代码中既是 `square` 没有被导出但是它仍然存在与代码中,而如何去除其代码则可以通过添加 `UglifyjsWebpackPlugin` 插件来处理。
相关推荐:
위 내용은 웹팩을 사용하여 리소스 방법 및 기술을 최적화하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

JavaScript는 웹 페이지의 상호 작용과 역학을 향상시키기 때문에 현대 웹 사이트의 핵심입니다. 1) 페이지를 새로 고치지 않고 콘텐츠를 변경할 수 있습니다. 2) Domapi를 통해 웹 페이지 조작, 3) 애니메이션 및 드래그 앤 드롭과 같은 복잡한 대화식 효과를 지원합니다. 4) 성능 및 모범 사례를 최적화하여 사용자 경험을 향상시킵니다.

C 및 JavaScript는 WebAssembly를 통한 상호 운용성을 달성합니다. 1) C 코드는 WebAssembly 모듈로 컴파일되어 컴퓨팅 전력을 향상시키기 위해 JavaScript 환경에 도입됩니다. 2) 게임 개발에서 C는 물리 엔진 및 그래픽 렌더링을 처리하며 JavaScript는 게임 로직 및 사용자 인터페이스를 담당합니다.

JavaScript는 웹 사이트, 모바일 응용 프로그램, 데스크탑 응용 프로그램 및 서버 측 프로그래밍에서 널리 사용됩니다. 1) 웹 사이트 개발에서 JavaScript는 HTML 및 CSS와 함께 DOM을 운영하여 동적 효과를 달성하고 jQuery 및 React와 같은 프레임 워크를 지원합니다. 2) 반응 및 이온 성을 통해 JavaScript는 크로스 플랫폼 모바일 애플리케이션을 개발하는 데 사용됩니다. 3) 전자 프레임 워크를 사용하면 JavaScript가 데스크탑 애플리케이션을 구축 할 수 있습니다. 4) node.js는 JavaScript가 서버 측에서 실행되도록하고 동시 요청이 높은 높은 요청을 지원합니다.

Python은 데이터 과학 및 자동화에 더 적합한 반면 JavaScript는 프론트 엔드 및 풀 스택 개발에 더 적합합니다. 1. Python은 데이터 처리 및 모델링을 위해 Numpy 및 Pandas와 같은 라이브러리를 사용하여 데이터 과학 및 기계 학습에서 잘 수행됩니다. 2. 파이썬은 간결하고 자동화 및 스크립팅이 효율적입니다. 3. JavaScript는 프론트 엔드 개발에 없어서는 안될 것이며 동적 웹 페이지 및 단일 페이지 응용 프로그램을 구축하는 데 사용됩니다. 4. JavaScript는 Node.js를 통해 백엔드 개발에 역할을하며 전체 스택 개발을 지원합니다.

C와 C는 주로 통역사와 JIT 컴파일러를 구현하는 데 사용되는 JavaScript 엔진에서 중요한 역할을합니다. 1) C는 JavaScript 소스 코드를 구문 분석하고 추상 구문 트리를 생성하는 데 사용됩니다. 2) C는 바이트 코드 생성 및 실행을 담당합니다. 3) C는 JIT 컴파일러를 구현하고 런타임에 핫스팟 코드를 최적화하고 컴파일하며 JavaScript의 실행 효율을 크게 향상시킵니다.

실제 세계에서 JavaScript의 응용 프로그램에는 프론트 엔드 및 백엔드 개발이 포함됩니다. 1) DOM 운영 및 이벤트 처리와 관련된 TODO 목록 응용 프로그램을 구축하여 프론트 엔드 애플리케이션을 표시합니다. 2) Node.js를 통해 RESTFULAPI를 구축하고 Express를 통해 백엔드 응용 프로그램을 시연하십시오.

웹 개발에서 JavaScript의 주요 용도에는 클라이언트 상호 작용, 양식 검증 및 비동기 통신이 포함됩니다. 1) DOM 운영을 통한 동적 컨텐츠 업데이트 및 사용자 상호 작용; 2) 사용자가 사용자 경험을 향상시키기 위해 데이터를 제출하기 전에 클라이언트 확인이 수행됩니다. 3) 서버와의 진실한 통신은 Ajax 기술을 통해 달성됩니다.

보다 효율적인 코드를 작성하고 성능 병목 현상 및 최적화 전략을 이해하는 데 도움이되기 때문에 JavaScript 엔진이 내부적으로 작동하는 방식을 이해하는 것은 개발자에게 중요합니다. 1) 엔진의 워크 플로에는 구문 분석, 컴파일 및 실행; 2) 실행 프로세스 중에 엔진은 인라인 캐시 및 숨겨진 클래스와 같은 동적 최적화를 수행합니다. 3) 모범 사례에는 글로벌 변수를 피하고 루프 최적화, Const 및 Lets 사용 및 과도한 폐쇄 사용을 피하는 것이 포함됩니다.


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

맨티스BT
Mantis는 제품 결함 추적을 돕기 위해 설계된 배포하기 쉬운 웹 기반 결함 추적 도구입니다. PHP, MySQL 및 웹 서버가 필요합니다. 데모 및 호스팅 서비스를 확인해 보세요.

SecList
SecLists는 최고의 보안 테스터의 동반자입니다. 보안 평가 시 자주 사용되는 다양한 유형의 목록을 한 곳에 모아 놓은 것입니다. SecLists는 보안 테스터에게 필요할 수 있는 모든 목록을 편리하게 제공하여 보안 테스트를 더욱 효율적이고 생산적으로 만드는 데 도움이 됩니다. 목록 유형에는 사용자 이름, 비밀번호, URL, 퍼징 페이로드, 민감한 데이터 패턴, 웹 셸 등이 포함됩니다. 테스터는 이 저장소를 새로운 테스트 시스템으로 간단히 가져올 수 있으며 필요한 모든 유형의 목록에 액세스할 수 있습니다.

mPDF
mPDF는 UTF-8로 인코딩된 HTML에서 PDF 파일을 생성할 수 있는 PHP 라이브러리입니다. 원저자인 Ian Back은 자신의 웹 사이트에서 "즉시" PDF 파일을 출력하고 다양한 언어를 처리하기 위해 mPDF를 작성했습니다. HTML2FPDF와 같은 원본 스크립트보다 유니코드 글꼴을 사용할 때 속도가 느리고 더 큰 파일을 생성하지만 CSS 스타일 등을 지원하고 많은 개선 사항이 있습니다. RTL(아랍어, 히브리어), CJK(중국어, 일본어, 한국어)를 포함한 거의 모든 언어를 지원합니다. 중첩된 블록 수준 요소(예: P, DIV)를 지원합니다.

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

MinGW - Windows용 미니멀리스트 GNU
이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.
