当前位置: 首页 > news >正文

Javascript模版引擎简介

回顾

  • Micro-Templating

出自John Resig 2008年的一片文章,以及其经典实现:

// Simple JavaScript Templating
// John Resig - http://ejohn.org/ - MIT Licensed
(function(){
  var cache = {};

  this.tmpl = function tmpl(str, data){
    // Figure out if we're getting a template, or if we need to
    // load the template - and be sure to cache the result.
    var fn = !/\W/.test(str) ?
      cache[str] = cache[str] ||
        tmpl(document.getElementById(str).innerHTML) :

      // Generate a reusable function that will serve as a template
      // generator (and which will be cached).
      new Function("obj",
        "var p=[],print=function(){p.push.apply(p,arguments);};" +

        // Introduce the data as local variables using with(){}
        "with(obj){p.push('" +

        // Convert the template into pure JavaScript
        str
          .replace(/[\r\t\n]/g, " ")
          .split("<%").join("\t")
          .replace(/((^|%>)[^\t]*)'/g, "$1\r")
          .replace(/\t=(.*?)%>/g, "',$1,'")
          .split("\t").join("');")
          .split("%>").join("p.push('")
          .split("\r").join("\\'")
      + "');}return p.join('');");

    // Provide some basic currying to the user
    return data ? fn( data ) : fn;
  };
})();
  1. 基本的replace生成代码,终端动态编译方案
  2. 使用with解决context问题
  • Mustache.js & othors

更加丰富的模版语法,以及更加容易扩展。

/**
   * Breaks up the given `template` string into a tree of tokens. If the `tags`
   * argument is given here it must be an array with two string values: the
   * opening and closing tags used in the template (e.g. [ "<%", "%>" ]). Of
   * course, the default is to use mustaches (i.e. mustache.tags).
   *
   * A token is an array with at least 4 elements. The first element is the
   * mustache symbol that was used inside the tag, e.g. "#" or "&". If the tag
   * did not contain a symbol (i.e. {{myValue}}) this element is "name". For
   * all text that appears outside a symbol this element is "text".
   *
   * The second element of a token is its "value". For mustache tags this is
   * whatever else was inside the tag besides the opening symbol. For text tokens
   * this is the text itself.
   *
   * The third and fourth elements of the token are the start and end indices,
   * respectively, of the token in the original template.
   *
   * Tokens that are the root node of a subtree contain two more elements: 1) an
   * array of tokens in the subtree and 2) the index in the original template at
   * which the closing tag for that section begins.
   */

我们可以从这段备注中简单的看出Mustache.js的编译原理。

性能优化之路

模版引擎成功将动态HTML代码从Javascript中分离出来,避免了从前频繁的Javascript代码中的字符串拼接,简化了编码工作,实则是前端发展的大跃进。但当部分人还在痴迷与模版引擎的功能时,已经有人朝性能方向迈进。

  • 缓存技术

每次将Template字符串转化成函数己经变成一种浪费,缓存简单说是编译后将函数cache起来,仅此而已。

  • context预赋值

为了避免使用with这种效率较低的方法而出现的,简单的说就是把传入的数据对象中的所有节点都变成局部变量,下面是一个简单的例子:

var compile = function(str){
        //避免with语法
        var strFn = "var _$jstpl='',__fn__=(function(__d__){var __v__='';for(var __k__ in __d__){__v__+=('var '+__k__+'=__d__[\"'+__k__+'\"];');};eval(__v__);_$jstpl+='" + parse(str) + "';__v__=null;})(param);__fn__ = null;return _$jstpl;";
        return new Function("param", strFn);
    };
  • 规范关键字

作为最快的模版引擎,doT根本不使用with,而是直接通过规范关键字传入参数为it,然后所有参数都用it的节点来引用。

  • 线下编译

浏览器编译过程转为线下,直接生成执行函数。

  • 拼接方法

字符串拼接方法一般有:

  1. arr.push & arr.join
  2. res += tmp
  3. res = res + tmp

很多人误以为数组 push 方法拼接字符串会比 += 快,要知道这仅仅是 IE6-8 的浏览器下。实测表明现代浏览器使用 += 会比数组 push 方法快,而在 v8 引擎中,使用 += 方式比数组拼接快 4.7 倍。最新的一些测试结果还发现res = res + tmp在v8某些版本甚至比res += tmp还快。

未来

有些时候流行总在轮回,比如黑框眼睛以前是我们奶奶那辈人戴的,但现在年轻人都开始戴了。

模版从后端render,变成前端render,变成线下render……现在又随着NodeJS的崛起回来了后端(前台?)render,部分大公司如:FacebookGoogle已经线上应用。

转载于:https://www.cnblogs.com/justany/p/3522075.html

相关文章:

  • paip.不同目录结构哈的文件批量比较
  • RHEL 5.x 平台 10G RAC 的快速安装脚本
  • 便捷的 chrome/Firefox扩展
  • mysql的datetime类型字段的区间查询
  • RGBA是什么
  • 模块化编程
  • ffmpeg编译
  • windows上安装Django
  • 故障原因:由于exchange服务器设置自动更新服务器重启后登陆owa报错http 500错误...
  • My name Hunk
  • 在VIM中添加一键编译和一键运行
  • baidumap demo(二)
  • css3中定义required,focus,valid和invalid样式
  • C#控制定位Word光标移动到任意行或者最后一行,取得光标位置等操作
  • Linux-ip配置
  • 网络传输文件的问题
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • Druid 在有赞的实践
  • E-HPC支持多队列管理和自动伸缩
  • ES6 学习笔记(一)let,const和解构赋值
  • flutter的key在widget list的作用以及必要性
  • GraphQL学习过程应该是这样的
  • HomeBrew常规使用教程
  • iOS | NSProxy
  • Java深入 - 深入理解Java集合
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • redis学习笔记(三):列表、集合、有序集合
  • Spark in action on Kubernetes - Playground搭建与架构浅析
  • spring cloud gateway 源码解析(4)跨域问题处理
  • 海量大数据大屏分析展示一步到位:DataWorks数据服务+MaxCompute Lightning对接DataV最佳实践...
  • 批量截取pdf文件
  • 漂亮刷新控件-iOS
  • 项目管理碎碎念系列之一:干系人管理
  • 在Docker Swarm上部署Apache Storm:第1部分
  • 《天龙八部3D》Unity技术方案揭秘
  • FaaS 的简单实践
  • ​​​​​​​GitLab 之 GitLab-Runner 安装,配置与问题汇总
  • ​Kaggle X光肺炎检测比赛第二名方案解析 | CVPR 2020 Workshop
  • ​比特币大跌的 2 个原因
  • ​如何防止网络攻击?
  • ​学习一下,什么是预包装食品?​
  • #define MODIFY_REG(REG, CLEARMASK, SETMASK)
  • #git 撤消对文件的更改
  • #includecmath
  • #微信小程序(布局、渲染层基础知识)
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (pojstep1.1.1)poj 1298(直叙式模拟)
  • (第9篇)大数据的的超级应用——数据挖掘-推荐系统
  • (动态规划)5. 最长回文子串 java解决
  • (分享)自己整理的一些简单awk实用语句
  • (经验分享)作为一名普通本科计算机专业学生,我大学四年到底走了多少弯路
  • (欧拉)openEuler系统添加网卡文件配置流程、(欧拉)openEuler系统手动配置ipv6地址流程、(欧拉)openEuler系统网络管理说明
  • (一)ClickHouse 中的 `MaterializedMySQL` 数据库引擎的使用方法、设置、特性和限制。
  • (一)spring cloud微服务分布式云架构 - Spring Cloud简介
  • .helper勒索病毒的最新威胁:如何恢复您的数据?